layerscape: update linux 4.9 patches to LSDK-18.06
[openwrt/staging/hauke.git] / target / linux / layerscape / patches-4.9 / 701-sdk_dpaa-support-layerscape.patch
1 From 6cc4cbfd0456c752f9f59d7d07fbb4b514dc6909 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Thu, 5 Jul 2018 16:25:00 +0800
4 Subject: [PATCH 07/32] sdk_dpaa: support layerscape
5
6 This is an integrated patch for layerscape dpaa1-sdk support.
7
8 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
9 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
10 Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
11 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
12 Signed-off-by: Mathew McBride <matt@traverse.com.au>
13 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
14 ---
15 .../net/ethernet/freescale/sdk_dpaa/Kconfig | 196 +
16 .../net/ethernet/freescale/sdk_dpaa/Makefile | 46 +
17 .../ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
18 .../ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
19 .../freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
20 .../freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
21 .../ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1224 +++
22 .../ethernet/freescale/sdk_dpaa/dpaa_eth.h | 687 ++
23 .../freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
24 .../freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
25 .../freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2115 +++++
26 .../freescale/sdk_dpaa/dpaa_eth_ceetm.h | 240 +
27 .../freescale/sdk_dpaa/dpaa_eth_common.c | 1802 ++++
28 .../freescale/sdk_dpaa/dpaa_eth_common.h | 225 +
29 .../freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
30 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1193 +++
31 .../freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
32 .../freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
33 .../freescale/sdk_dpaa/dpaa_ethtool.c | 544 ++
34 .../ethernet/freescale/sdk_dpaa/dpaa_ptp.c | 291 +
35 .../net/ethernet/freescale/sdk_dpaa/mac-api.c | 931 ++
36 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 489 ++
37 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 135 +
38 .../freescale/sdk_dpaa/offline_port.c | 848 ++
39 .../freescale/sdk_dpaa/offline_port.h | 59 +
40 .../net/ethernet/freescale/sdk_fman/Kconfig | 153 +
41 .../net/ethernet/freescale/sdk_fman/Makefile | 11 +
42 .../sdk_fman/Peripherals/FM/HC/Makefile | 15 +
43 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 +++
44 .../sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
45 .../sdk_fman/Peripherals/FM/MAC/dtsec.c | 1504 ++++
46 .../sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
47 .../Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
48 .../Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
49 .../sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++
50 .../sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 +
51 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
52 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
53 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 845 ++
54 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 163 +
55 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++
56 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 213 +
57 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
58 .../sdk_fman/Peripherals/FM/MAC/memac.c | 1153 +++
59 .../sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
60 .../Peripherals/FM/MAC/memac_mii_acc.c | 78 +
61 .../Peripherals/FM/MAC/memac_mii_acc.h | 73 +
62 .../sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++
63 .../sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
64 .../Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
65 .../Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
66 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
67 .../Peripherals/FM/MACSEC/fm_macsec.c | 237 +
68 .../Peripherals/FM/MACSEC/fm_macsec.h | 203 +
69 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
70 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
71 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
72 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 ++
73 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
74 .../sdk_fman/Peripherals/FM/Makefile | 23 +
75 .../sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
76 .../sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
77 .../sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 +++++++++++++++++
78 .../sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
79 .../sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++
80 .../sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
81 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++
82 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
83 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 +++++
84 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
85 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
86 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 ++++
87 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
88 .../sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 +
89 .../sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
90 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
91 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
92 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 888 ++
93 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
94 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
95 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6436 ++++++++++++++
96 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
97 .../Peripherals/FM/Port/fm_port_dsar.h | 494 ++
98 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
99 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1568 ++++
100 .../sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
101 .../sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
102 .../sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
103 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
104 .../sdk_fman/Peripherals/FM/SP/Makefile | 15 +
105 .../sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
106 .../sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
107 .../sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
108 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++
109 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
110 .../sdk_fman/Peripherals/FM/fm_ipc.h | 465 +
111 .../sdk_fman/Peripherals/FM/fm_muram.c | 174 +
112 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1398 +++
113 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 +++
114 .../sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
115 .../Peripherals/FM/inc/fm_sp_common.h | 117 +
116 .../ethernet/freescale/sdk_fman/etc/Makefile | 12 +
117 .../ethernet/freescale/sdk_fman/etc/error.c | 95 +
118 .../ethernet/freescale/sdk_fman/etc/list.c | 71 +
119 .../ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
120 .../net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
121 .../net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
122 .../ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
123 .../freescale/sdk_fman/fmanv3h_dflags.h | 57 +
124 .../freescale/sdk_fman/fmanv3l_dflags.h | 56 +
125 .../inc/Peripherals/crc_mac_addr_ext.h | 364 +
126 .../sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
127 .../sdk_fman/inc/Peripherals/fm_ext.h | 1731 ++++
128 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 ++
129 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 +++
130 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
131 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 +++++++++
132 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 ++++++
133 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
134 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 +
135 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
136 .../freescale/sdk_fman/inc/core_ext.h | 90 +
137 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
138 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
139 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
140 .../freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
141 .../freescale/sdk_fman/inc/debug_ext.h | 233 +
142 .../freescale/sdk_fman/inc/endian_ext.h | 447 +
143 .../freescale/sdk_fman/inc/enet_ext.h | 205 +
144 .../freescale/sdk_fman/inc/error_ext.h | 529 ++
145 .../freescale/sdk_fman/inc/etc/list_ext.h | 358 +
146 .../freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
147 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
148 .../freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
149 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
150 .../inc/flib/common/arch/ppc_access.h | 37 +
151 .../sdk_fman/inc/flib/common/general.h | 52 +
152 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
153 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
154 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 ++
155 .../sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
156 .../inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
157 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
158 .../sdk_fman/inc/flib/fsl_fman_memac.h | 434 +
159 .../inc/flib/fsl_fman_memac_mii_acc.h | 78 +
160 .../sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
161 .../sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
162 .../sdk_fman/inc/flib/fsl_fman_rtc.h | 449 +
163 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
164 .../sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
165 .../FMANV3H/dpaa_integration_ext.h | 291 +
166 .../inc/integrations/FMANV3H/part_ext.h | 71 +
167 .../FMANV3H/part_integration_ext.h | 304 +
168 .../FMANV3L/dpaa_integration_ext.h | 293 +
169 .../inc/integrations/FMANV3L/part_ext.h | 59 +
170 .../FMANV3L/part_integration_ext.h | 304 +
171 .../LS1043/dpaa_integration_ext.h | 291 +
172 .../inc/integrations/LS1043/part_ext.h | 64 +
173 .../LS1043/part_integration_ext.h | 185 +
174 .../integrations/P1023/dpaa_integration_ext.h | 213 +
175 .../inc/integrations/P1023/part_ext.h | 82 +
176 .../integrations/P1023/part_integration_ext.h | 635 ++
177 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
178 .../integrations/P3040_P4080_P5020/part_ext.h | 83 +
179 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
180 .../freescale/sdk_fman/inc/math_ext.h | 100 +
181 .../freescale/sdk_fman/inc/ncsw_ext.h | 435 +
182 .../ethernet/freescale/sdk_fman/inc/net_ext.h | 430 +
183 .../ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
184 .../freescale/sdk_fman/inc/stdarg_ext.h | 49 +
185 .../freescale/sdk_fman/inc/stdlib_ext.h | 162 +
186 .../freescale/sdk_fman/inc/string_ext.h | 56 +
187 .../freescale/sdk_fman/inc/types_ext.h | 62 +
188 .../freescale/sdk_fman/inc/xx_common.h | 56 +
189 .../ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
190 .../freescale/sdk_fman/ls1043_dflags.h | 56 +
191 .../freescale/sdk_fman/ncsw_config.mk | 53 +
192 .../freescale/sdk_fman/p1023_dflags.h | 65 +
193 .../sdk_fman/p3040_4080_5020_dflags.h | 62 +
194 .../ethernet/freescale/sdk_fman/src/Makefile | 11 +
195 .../sdk_fman/src/inc/system/sys_ext.h | 118 +
196 .../sdk_fman/src/inc/system/sys_io_ext.h | 46 +
197 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
198 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
199 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 +
200 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
201 .../src/inc/wrapper/lnxwrp_fsl_fman.h | 921 ++
202 .../freescale/sdk_fman/src/inc/xx/xx.h | 50 +
203 .../freescale/sdk_fman/src/system/Makefile | 10 +
204 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
205 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
206 .../sdk_fman/src/wrapper/fman_test.c | 1665 ++++
207 .../sdk_fman/src/wrapper/lnxwrp_fm.c | 2908 +++++++
208 .../sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
209 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1512 ++++
210 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++
211 .../src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 +++
212 .../src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
213 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
214 .../src/wrapper/lnxwrp_resources_ut.c | 191 +
215 .../src/wrapper/lnxwrp_resources_ut.h | 144 +
216 .../src/wrapper/lnxwrp_resources_ut.make | 28 +
217 .../sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
218 .../sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
219 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 ++++
220 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
221 .../src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 +++
222 .../src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
223 .../freescale/sdk_fman/src/xx/Makefile | 18 +
224 .../sdk_fman/src/xx/module_strings.c | 46 +
225 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 ++
226 .../freescale/sdk_fman/src/xx/xx_linux.c | 918 ++
227 drivers/staging/fsl_qbman/Kconfig | 228 +
228 drivers/staging/fsl_qbman/Makefile | 28 +
229 drivers/staging/fsl_qbman/bman_config.c | 720 ++
230 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
231 drivers/staging/fsl_qbman/bman_driver.c | 575 ++
232 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
233 drivers/staging/fsl_qbman/bman_low.h | 565 ++
234 drivers/staging/fsl_qbman/bman_private.h | 166 +
235 drivers/staging/fsl_qbman/bman_test.c | 56 +
236 drivers/staging/fsl_qbman/bman_test.h | 44 +
237 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
238 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
239 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
240 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
241 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
242 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
243 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
244 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
245 drivers/staging/fsl_qbman/fsl_usdpaa.c | 2007 +++++
246 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
247 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
248 drivers/staging/fsl_qbman/qman_config.c | 1224 +++
249 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
250 drivers/staging/fsl_qbman/qman_driver.c | 977 +++
251 drivers/staging/fsl_qbman/qman_high.c | 5652 ++++++++++++
252 drivers/staging/fsl_qbman/qman_low.h | 1442 ++++
253 drivers/staging/fsl_qbman/qman_private.h | 398 +
254 drivers/staging/fsl_qbman/qman_test.c | 57 +
255 drivers/staging/fsl_qbman/qman_test.h | 45 +
256 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
257 .../staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
258 drivers/staging/fsl_qbman/qman_utility.c | 129 +
259 include/linux/fsl_bman.h | 532 ++
260 include/linux/fsl_qman.h | 3900 +++++++++
261 include/linux/fsl_usdpaa.h | 372 +
262 include/uapi/linux/fmd/Kbuild | 5 +
263 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
264 .../uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
265 .../linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 +++++++
266 .../linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++
267 .../linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
268 include/uapi/linux/fmd/integrations/Kbuild | 1 +
269 .../fmd/integrations/integration_ioctls.h | 56 +
270 include/uapi/linux/fmd/ioctls.h | 96 +
271 include/uapi/linux/fmd/net_ioctls.h | 430 +
272 257 files changed, 153455 insertions(+)
273 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
274 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
275 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
276 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
277 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
278 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
279 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
280 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
281 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
282 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
283 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
284 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
285 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
286 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
287 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
288 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
289 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
290 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
291 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
292 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
293 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
294 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
295 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
296 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
297 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
298 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
299 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
300 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
301 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
302 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
303 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
304 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
305 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
306 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
307 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
308 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
309 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
310 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
311 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
312 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
313 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
314 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
315 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
316 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
317 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
318 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
319 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
320 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
321 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
322 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
323 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
324 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
325 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
326 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
327 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
328 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
329 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
330 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
331 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
332 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
333 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
346 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
350 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
354 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
355 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
356 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
357 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
360 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
361 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
364 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
365 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
369 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
370 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
387 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
389 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
391 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
393 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
397 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
401 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
402 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
406 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
409 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
410 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
411 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
412 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
416 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
417 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
418 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
419 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
420 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
421 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
442 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
444 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
446 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
448 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
449 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
450 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
452 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
453 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
454 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
456 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
457 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
464 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
465 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
484 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
485 create mode 100644 drivers/staging/fsl_qbman/Kconfig
486 create mode 100644 drivers/staging/fsl_qbman/Makefile
487 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
488 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
489 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
490 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
491 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
492 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
493 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
494 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
495 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
496 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
497 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
498 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
499 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
500 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
501 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
502 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
503 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
504 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
505 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
506 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
507 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
508 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
509 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
510 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
511 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
512 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
513 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
514 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
515 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
516 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
517 create mode 100644 include/linux/fsl_bman.h
518 create mode 100644 include/linux/fsl_qman.h
519 create mode 100644 include/linux/fsl_usdpaa.h
520 create mode 100644 include/uapi/linux/fmd/Kbuild
521 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
522 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
523 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
524 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
525 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
526 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
527 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
528 create mode 100644 include/uapi/linux/fmd/ioctls.h
529 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
530
531 --- /dev/null
532 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
533 @@ -0,0 +1,196 @@
534 +menuconfig FSL_SDK_DPAA_ETH
535 + tristate "DPAA Ethernet"
536 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
537 + select PHYLIB
538 + help
539 + Data Path Acceleration Architecture Ethernet driver,
540 + supporting the Freescale QorIQ chips.
541 + Depends on Freescale Buffer Manager and Queue Manager
542 + driver and Frame Manager Driver.
543 +
544 +if FSL_SDK_DPAA_ETH
545 +
546 +config FSL_DPAA_HOOKS
547 + bool "DPAA Ethernet driver hooks"
548 +
549 +config FSL_DPAA_CEETM
550 + bool "DPAA CEETM QoS"
551 + depends on NET_SCHED
552 + default n
553 + help
554 + Enable QoS offloading support through the CEETM hardware block.
555 +
556 +config FSL_DPAA_CEETM_CCS_THRESHOLD_1G
557 + hex "CEETM egress congestion threshold on 1G ports"
558 + depends on FSL_DPAA_CEETM
559 + range 0x1000 0x10000000
560 + default "0x000a0000"
561 + help
562 + The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports.
563 + The threshold needs to be configured keeping in mind the following factors:
564 + - A threshold too large will buffer frames for a long time in the TX queues,
565 + when a small shaping rate is configured. This will cause buffer pool depletion
566 + or out of memory errors. This in turn will cause frame loss on RX;
567 + - A threshold too small will cause unnecessary frame loss by entering
568 + congestion too often.
569 +
570 +config FSL_DPAA_CEETM_CCS_THRESHOLD_10G
571 + hex "CEETM egress congestion threshold on 10G ports"
572 + depends on FSL_DPAA_CEETM
573 + range 0x1000 0x20000000
574 + default "0x00640000"
575 + help
576 + The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports.
577 + See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details.
578 +
579 +config FSL_DPAA_OFFLINE_PORTS
580 + bool "Offline Ports support"
581 + depends on FSL_SDK_DPAA_ETH
582 + default y
583 + help
584 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
585 + most of the functionality of the regular, online ports, except they receive their
586 + frames from a core or an accelerator on the SoC, via QMan frame queues,
587 + rather than directly from the network.
588 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
589 + any online FMan port. They deliver the processed frames to frame queues, according
590 + to the applied PCD configurations.
591 +
592 + Choosing this feature will not impact the functionality and/or performance of the system,
593 + so it is safe to have it.
594 +
595 +config FSL_DPAA_ADVANCED_DRIVERS
596 + bool "Advanced DPAA Ethernet drivers"
597 + depends on FSL_SDK_DPAA_ETH
598 + default y
599 + help
600 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
601 + is needed to support advanced scenarios. Select this to also build the advanced
602 + drivers.
603 +
604 +config FSL_DPAA_ETH_JUMBO_FRAME
605 + bool "Optimize for jumbo frames"
606 + default n
607 + help
608 + Optimize the DPAA Ethernet driver throughput for large frames
609 + termination traffic (e.g. 4K and above).
610 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
611 + is set to 9600 bytes.
612 + Using this option in combination with small frames increases
613 + significantly the driver's memory footprint and may even deplete
614 + the system memory. Also, the skb truesize is altered and messages
615 + from the stack that warn against this are bypassed.
616 + This option is not available on LS1043.
617 +
618 +config FSL_DPAA_TS
619 + bool "Linux compliant timestamping"
620 + depends on FSL_SDK_DPAA_ETH
621 + default n
622 + help
623 + Enable Linux API compliant timestamping support.
624 +
625 +config FSL_DPAA_1588
626 + bool "IEEE 1588-compliant timestamping"
627 + depends on FSL_SDK_DPAA_ETH
628 + select FSL_DPAA_TS
629 + default n
630 + help
631 + Enable IEEE1588 support code.
632 +
633 +config FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
634 + bool "Use driver's Tx queue selection mechanism"
635 + default y
636 + depends on FSL_SDK_DPAA_ETH
637 + help
638 + The DPAA-Ethernet driver defines a ndo_select_queue() callback for optimal selection
639 + of the egress FQ. That will override the XPS support for this netdevice.
640 + If for whatever reason you want to be in control of the egress FQ-to-CPU selection and mapping,
641 + or simply don't want to use the driver's ndo_select_queue() callback, then unselect this
642 + and use the standard XPS support instead.
643 +
644 +config FSL_DPAA_ETH_MAX_BUF_COUNT
645 + int "Maximum nuber of buffers in private bpool"
646 + depends on FSL_SDK_DPAA_ETH
647 + range 64 2048
648 + default "128"
649 + help
650 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
651 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
652 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
653 +
654 +config FSL_DPAA_ETH_REFILL_THRESHOLD
655 + int "Private bpool refill threshold"
656 + depends on FSL_SDK_DPAA_ETH
657 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
658 + default "80"
659 + help
660 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
661 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
662 + modify this value unless one has very specific performance reasons.
663 +
664 +config FSL_DPAA_CS_THRESHOLD_1G
665 + hex "Egress congestion threshold on 1G ports"
666 + depends on FSL_SDK_DPAA_ETH
667 + range 0x1000 0x10000000
668 + default "0x06000000"
669 + help
670 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
671 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
672 + (e.g. by sending UDP datagrams at "while(1) speed"),
673 + and the larger the frame size, the more acute the problem.
674 + So we have to find a balance between these factors:
675 + - avoiding the device staying congested for a prolonged time (risking
676 + the netdev watchdog to fire - see also the tx_timeout module param);
677 + - affecting performance of protocols such as TCP, which otherwise
678 + behave well under the congestion notification mechanism;
679 + - preventing the Tx cores from tightly-looping (as if the congestion
680 + threshold was too low to be effective);
681 + - running out of memory if the CS threshold is set too high.
682 +
683 +config FSL_DPAA_CS_THRESHOLD_10G
684 + hex "Egress congestion threshold on 10G ports"
685 + depends on FSL_SDK_DPAA_ETH
686 + range 0x1000 0x20000000
687 + default "0x10000000"
688 + help
689 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
690 +
691 +config FSL_DPAA_INGRESS_CS_THRESHOLD
692 + hex "Ingress congestion threshold on FMan ports"
693 + depends on FSL_SDK_DPAA_ETH
694 + default "0x10000000"
695 + help
696 + The size in bytes of the ingress tail-drop threshold on FMan ports.
697 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
698 +
699 +config FSL_DPAA_ETH_DEBUGFS
700 + bool "DPAA Ethernet debugfs interface"
701 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
702 + default y
703 + help
704 + This option compiles debugfs code for the DPAA Ethernet driver.
705 +
706 +config FSL_DPAA_ETH_DEBUG
707 + bool "DPAA Ethernet Debug Support"
708 + depends on FSL_SDK_DPAA_ETH
709 + default n
710 + help
711 + This option compiles debug code for the DPAA Ethernet driver.
712 +
713 +config FSL_DPAA_DBG_LOOP
714 + bool "DPAA Ethernet Debug loopback"
715 + depends on FSL_DPAA_ETH_DEBUGFS && FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
716 + default n
717 + help
718 + This option allows to divert all received traffic on a certain interface A towards a
719 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
720 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
721 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
722 + change the loop setting for interface 4 and divert all received traffic to interface 5
723 + write Tx interface number in the receive interface debugfs file:
724 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
725 + 4->-1
726 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
727 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
728 + 4->5
729 +endif # FSL_SDK_DPAA_ETH
730 --- /dev/null
731 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
732 @@ -0,0 +1,46 @@
733 +#
734 +# Makefile for the Freescale Ethernet controllers
735 +#
736 +ccflags-y += -DVERSION=\"\"
737 +#
738 +# Include netcomm SW specific definitions
739 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
740 +
741 +ccflags-y += -I$(NET_DPA)
742 +
743 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
744 +obj-$(CONFIG_PTP_1588_CLOCK_DPAA) += dpaa_ptp.o
745 +
746 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
747 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
748 +fsl_dpa-objs += dpaa_debugfs.o
749 +endif
750 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
751 +fsl_dpa-objs += dpaa_1588.o
752 +endif
753 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
754 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
755 +fsl_dpa-objs += dpaa_eth_ceetm.o
756 +endif
757 +
758 +fsl_mac-objs += mac.o mac-api.o
759 +
760 +# Advanced drivers
761 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
762 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
763 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
764 +
765 +fsl_advanced-objs += dpaa_eth_base.o
766 +# suport for multiple drivers per kernel module comes in kernel 3.14
767 +# so we are forced to generate several modules for the advanced drivers
768 +fsl_proxy-objs += dpaa_eth_proxy.o
769 +
770 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
771 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
772 +
773 +fsl_oh-objs += offline_port.o
774 +endif
775 +endif
776 +
777 +# Needed by the tracing framework
778 +CFLAGS_dpaa_eth.o := -I$(src)
779 --- /dev/null
780 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
781 @@ -0,0 +1,580 @@
782 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
783 + * Copyright (C) 2009 IXXAT Automation, GmbH
784 + *
785 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
786 + *
787 + * This program is free software; you can redistribute it and/or modify
788 + * it under the terms of the GNU General Public License as published by
789 + * the Free Software Foundation; either version 2 of the License, or
790 + * (at your option) any later version.
791 + *
792 + * This program is distributed in the hope that it will be useful,
793 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
794 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
795 + * GNU General Public License for more details.
796 + *
797 + * You should have received a copy of the GNU General Public License along
798 + * with this program; if not, write to the Free Software Foundation, Inc.,
799 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
800 + *
801 + */
802 +#include <linux/io.h>
803 +#include <linux/device.h>
804 +#include <linux/fs.h>
805 +#include <linux/vmalloc.h>
806 +#include <linux/spinlock.h>
807 +#include <linux/ip.h>
808 +#include <linux/ipv6.h>
809 +#include <linux/udp.h>
810 +#include <asm/div64.h>
811 +#include "dpaa_eth.h"
812 +#include "dpaa_eth_common.h"
813 +#include "dpaa_1588.h"
814 +#include "mac.h"
815 +
816 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
817 +{
818 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
819 +
820 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
821 + if (!circ_buf->buf)
822 + return 1;
823 +
824 + circ_buf->head = 0;
825 + circ_buf->tail = 0;
826 + ptp_buf->size = size;
827 + spin_lock_init(&ptp_buf->ptp_lock);
828 +
829 + return 0;
830 +}
831 +
832 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
833 +{
834 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
835 +
836 + circ_buf->head = 0;
837 + circ_buf->tail = 0;
838 + ptp_buf->size = size;
839 +}
840 +
841 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
842 + struct dpa_ptp_data *data)
843 +{
844 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
845 + int size = ptp_buf->size;
846 + struct dpa_ptp_data *tmp;
847 + unsigned long flags;
848 + int head, tail;
849 +
850 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
851 +
852 + head = circ_buf->head;
853 + tail = circ_buf->tail;
854 +
855 + if (CIRC_SPACE(head, tail, size) <= 0)
856 + circ_buf->tail = (tail + 1) & (size - 1);
857 +
858 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
859 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
860 +
861 + circ_buf->head = (head + 1) & (size - 1);
862 +
863 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
864 +
865 + return 0;
866 +}
867 +
868 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
869 + struct dpa_ptp_ident *src)
870 +{
871 + int ret;
872 +
873 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
874 + return 0;
875 +
876 + if ((dst->netw_prot == src->netw_prot)
877 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
878 + if (dst->seq_id != src->seq_id)
879 + return 0;
880 +
881 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
882 + DPA_PTP_SOURCE_PORT_LENGTH);
883 + if (ret)
884 + return 0;
885 + else
886 + return 1;
887 + }
888 +
889 + return 0;
890 +}
891 +
892 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
893 + struct dpa_ptp_ident *ident,
894 + struct dpa_ptp_time *ts)
895 +{
896 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
897 + int size = ptp_buf->size;
898 + int head, tail, idx;
899 + unsigned long flags;
900 + struct dpa_ptp_data *tmp, *tmp2;
901 + struct dpa_ptp_ident *tmp_ident;
902 +
903 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
904 +
905 + head = circ_buf->head;
906 + tail = idx = circ_buf->tail;
907 +
908 + if (CIRC_CNT(head, tail, size) == 0) {
909 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
910 + return 1;
911 + }
912 +
913 + while (idx != head) {
914 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
915 + tmp_ident = &tmp->ident;
916 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
917 + break;
918 + idx = (idx + 1) & (size - 1);
919 + }
920 +
921 + if (idx == head) {
922 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
923 + return 1;
924 + }
925 +
926 + ts->sec = tmp->ts.sec;
927 + ts->nsec = tmp->ts.nsec;
928 +
929 + if (idx != tail) {
930 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
931 + tail = circ_buf->tail =
932 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
933 + }
934 +
935 + while (CIRC_CNT(idx, tail, size) > 0) {
936 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
937 + idx = (idx - 1) & (size - 1);
938 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
939 + *tmp = *tmp2;
940 + }
941 + }
942 + circ_buf->tail = (tail + 1) & (size - 1);
943 +
944 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
945 +
946 + return 0;
947 +}
948 +
949 +/* Parse the PTP packets
950 + *
951 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
952 + * an IEEE802.3 ethernet frame. This function returns the position of
953 + * the PTP packet or NULL if no PTP found
954 + */
955 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
956 +{
957 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
958 + u8 *ptp_loc = NULL;
959 + u8 msg_type;
960 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
961 + struct iphdr *iph;
962 + struct udphdr *udph;
963 + struct ipv6hdr *ipv6h;
964 +
965 + /* when we can receive S/G frames we need to check the data we want to
966 + * access is in the linear skb buffer
967 + */
968 + if (!pskb_may_pull(skb, access_len))
969 + return NULL;
970 +
971 + *eth_type = *((u16 *)pos);
972 +
973 + /* Check if inner tag is here */
974 + if (*eth_type == ETH_P_8021Q) {
975 + access_len += DPA_VLAN_TAG_LEN;
976 +
977 + if (!pskb_may_pull(skb, access_len))
978 + return NULL;
979 +
980 + pos += DPA_VLAN_TAG_LEN;
981 + *eth_type = *((u16 *)pos);
982 + }
983 +
984 + pos += DPA_ETYPE_LEN;
985 +
986 + switch (*eth_type) {
987 + /* Transport of PTP over Ethernet */
988 + case ETH_P_1588:
989 + ptp_loc = pos;
990 +
991 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
992 + return NULL;
993 +
994 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
995 + if ((msg_type == PTP_MSGTYPE_SYNC)
996 + || (msg_type == PTP_MSGTYPE_DELREQ)
997 + || (msg_type == PTP_MSGTYPE_PDELREQ)
998 + || (msg_type == PTP_MSGTYPE_PDELRESP))
999 + return ptp_loc;
1000 + break;
1001 + /* Transport of PTP over IPv4 */
1002 + case ETH_P_IP:
1003 + iph = (struct iphdr *)pos;
1004 + access_len += sizeof(struct iphdr);
1005 +
1006 + if (!pskb_may_pull(skb, access_len))
1007 + return NULL;
1008 +
1009 + if (ntohs(iph->protocol) != IPPROTO_UDP)
1010 + return NULL;
1011 +
1012 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
1013 + sizeof(struct udphdr);
1014 +
1015 + if (!pskb_may_pull(skb, access_len))
1016 + return NULL;
1017 +
1018 + pos += iph->ihl * 4;
1019 + udph = (struct udphdr *)pos;
1020 + if (ntohs(udph->dest) != 319)
1021 + return NULL;
1022 + ptp_loc = pos + sizeof(struct udphdr);
1023 + break;
1024 + /* Transport of PTP over IPv6 */
1025 + case ETH_P_IPV6:
1026 + ipv6h = (struct ipv6hdr *)pos;
1027 +
1028 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
1029 +
1030 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
1031 + return NULL;
1032 +
1033 + pos += sizeof(struct ipv6hdr);
1034 + udph = (struct udphdr *)pos;
1035 + if (ntohs(udph->dest) != 319)
1036 + return NULL;
1037 + ptp_loc = pos + sizeof(struct udphdr);
1038 + break;
1039 + default:
1040 + break;
1041 + }
1042 +
1043 + return ptp_loc;
1044 +}
1045 +
1046 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
1047 + struct sk_buff *skb, void *data, enum port_type rx_tx,
1048 + struct dpa_ptp_data *ptp_data)
1049 +{
1050 + u64 nsec;
1051 + u32 mod;
1052 + u8 *ptp_loc;
1053 + u16 eth_type;
1054 +
1055 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
1056 + if (!ptp_loc)
1057 + return -EINVAL;
1058 +
1059 + switch (eth_type) {
1060 + case ETH_P_IP:
1061 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
1062 + break;
1063 + case ETH_P_IPV6:
1064 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
1065 + break;
1066 + case ETH_P_1588:
1067 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
1068 + break;
1069 + default:
1070 + return -EINVAL;
1071 + }
1072 +
1073 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
1074 + return -EINVAL;
1075 +
1076 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
1077 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
1078 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
1079 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
1080 + DPA_PTP_SOURCE_PORT_LENGTH);
1081 +
1082 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
1083 + mod = do_div(nsec, NANOSEC_PER_SECOND);
1084 + ptp_data->ts.sec = nsec;
1085 + ptp_data->ts.nsec = mod;
1086 +
1087 + return 0;
1088 +}
1089 +
1090 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1091 + struct sk_buff *skb, void *data)
1092 +{
1093 + struct dpa_ptp_tsu *tsu = priv->tsu;
1094 + struct dpa_ptp_data ptp_tx_data;
1095 +
1096 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
1097 + return;
1098 +
1099 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
1100 +}
1101 +
1102 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1103 + struct sk_buff *skb, void *data)
1104 +{
1105 + struct dpa_ptp_tsu *tsu = priv->tsu;
1106 + struct dpa_ptp_data ptp_rx_data;
1107 +
1108 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
1109 + return;
1110 +
1111 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
1112 +}
1113 +
1114 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1115 + struct dpa_ptp_ident *ident,
1116 + struct dpa_ptp_time *ts)
1117 +{
1118 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1119 + struct dpa_ptp_time tmp;
1120 + int flag;
1121 +
1122 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
1123 + if (!flag) {
1124 + ts->sec = tmp.sec;
1125 + ts->nsec = tmp.nsec;
1126 + return 0;
1127 + }
1128 +
1129 + return -1;
1130 +}
1131 +
1132 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
1133 + struct dpa_ptp_ident *ident,
1134 + struct dpa_ptp_time *ts)
1135 +{
1136 + struct dpa_ptp_tsu *tsu = ptp_tsu;
1137 + struct dpa_ptp_time tmp;
1138 + int flag;
1139 +
1140 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
1141 + if (!flag) {
1142 + ts->sec = tmp.sec;
1143 + ts->nsec = tmp.nsec;
1144 + return 0;
1145 + }
1146 +
1147 + return -1;
1148 +}
1149 +
1150 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
1151 + struct dpa_ptp_time *cnt_time)
1152 +{
1153 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1154 + u64 tmp, fiper;
1155 +
1156 + if (mac_dev->fm_rtc_disable)
1157 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
1158 +
1159 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
1160 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1161 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
1162 + if (mac_dev->fm_rtc_set_alarm)
1163 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
1164 + 0, tmp);
1165 + if (mac_dev->fm_rtc_set_fiper)
1166 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
1167 + 0, fiper);
1168 +
1169 + if (mac_dev->fm_rtc_enable)
1170 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
1171 +}
1172 +
1173 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
1174 + struct dpa_ptp_time *curr_time)
1175 +{
1176 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1177 + u64 tmp;
1178 + u32 mod;
1179 +
1180 + if (mac_dev->fm_rtc_get_cnt)
1181 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1182 + &tmp);
1183 +
1184 + mod = do_div(tmp, NANOSEC_PER_SECOND);
1185 + curr_time->sec = (u32)tmp;
1186 + curr_time->nsec = mod;
1187 +}
1188 +
1189 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
1190 + struct dpa_ptp_time *cnt_time)
1191 +{
1192 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1193 + u64 tmp;
1194 +
1195 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
1196 +
1197 + if (mac_dev->fm_rtc_set_cnt)
1198 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
1199 + tmp);
1200 +
1201 + /* Restart fiper two seconds later */
1202 + cnt_time->sec += 2;
1203 + cnt_time->nsec = 0;
1204 + dpa_set_fiper_alarm(tsu, cnt_time);
1205 +}
1206 +
1207 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
1208 +{
1209 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1210 + u32 drift;
1211 +
1212 + if (mac_dev->fm_rtc_get_drift)
1213 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1214 + &drift);
1215 +
1216 + *addend = drift;
1217 +}
1218 +
1219 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
1220 +{
1221 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
1222 +
1223 + if (mac_dev->fm_rtc_set_drift)
1224 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
1225 + addend);
1226 +}
1227 +
1228 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
1229 +{
1230 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1231 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1232 +}
1233 +
1234 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
1235 +{
1236 + struct dpa_priv_s *priv = netdev_priv(dev);
1237 + struct dpa_ptp_tsu *tsu = priv->tsu;
1238 + struct mac_device *mac_dev = priv->mac_dev;
1239 + struct dpa_ptp_data ptp_data;
1240 + struct dpa_ptp_data *ptp_data_user;
1241 + struct dpa_ptp_time act_time;
1242 + u32 addend;
1243 + int retval = 0;
1244 +
1245 + if (!tsu || !tsu->valid)
1246 + return -ENODEV;
1247 +
1248 + switch (cmd) {
1249 + case PTP_ENBL_TXTS_IOCTL:
1250 + tsu->hwts_tx_en_ioctl = 1;
1251 + if (mac_dev->fm_rtc_enable)
1252 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
1253 + if (mac_dev->ptp_enable)
1254 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
1255 + break;
1256 + case PTP_DSBL_TXTS_IOCTL:
1257 + tsu->hwts_tx_en_ioctl = 0;
1258 + if (mac_dev->fm_rtc_disable)
1259 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
1260 + if (mac_dev->ptp_disable)
1261 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
1262 + break;
1263 + case PTP_ENBL_RXTS_IOCTL:
1264 + tsu->hwts_rx_en_ioctl = 1;
1265 + break;
1266 + case PTP_DSBL_RXTS_IOCTL:
1267 + tsu->hwts_rx_en_ioctl = 0;
1268 + break;
1269 + case PTP_GET_RX_TIMESTAMP:
1270 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1271 + if (copy_from_user(&ptp_data.ident,
1272 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1273 + return -EINVAL;
1274 +
1275 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1276 + return -EAGAIN;
1277 +
1278 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1279 + &ptp_data.ts, sizeof(ptp_data.ts)))
1280 + return -EFAULT;
1281 + break;
1282 + case PTP_GET_TX_TIMESTAMP:
1283 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
1284 + if (copy_from_user(&ptp_data.ident,
1285 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
1286 + return -EINVAL;
1287 +
1288 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
1289 + return -EAGAIN;
1290 +
1291 + if (copy_to_user((void __user *)&ptp_data_user->ts,
1292 + &ptp_data.ts, sizeof(ptp_data.ts)))
1293 + return -EFAULT;
1294 + break;
1295 + case PTP_GET_TIME:
1296 + dpa_get_curr_cnt(tsu, &act_time);
1297 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
1298 + return -EFAULT;
1299 + break;
1300 + case PTP_SET_TIME:
1301 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1302 + return -EINVAL;
1303 + dpa_set_1588cnt(tsu, &act_time);
1304 + break;
1305 + case PTP_GET_ADJ:
1306 + dpa_get_drift(tsu, &addend);
1307 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
1308 + return -EFAULT;
1309 + break;
1310 + case PTP_SET_ADJ:
1311 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
1312 + return -EINVAL;
1313 + dpa_set_drift(tsu, addend);
1314 + break;
1315 + case PTP_SET_FIPER_ALARM:
1316 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
1317 + return -EINVAL;
1318 + dpa_set_fiper_alarm(tsu, &act_time);
1319 + break;
1320 + case PTP_CLEANUP_TS:
1321 + dpa_flush_timestamp(tsu);
1322 + break;
1323 + default:
1324 + return -EINVAL;
1325 + }
1326 +
1327 + return retval;
1328 +}
1329 +
1330 +int dpa_ptp_init(struct dpa_priv_s *priv)
1331 +{
1332 + struct dpa_ptp_tsu *tsu;
1333 +
1334 + /* Allocate memory for PTP structure */
1335 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
1336 + if (!tsu)
1337 + return -ENOMEM;
1338 +
1339 + tsu->valid = TRUE;
1340 + tsu->dpa_priv = priv;
1341 +
1342 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
1343 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
1344 +
1345 + priv->tsu = tsu;
1346 +
1347 + return 0;
1348 +}
1349 +EXPORT_SYMBOL(dpa_ptp_init);
1350 +
1351 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
1352 +{
1353 + struct dpa_ptp_tsu *tsu = priv->tsu;
1354 +
1355 + tsu->valid = FALSE;
1356 + vfree(tsu->rx_timestamps.circ_buf.buf);
1357 + vfree(tsu->tx_timestamps.circ_buf.buf);
1358 +
1359 + kfree(tsu);
1360 +}
1361 +EXPORT_SYMBOL(dpa_ptp_cleanup);
1362 --- /dev/null
1363 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
1364 @@ -0,0 +1,138 @@
1365 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
1366 + *
1367 + * This program is free software; you can redistribute it and/or modify
1368 + * it under the terms of the GNU General Public License as published by
1369 + * the Free Software Foundation; either version 2 of the License, or
1370 + * (at your option) any later version.
1371 + *
1372 + * This program is distributed in the hope that it will be useful,
1373 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1374 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1375 + * GNU General Public License for more details.
1376 + *
1377 + * You should have received a copy of the GNU General Public License along
1378 + * with this program; if not, write to the Free Software Foundation, Inc.,
1379 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1380 + *
1381 + */
1382 +#ifndef __DPAA_1588_H__
1383 +#define __DPAA_1588_H__
1384 +
1385 +#include <linux/netdevice.h>
1386 +#include <linux/etherdevice.h>
1387 +#include <linux/circ_buf.h>
1388 +#include <linux/fsl_qman.h>
1389 +
1390 +#define DEFAULT_PTP_RX_BUF_SZ 256
1391 +#define DEFAULT_PTP_TX_BUF_SZ 256
1392 +
1393 +/* 1588 private ioctl calls */
1394 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
1395 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
1396 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
1397 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
1398 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
1399 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
1400 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
1401 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
1402 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
1403 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
1404 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
1405 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
1406 +
1407 +/* PTP V2 message type */
1408 +enum {
1409 + PTP_MSGTYPE_SYNC = 0x0,
1410 + PTP_MSGTYPE_DELREQ = 0x1,
1411 + PTP_MSGTYPE_PDELREQ = 0x2,
1412 + PTP_MSGTYPE_PDELRESP = 0x3,
1413 + PTP_MSGTYPE_FLWUP = 0x8,
1414 + PTP_MSGTYPE_DELRESP = 0x9,
1415 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
1416 + PTP_MSGTYPE_ANNOUNCE = 0xB,
1417 + PTP_MSGTYPE_SGNLNG = 0xC,
1418 + PTP_MSGTYPE_MNGMNT = 0xD,
1419 +};
1420 +
1421 +/* Byte offset of data in the PTP V2 headers */
1422 +#define PTP_OFFS_MSG_TYPE 0
1423 +#define PTP_OFFS_VER_PTP 1
1424 +#define PTP_OFFS_MSG_LEN 2
1425 +#define PTP_OFFS_DOM_NMB 4
1426 +#define PTP_OFFS_FLAGS 6
1427 +#define PTP_OFFS_CORFIELD 8
1428 +#define PTP_OFFS_SRCPRTID 20
1429 +#define PTP_OFFS_SEQ_ID 30
1430 +#define PTP_OFFS_CTRL 32
1431 +#define PTP_OFFS_LOGMEAN 33
1432 +
1433 +#define PTP_IP_OFFS 14
1434 +#define PTP_UDP_OFFS 34
1435 +#define PTP_HEADER_OFFS 42
1436 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
1437 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
1438 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
1439 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
1440 +
1441 +/* 1588-2008 network protocol enumeration values */
1442 +#define DPA_PTP_PROT_IPV4 1
1443 +#define DPA_PTP_PROT_IPV6 2
1444 +#define DPA_PTP_PROT_802_3 3
1445 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
1446 +
1447 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
1448 +#define DPA_PTP_HEADER_SZE 34
1449 +#define DPA_ETYPE_LEN 2
1450 +#define DPA_VLAN_TAG_LEN 4
1451 +#define NANOSEC_PER_SECOND 1000000000
1452 +
1453 +/* The threshold between the current found one and the oldest one */
1454 +#define TS_ACCUMULATION_THRESHOLD 50
1455 +
1456 +/* Struct needed to identify a timestamp */
1457 +struct dpa_ptp_ident {
1458 + u8 version;
1459 + u8 msg_type;
1460 + u16 netw_prot;
1461 + u16 seq_id;
1462 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
1463 +};
1464 +
1465 +/* Timestamp format in 1588-2008 */
1466 +struct dpa_ptp_time {
1467 + u64 sec; /* just 48 bit used */
1468 + u32 nsec;
1469 +};
1470 +
1471 +/* needed for timestamp data over ioctl */
1472 +struct dpa_ptp_data {
1473 + struct dpa_ptp_ident ident;
1474 + struct dpa_ptp_time ts;
1475 +};
1476 +
1477 +struct dpa_ptp_circ_buf {
1478 + struct circ_buf circ_buf;
1479 + u32 size;
1480 + spinlock_t ptp_lock;
1481 +};
1482 +
1483 +/* PTP TSU control structure */
1484 +struct dpa_ptp_tsu {
1485 + struct dpa_priv_s *dpa_priv;
1486 + bool valid;
1487 + struct dpa_ptp_circ_buf rx_timestamps;
1488 + struct dpa_ptp_circ_buf tx_timestamps;
1489 +
1490 + /* HW timestamping over ioctl enabled flag */
1491 + int hwts_tx_en_ioctl;
1492 + int hwts_rx_en_ioctl;
1493 +};
1494 +
1495 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
1496 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
1497 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
1498 + struct sk_buff *skb, void *data);
1499 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
1500 + struct sk_buff *skb, void *data);
1501 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
1502 +#endif
1503 --- /dev/null
1504 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
1505 @@ -0,0 +1,180 @@
1506 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1507 + *
1508 + * Redistribution and use in source and binary forms, with or without
1509 + * modification, are permitted provided that the following conditions are met:
1510 + * * Redistributions of source code must retain the above copyright
1511 + * notice, this list of conditions and the following disclaimer.
1512 + * * Redistributions in binary form must reproduce the above copyright
1513 + * notice, this list of conditions and the following disclaimer in the
1514 + * documentation and/or other materials provided with the distribution.
1515 + * * Neither the name of Freescale Semiconductor nor the
1516 + * names of its contributors may be used to endorse or promote products
1517 + * derived from this software without specific prior written permission.
1518 + *
1519 + *
1520 + * ALTERNATIVELY, this software may be distributed under the terms of the
1521 + * GNU General Public License ("GPL") as published by the Free Software
1522 + * Foundation, either version 2 of that License or (at your option) any
1523 + * later version.
1524 + *
1525 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1526 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1527 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1528 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1529 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1530 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1531 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1532 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1533 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1534 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1535 + */
1536 +
1537 +#include <linux/module.h>
1538 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
1539 +#include <linux/debugfs.h>
1540 +#include "dpaa_debugfs.h"
1541 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
1542 +
1543 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
1544 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
1545 +
1546 +static struct dentry *dpa_debugfs_root;
1547 +
1548 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
1549 +static ssize_t dpa_loop_write(struct file *f,
1550 + const char __user *buf, size_t count, loff_t *off);
1551 +
1552 +static const struct file_operations dpa_debugfs_lp_fops = {
1553 + .open = dpa_debugfs_loop_open,
1554 + .write = dpa_loop_write,
1555 + .read = seq_read,
1556 + .llseek = seq_lseek,
1557 + .release = single_release,
1558 +};
1559 +
1560 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
1561 +{
1562 + struct dpa_priv_s *priv;
1563 +
1564 + BUG_ON(offset == NULL);
1565 +
1566 + priv = netdev_priv((struct net_device *)file->private);
1567 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
1568 +
1569 + return 0;
1570 +}
1571 +
1572 +static int user_input_convert(const char __user *user_buf, size_t count,
1573 + long *val)
1574 +{
1575 + char buf[12];
1576 +
1577 + if (count > sizeof(buf) - 1)
1578 + return -EINVAL;
1579 + if (copy_from_user(buf, user_buf, count))
1580 + return -EFAULT;
1581 + buf[count] = '\0';
1582 + if (kstrtol(buf, 0, val))
1583 + return -EINVAL;
1584 + return 0;
1585 +}
1586 +
1587 +static ssize_t dpa_loop_write(struct file *f,
1588 + const char __user *buf, size_t count, loff_t *off)
1589 +{
1590 + struct dpa_priv_s *priv;
1591 + struct net_device *netdev;
1592 + struct seq_file *sf;
1593 + int ret;
1594 + long val;
1595 +
1596 + ret = user_input_convert(buf, count, &val);
1597 + if (ret)
1598 + return ret;
1599 +
1600 + sf = (struct seq_file *)f->private_data;
1601 + netdev = (struct net_device *)sf->private;
1602 + priv = netdev_priv(netdev);
1603 +
1604 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
1605 +
1606 + return count;
1607 +}
1608 +
1609 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
1610 +{
1611 + int _errno;
1612 + const struct net_device *net_dev;
1613 +
1614 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
1615 + if (unlikely(_errno < 0)) {
1616 + net_dev = (struct net_device *)inode->i_private;
1617 +
1618 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
1619 + netdev_err(net_dev, "single_open() = %d\n",
1620 + _errno);
1621 + }
1622 +
1623 + return _errno;
1624 +}
1625 +
1626 +
1627 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
1628 +{
1629 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1630 + static int cnt;
1631 + char loop_file_name[100];
1632 +
1633 + if (unlikely(dpa_debugfs_root == NULL)) {
1634 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
1635 + KBUILD_BASENAME".c", __LINE__, __func__,
1636 + "root debugfs missing, possible module ordering issue");
1637 + return -ENOMEM;
1638 + }
1639 +
1640 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
1641 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
1642 + S_IRUGO,
1643 + dpa_debugfs_root,
1644 + net_dev,
1645 + &dpa_debugfs_lp_fops);
1646 + if (unlikely(priv->debugfs_loop_file == NULL)) {
1647 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
1648 + dpa_debugfs_root->d_iname,
1649 + loop_file_name);
1650 +
1651 + return -ENOMEM;
1652 + }
1653 + return 0;
1654 +}
1655 +
1656 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
1657 +{
1658 + struct dpa_priv_s *priv = netdev_priv(net_dev);
1659 +
1660 + debugfs_remove(priv->debugfs_loop_file);
1661 +}
1662 +
1663 +int __init dpa_debugfs_module_init(void)
1664 +{
1665 + int _errno = 0;
1666 +
1667 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
1668 +
1669 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
1670 +
1671 + if (unlikely(dpa_debugfs_root == NULL)) {
1672 + _errno = -ENOMEM;
1673 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
1674 + KBUILD_BASENAME".c", __LINE__, __func__);
1675 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
1676 + DPA_ETH_DEBUGFS_ROOT, _errno);
1677 + }
1678 +
1679 + return _errno;
1680 +}
1681 +
1682 +void __exit dpa_debugfs_module_exit(void)
1683 +{
1684 + debugfs_remove(dpa_debugfs_root);
1685 +}
1686 --- /dev/null
1687 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
1688 @@ -0,0 +1,43 @@
1689 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1690 + *
1691 + * Redistribution and use in source and binary forms, with or without
1692 + * modification, are permitted provided that the following conditions are met:
1693 + * * Redistributions of source code must retain the above copyright
1694 + * notice, this list of conditions and the following disclaimer.
1695 + * * Redistributions in binary form must reproduce the above copyright
1696 + * notice, this list of conditions and the following disclaimer in the
1697 + * documentation and/or other materials provided with the distribution.
1698 + * * Neither the name of Freescale Semiconductor nor the
1699 + * names of its contributors may be used to endorse or promote products
1700 + * derived from this software without specific prior written permission.
1701 + *
1702 + *
1703 + * ALTERNATIVELY, this software may be distributed under the terms of the
1704 + * GNU General Public License ("GPL") as published by the Free Software
1705 + * Foundation, either version 2 of that License or (at your option) any
1706 + * later version.
1707 + *
1708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1718 + */
1719 +
1720 +#ifndef DPAA_DEBUGFS_H_
1721 +#define DPAA_DEBUGFS_H_
1722 +
1723 +#include <linux/netdevice.h>
1724 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
1725 +
1726 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
1727 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
1728 +int __init dpa_debugfs_module_init(void);
1729 +void __exit dpa_debugfs_module_exit(void);
1730 +
1731 +#endif /* DPAA_DEBUGFS_H_ */
1732 --- /dev/null
1733 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
1734 @@ -0,0 +1,1224 @@
1735 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
1736 + *
1737 + * Redistribution and use in source and binary forms, with or without
1738 + * modification, are permitted provided that the following conditions are met:
1739 + * * Redistributions of source code must retain the above copyright
1740 + * notice, this list of conditions and the following disclaimer.
1741 + * * Redistributions in binary form must reproduce the above copyright
1742 + * notice, this list of conditions and the following disclaimer in the
1743 + * documentation and/or other materials provided with the distribution.
1744 + * * Neither the name of Freescale Semiconductor nor the
1745 + * names of its contributors may be used to endorse or promote products
1746 + * derived from this software without specific prior written permission.
1747 + *
1748 + *
1749 + * ALTERNATIVELY, this software may be distributed under the terms of the
1750 + * GNU General Public License ("GPL") as published by the Free Software
1751 + * Foundation, either version 2 of that License or (at your option) any
1752 + * later version.
1753 + *
1754 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
1755 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1756 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1757 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
1758 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1759 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1760 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1761 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1762 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1763 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1764 + */
1765 +
1766 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
1767 +#define pr_fmt(fmt) \
1768 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
1769 + KBUILD_BASENAME".c", __LINE__, __func__
1770 +#else
1771 +#define pr_fmt(fmt) \
1772 + KBUILD_MODNAME ": " fmt
1773 +#endif
1774 +
1775 +#include <linux/init.h>
1776 +#include <linux/module.h>
1777 +#include <linux/of_mdio.h>
1778 +#include <linux/of_net.h>
1779 +#include <linux/kthread.h>
1780 +#include <linux/io.h>
1781 +#include <linux/if_arp.h> /* arp_hdr_len() */
1782 +#include <linux/if_vlan.h> /* VLAN_HLEN */
1783 +#include <linux/icmp.h> /* struct icmphdr */
1784 +#include <linux/ip.h> /* struct iphdr */
1785 +#include <linux/ipv6.h> /* struct ipv6hdr */
1786 +#include <linux/udp.h> /* struct udphdr */
1787 +#include <linux/tcp.h> /* struct tcphdr */
1788 +#include <linux/net.h> /* net_ratelimit() */
1789 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
1790 +#include <linux/highmem.h>
1791 +#include <linux/percpu.h>
1792 +#include <linux/dma-mapping.h>
1793 +#include <linux/fsl_bman.h>
1794 +#ifdef CONFIG_SOC_BUS
1795 +#include <linux/sys_soc.h> /* soc_device_match */
1796 +#endif
1797 +
1798 +#include "fsl_fman.h"
1799 +#include "fm_ext.h"
1800 +#include "fm_port_ext.h"
1801 +
1802 +#include "mac.h"
1803 +#include "dpaa_eth.h"
1804 +#include "dpaa_eth_common.h"
1805 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1806 +#include "dpaa_debugfs.h"
1807 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
1808 +
1809 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
1810 + * using trace events only need to #include <trace/events/sched.h>
1811 + */
1812 +#define CREATE_TRACE_POINTS
1813 +#include "dpaa_eth_trace.h"
1814 +
1815 +#define DPA_NAPI_WEIGHT 64
1816 +
1817 +/* Valid checksum indication */
1818 +#define DPA_CSUM_VALID 0xFFFF
1819 +
1820 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
1821 +
1822 +MODULE_LICENSE("Dual BSD/GPL");
1823 +
1824 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
1825 +
1826 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
1827 +
1828 +static uint8_t debug = -1;
1829 +module_param(debug, byte, S_IRUGO);
1830 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
1831 +
1832 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
1833 +static uint16_t tx_timeout = 1000;
1834 +module_param(tx_timeout, ushort, S_IRUGO);
1835 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
1836 +
1837 +static const char rtx[][3] = {
1838 + [RX] = "RX",
1839 + [TX] = "TX"
1840 +};
1841 +
1842 +#ifndef CONFIG_PPC
1843 +bool dpaa_errata_a010022;
1844 +EXPORT_SYMBOL(dpaa_errata_a010022);
1845 +#endif
1846 +
1847 +/* BM */
1848 +
1849 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
1850 +
1851 +static uint8_t dpa_priv_common_bpid;
1852 +
1853 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
1854 +struct net_device *dpa_loop_netdevs[20];
1855 +#endif
1856 +
1857 +#ifdef CONFIG_PM
1858 +
1859 +static int dpaa_suspend(struct device *dev)
1860 +{
1861 + struct net_device *net_dev;
1862 + struct dpa_priv_s *priv;
1863 + struct mac_device *mac_dev;
1864 + int err = 0;
1865 +
1866 + net_dev = dev_get_drvdata(dev);
1867 +
1868 + if (net_dev->flags & IFF_UP) {
1869 + priv = netdev_priv(net_dev);
1870 + mac_dev = priv->mac_dev;
1871 +
1872 + if (priv->wol & DPAA_WOL_MAGIC) {
1873 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1874 + priv->mac_dev->get_mac_handle(mac_dev), true);
1875 + if (err) {
1876 + netdev_err(net_dev, "set_wol() = %d\n", err);
1877 + goto set_wol_failed;
1878 + }
1879 + }
1880 +
1881 + err = fm_port_suspend(mac_dev->port_dev[RX]);
1882 + if (err) {
1883 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
1884 + goto rx_port_suspend_failed;
1885 + }
1886 +
1887 + err = fm_port_suspend(mac_dev->port_dev[TX]);
1888 + if (err) {
1889 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
1890 + goto tx_port_suspend_failed;
1891 + }
1892 + }
1893 +
1894 + return 0;
1895 +
1896 +tx_port_suspend_failed:
1897 + fm_port_resume(mac_dev->port_dev[RX]);
1898 +rx_port_suspend_failed:
1899 + if (priv->wol & DPAA_WOL_MAGIC) {
1900 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1901 + priv->mac_dev->get_mac_handle(mac_dev), false);
1902 + }
1903 +set_wol_failed:
1904 + return err;
1905 +}
1906 +
1907 +static int dpaa_resume(struct device *dev)
1908 +{
1909 + struct net_device *net_dev;
1910 + struct dpa_priv_s *priv;
1911 + struct mac_device *mac_dev;
1912 + int err = 0;
1913 +
1914 + net_dev = dev_get_drvdata(dev);
1915 +
1916 + if (net_dev->flags & IFF_UP) {
1917 + priv = netdev_priv(net_dev);
1918 + mac_dev = priv->mac_dev;
1919 +
1920 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
1921 + if (err) {
1922 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
1923 + goto resume_failed;
1924 + }
1925 +
1926 + err = fm_port_resume(mac_dev->port_dev[TX]);
1927 + if (err) {
1928 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
1929 + goto resume_failed;
1930 + }
1931 +
1932 + err = fm_port_resume(mac_dev->port_dev[RX]);
1933 + if (err) {
1934 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
1935 + goto resume_failed;
1936 + }
1937 +
1938 + if (priv->wol & DPAA_WOL_MAGIC) {
1939 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
1940 + priv->mac_dev->get_mac_handle(mac_dev), false);
1941 + if (err) {
1942 + netdev_err(net_dev, "set_wol() = %d\n", err);
1943 + goto resume_failed;
1944 + }
1945 + }
1946 + }
1947 +
1948 + return 0;
1949 +
1950 +resume_failed:
1951 + return err;
1952 +}
1953 +
1954 +static const struct dev_pm_ops dpaa_pm_ops = {
1955 + .suspend = dpaa_suspend,
1956 + .resume = dpaa_resume,
1957 +};
1958 +
1959 +#define DPAA_PM_OPS (&dpaa_pm_ops)
1960 +
1961 +#else /* CONFIG_PM */
1962 +
1963 +#define DPAA_PM_OPS NULL
1964 +
1965 +#endif /* CONFIG_PM */
1966 +
1967 +/* Checks whether the checksum field in Parse Results array is valid
1968 + * (equals 0xFFFF) and increments the .cse counter otherwise
1969 + */
1970 +static inline void
1971 +dpa_csum_validation(const struct dpa_priv_s *priv,
1972 + struct dpa_percpu_priv_s *percpu_priv,
1973 + const struct qm_fd *fd)
1974 +{
1975 + dma_addr_t addr = qm_fd_addr(fd);
1976 + struct dpa_bp *dpa_bp = priv->dpa_bp;
1977 + void *frm = phys_to_virt(addr);
1978 + fm_prs_result_t *parse_result;
1979 +
1980 + if (unlikely(!frm))
1981 + return;
1982 +
1983 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
1984 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
1985 +
1986 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
1987 +
1988 + if (parse_result->cksum != DPA_CSUM_VALID)
1989 + percpu_priv->rx_errors.cse++;
1990 +}
1991 +
1992 +static void _dpa_rx_error(struct net_device *net_dev,
1993 + const struct dpa_priv_s *priv,
1994 + struct dpa_percpu_priv_s *percpu_priv,
1995 + const struct qm_fd *fd,
1996 + u32 fqid)
1997 +{
1998 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
1999 + * interference with zero-loss convergence benchmark results.
2000 + */
2001 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
2002 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
2003 + else
2004 + if (netif_msg_hw(priv) && net_ratelimit())
2005 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
2006 + fd->status & FM_FD_STAT_RX_ERRORS);
2007 +#ifdef CONFIG_FSL_DPAA_HOOKS
2008 + if (dpaa_eth_hooks.rx_error &&
2009 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2010 + /* it's up to the hook to perform resource cleanup */
2011 + return;
2012 +#endif
2013 + percpu_priv->stats.rx_errors++;
2014 +
2015 + if (fd->status & FM_PORT_FRM_ERR_DMA)
2016 + percpu_priv->rx_errors.dme++;
2017 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
2018 + percpu_priv->rx_errors.fpe++;
2019 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
2020 + percpu_priv->rx_errors.fse++;
2021 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
2022 + percpu_priv->rx_errors.phe++;
2023 + if (fd->status & FM_FD_STAT_L4CV)
2024 + dpa_csum_validation(priv, percpu_priv, fd);
2025 +
2026 + dpa_fd_release(net_dev, fd);
2027 +}
2028 +
2029 +static void _dpa_tx_error(struct net_device *net_dev,
2030 + const struct dpa_priv_s *priv,
2031 + struct dpa_percpu_priv_s *percpu_priv,
2032 + const struct qm_fd *fd,
2033 + u32 fqid)
2034 +{
2035 + struct sk_buff *skb;
2036 +
2037 + if (netif_msg_hw(priv) && net_ratelimit())
2038 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2039 + fd->status & FM_FD_STAT_TX_ERRORS);
2040 +#ifdef CONFIG_FSL_DPAA_HOOKS
2041 + if (dpaa_eth_hooks.tx_error &&
2042 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
2043 + /* now the hook must ensure proper cleanup */
2044 + return;
2045 +#endif
2046 + percpu_priv->stats.tx_errors++;
2047 +
2048 + /* If we intended the buffers from this frame to go into the bpools
2049 + * when the FMan transmit was done, we need to put it in manually.
2050 + */
2051 + if (fd->bpid != 0xff) {
2052 + dpa_fd_release(net_dev, fd);
2053 + return;
2054 + }
2055 +
2056 + skb = _dpa_cleanup_tx_fd(priv, fd);
2057 + dev_kfree_skb(skb);
2058 +}
2059 +
2060 +/* Helper function to factor out frame validation logic on all Rx paths. Its
2061 + * purpose is to extract from the Parse Results structure information about
2062 + * the integrity of the frame, its checksum, the length of the parsed headers
2063 + * and whether the frame is suitable for GRO.
2064 + *
2065 + * Assumes no parser errors, since any error frame is dropped before this
2066 + * function is called.
2067 + *
2068 + * @skb will have its ip_summed field overwritten;
2069 + * @use_gro will only be written with 0, if the frame is definitely not
2070 + * GRO-able; otherwise, it will be left unchanged;
2071 + * @hdr_size will be written with a safe value, at least the size of the
2072 + * headers' length.
2073 + */
2074 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
2075 + const struct qm_fd *fd,
2076 + struct sk_buff *skb, int *use_gro)
2077 +{
2078 + if (fd->status & FM_FD_STAT_L4CV) {
2079 + /* The parser has run and performed L4 checksum validation.
2080 + * We know there were no parser errors (and implicitly no
2081 + * L4 csum error), otherwise we wouldn't be here.
2082 + */
2083 + skb->ip_summed = CHECKSUM_UNNECESSARY;
2084 +
2085 + /* Don't go through GRO for certain types of traffic that
2086 + * we know are not GRO-able, such as dgram-based protocols.
2087 + * In the worst-case scenarios, such as small-pkt terminating
2088 + * UDP, the extra GRO processing would be overkill.
2089 + *
2090 + * The only protocol the Parser supports that is also GRO-able
2091 + * is currently TCP.
2092 + */
2093 + if (!fm_l4_frame_is_tcp(parse_results))
2094 + *use_gro = 0;
2095 +
2096 + return;
2097 + }
2098 +
2099 + /* We're here because either the parser didn't run or the L4 checksum
2100 + * was not verified. This may include the case of a UDP frame with
2101 + * checksum zero or an L4 proto other than TCP/UDP
2102 + */
2103 + skb->ip_summed = CHECKSUM_NONE;
2104 +
2105 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
2106 + *use_gro = 0;
2107 +}
2108 +
2109 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
2110 +{
2111 + struct dpa_napi_portal *np =
2112 + container_of(napi, struct dpa_napi_portal, napi);
2113 +
2114 + int cleaned = qman_p_poll_dqrr(np->p, budget);
2115 +
2116 + if (cleaned < budget) {
2117 + int tmp;
2118 + napi_complete(napi);
2119 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2120 + DPA_BUG_ON(tmp);
2121 + }
2122 +
2123 + return cleaned;
2124 +}
2125 +EXPORT_SYMBOL(dpaa_eth_poll);
2126 +
2127 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
2128 + const struct dpa_priv_s *priv,
2129 + struct dpa_percpu_priv_s *percpu_priv,
2130 + const struct qm_fd *fd,
2131 + u32 fqid)
2132 +{
2133 + struct sk_buff *skb;
2134 +
2135 + /* do we need the timestamp for the error frames? */
2136 +
2137 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
2138 + if (netif_msg_hw(priv) && net_ratelimit())
2139 + netdev_warn(net_dev, "FD status = 0x%08x\n",
2140 + fd->status & FM_FD_STAT_TX_ERRORS);
2141 +
2142 + percpu_priv->stats.tx_errors++;
2143 + }
2144 +
2145 + /* hopefully we need not get the timestamp before the hook */
2146 +#ifdef CONFIG_FSL_DPAA_HOOKS
2147 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
2148 + fd, fqid) == DPAA_ETH_STOLEN)
2149 + /* it's the hook that must now perform cleanup */
2150 + return;
2151 +#endif
2152 + /* This might not perfectly reflect the reality, if the core dequeuing
2153 + * the Tx confirmation is different from the one that did the enqueue,
2154 + * but at least it'll show up in the total count.
2155 + */
2156 + percpu_priv->tx_confirm++;
2157 +
2158 + skb = _dpa_cleanup_tx_fd(priv, fd);
2159 +
2160 + dev_kfree_skb(skb);
2161 +}
2162 +
2163 +enum qman_cb_dqrr_result
2164 +priv_rx_error_dqrr(struct qman_portal *portal,
2165 + struct qman_fq *fq,
2166 + const struct qm_dqrr_entry *dq)
2167 +{
2168 + struct net_device *net_dev;
2169 + struct dpa_priv_s *priv;
2170 + struct dpa_percpu_priv_s *percpu_priv;
2171 + int *count_ptr;
2172 +
2173 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2174 + priv = netdev_priv(net_dev);
2175 +
2176 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2177 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
2178 +
2179 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2180 + return qman_cb_dqrr_stop;
2181 +
2182 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
2183 + /* Unable to refill the buffer pool due to insufficient
2184 + * system memory. Just release the frame back into the pool,
2185 + * otherwise we'll soon end up with an empty buffer pool.
2186 + */
2187 + dpa_fd_release(net_dev, &dq->fd);
2188 + else
2189 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2190 +
2191 + return qman_cb_dqrr_consume;
2192 +}
2193 +
2194 +
2195 +enum qman_cb_dqrr_result __hot
2196 +priv_rx_default_dqrr(struct qman_portal *portal,
2197 + struct qman_fq *fq,
2198 + const struct qm_dqrr_entry *dq)
2199 +{
2200 + struct net_device *net_dev;
2201 + struct dpa_priv_s *priv;
2202 + struct dpa_percpu_priv_s *percpu_priv;
2203 + int *count_ptr;
2204 + struct dpa_bp *dpa_bp;
2205 +
2206 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2207 + priv = netdev_priv(net_dev);
2208 + dpa_bp = priv->dpa_bp;
2209 +
2210 + /* Trace the Rx fd */
2211 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
2212 +
2213 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
2214 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2215 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
2216 +
2217 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
2218 + return qman_cb_dqrr_stop;
2219 +
2220 + /* Vale of plenty: make sure we didn't run out of buffers */
2221 +
2222 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
2223 + /* Unable to refill the buffer pool due to insufficient
2224 + * system memory. Just release the frame back into the pool,
2225 + * otherwise we'll soon end up with an empty buffer pool.
2226 + */
2227 + dpa_fd_release(net_dev, &dq->fd);
2228 + else
2229 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
2230 + count_ptr);
2231 +
2232 + return qman_cb_dqrr_consume;
2233 +}
2234 +
2235 +enum qman_cb_dqrr_result
2236 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
2237 + struct qman_fq *fq,
2238 + const struct qm_dqrr_entry *dq)
2239 +{
2240 + struct net_device *net_dev;
2241 + struct dpa_priv_s *priv;
2242 + struct dpa_percpu_priv_s *percpu_priv;
2243 +
2244 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2245 + priv = netdev_priv(net_dev);
2246 +
2247 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2248 +
2249 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2250 + return qman_cb_dqrr_stop;
2251 +
2252 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2253 +
2254 + return qman_cb_dqrr_consume;
2255 +}
2256 +
2257 +enum qman_cb_dqrr_result __hot
2258 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
2259 + struct qman_fq *fq,
2260 + const struct qm_dqrr_entry *dq)
2261 +{
2262 + struct net_device *net_dev;
2263 + struct dpa_priv_s *priv;
2264 + struct dpa_percpu_priv_s *percpu_priv;
2265 +
2266 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2267 + priv = netdev_priv(net_dev);
2268 +
2269 + /* Trace the fd */
2270 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
2271 +
2272 + /* Non-migratable context, safe to use raw_cpu_ptr */
2273 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2274 +
2275 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
2276 + return qman_cb_dqrr_stop;
2277 +
2278 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
2279 +
2280 + return qman_cb_dqrr_consume;
2281 +}
2282 +
2283 +void priv_ern(struct qman_portal *portal,
2284 + struct qman_fq *fq,
2285 + const struct qm_mr_entry *msg)
2286 +{
2287 + struct net_device *net_dev;
2288 + const struct dpa_priv_s *priv;
2289 + struct sk_buff *skb;
2290 + struct dpa_percpu_priv_s *percpu_priv;
2291 + struct qm_fd fd = msg->ern.fd;
2292 +
2293 + net_dev = ((struct dpa_fq *)fq)->net_dev;
2294 + priv = netdev_priv(net_dev);
2295 + /* Non-migratable context, safe to use raw_cpu_ptr */
2296 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
2297 +
2298 + percpu_priv->stats.tx_dropped++;
2299 + percpu_priv->stats.tx_fifo_errors++;
2300 + count_ern(percpu_priv, msg);
2301 +
2302 + /* If we intended this buffer to go into the pool
2303 + * when the FM was done, we need to put it in
2304 + * manually.
2305 + */
2306 + if (msg->ern.fd.bpid != 0xff) {
2307 + dpa_fd_release(net_dev, &fd);
2308 + return;
2309 + }
2310 +
2311 + skb = _dpa_cleanup_tx_fd(priv, &fd);
2312 + dev_kfree_skb_any(skb);
2313 +}
2314 +
2315 +const struct dpa_fq_cbs_t private_fq_cbs = {
2316 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
2317 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
2318 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
2319 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
2320 + .egress_ern = { .cb = { .ern = priv_ern } }
2321 +};
2322 +EXPORT_SYMBOL(private_fq_cbs);
2323 +
2324 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
2325 +{
2326 + struct dpa_percpu_priv_s *percpu_priv;
2327 + int i, j;
2328 +
2329 + for_each_possible_cpu(i) {
2330 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2331 +
2332 + for (j = 0; j < qman_portal_max; j++)
2333 + napi_enable(&percpu_priv->np[j].napi);
2334 + }
2335 +}
2336 +
2337 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
2338 +{
2339 + struct dpa_percpu_priv_s *percpu_priv;
2340 + int i, j;
2341 +
2342 + for_each_possible_cpu(i) {
2343 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2344 +
2345 + for (j = 0; j < qman_portal_max; j++)
2346 + napi_disable(&percpu_priv->np[j].napi);
2347 + }
2348 +}
2349 +
2350 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
2351 +{
2352 + int err;
2353 + struct dpa_priv_s *priv;
2354 +
2355 + priv = netdev_priv(net_dev);
2356 +
2357 + dpaa_eth_napi_enable(priv);
2358 +
2359 + err = dpa_start(net_dev);
2360 + if (err < 0)
2361 + dpaa_eth_napi_disable(priv);
2362 +
2363 + return err;
2364 +}
2365 +
2366 +
2367 +
2368 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
2369 +{
2370 + int _errno;
2371 + struct dpa_priv_s *priv;
2372 +
2373 + _errno = dpa_stop(net_dev);
2374 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
2375 + * ingress queues. This is to avoid a race between the current
2376 + * context and ksoftirqd which could leave NAPI disabled while
2377 + * in fact there's still Rx traffic to be processed.
2378 + */
2379 + usleep_range(5000, 10000);
2380 +
2381 + priv = netdev_priv(net_dev);
2382 + dpaa_eth_napi_disable(priv);
2383 +
2384 + return _errno;
2385 +}
2386 +
2387 +#ifdef CONFIG_NET_POLL_CONTROLLER
2388 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
2389 +{
2390 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2391 + struct dpa_percpu_priv_s *percpu_priv =
2392 + raw_cpu_ptr(priv->percpu_priv);
2393 + struct qman_portal *p;
2394 + const struct qman_portal_config *pc;
2395 + struct dpa_napi_portal *np;
2396 +
2397 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
2398 + pc = qman_p_get_portal_config(p);
2399 + np = &percpu_priv->np[pc->index];
2400 +
2401 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
2402 + qman_p_poll_dqrr(np->p, np->napi.weight);
2403 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
2404 +}
2405 +#endif
2406 +
2407 +static const struct net_device_ops dpa_private_ops = {
2408 + .ndo_open = dpa_eth_priv_start,
2409 + .ndo_start_xmit = dpa_tx,
2410 + .ndo_stop = dpa_eth_priv_stop,
2411 + .ndo_tx_timeout = dpa_timeout,
2412 + .ndo_get_stats64 = dpa_get_stats64,
2413 + .ndo_set_mac_address = dpa_set_mac_address,
2414 + .ndo_validate_addr = eth_validate_addr,
2415 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
2416 + .ndo_select_queue = dpa_select_queue,
2417 +#endif
2418 + .ndo_change_mtu = dpa_change_mtu,
2419 + .ndo_set_rx_mode = dpa_set_rx_mode,
2420 + .ndo_init = dpa_ndo_init,
2421 + .ndo_set_features = dpa_set_features,
2422 + .ndo_fix_features = dpa_fix_features,
2423 + .ndo_do_ioctl = dpa_ioctl,
2424 +#ifdef CONFIG_NET_POLL_CONTROLLER
2425 + .ndo_poll_controller = dpaa_eth_poll_controller,
2426 +#endif
2427 +};
2428 +
2429 +static int dpa_private_napi_add(struct net_device *net_dev)
2430 +{
2431 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2432 + struct dpa_percpu_priv_s *percpu_priv;
2433 + int i, cpu;
2434 +
2435 + for_each_possible_cpu(cpu) {
2436 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2437 +
2438 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
2439 + qman_portal_max * sizeof(struct dpa_napi_portal),
2440 + GFP_KERNEL);
2441 +
2442 + if (unlikely(percpu_priv->np == NULL)) {
2443 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
2444 + return -ENOMEM;
2445 + }
2446 +
2447 + for (i = 0; i < qman_portal_max; i++)
2448 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
2449 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
2450 + }
2451 +
2452 + return 0;
2453 +}
2454 +
2455 +void dpa_private_napi_del(struct net_device *net_dev)
2456 +{
2457 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2458 + struct dpa_percpu_priv_s *percpu_priv;
2459 + int i, cpu;
2460 +
2461 + for_each_possible_cpu(cpu) {
2462 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
2463 +
2464 + if (percpu_priv->np) {
2465 + for (i = 0; i < qman_portal_max; i++)
2466 + netif_napi_del(&percpu_priv->np[i].napi);
2467 +
2468 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
2469 + }
2470 + }
2471 +}
2472 +EXPORT_SYMBOL(dpa_private_napi_del);
2473 +
2474 +static int dpa_private_netdev_init(struct net_device *net_dev)
2475 +{
2476 + int i;
2477 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2478 + struct dpa_percpu_priv_s *percpu_priv;
2479 + const uint8_t *mac_addr;
2480 +
2481 + /* Although we access another CPU's private data here
2482 + * we do it at initialization so it is safe
2483 + */
2484 + for_each_possible_cpu(i) {
2485 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2486 + percpu_priv->net_dev = net_dev;
2487 + }
2488 +
2489 + net_dev->netdev_ops = &dpa_private_ops;
2490 + mac_addr = priv->mac_dev->addr;
2491 +
2492 + net_dev->mem_start = priv->mac_dev->res->start;
2493 + net_dev->mem_end = priv->mac_dev->res->end;
2494 +
2495 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
2496 + NETIF_F_LLTX);
2497 +
2498 + /* Advertise S/G and HIGHDMA support for private interfaces */
2499 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
2500 + /* Recent kernels enable GSO automatically, if
2501 + * we declare NETIF_F_SG. For conformity, we'll
2502 + * still declare GSO explicitly.
2503 + */
2504 + net_dev->features |= NETIF_F_GSO;
2505 +
2506 + /* Advertise GRO support */
2507 + net_dev->features |= NETIF_F_GRO;
2508 +
2509 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
2510 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
2511 +
2512 +#ifndef CONFIG_PPC
2513 + /* Due to the A010022 FMan errata, we can not use contig frames larger
2514 + * than 4K, nor S/G frames. We need to stop advertising S/G and GSO
2515 + * support.
2516 + */
2517 + if (unlikely(dpaa_errata_a010022)) {
2518 + net_dev->hw_features &= ~NETIF_F_SG;
2519 + net_dev->features &= ~NETIF_F_GSO;
2520 + }
2521 +#endif
2522 +
2523 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
2524 +}
2525 +
2526 +static struct dpa_bp * __cold
2527 +dpa_priv_bp_probe(struct device *dev)
2528 +{
2529 + struct dpa_bp *dpa_bp;
2530 +
2531 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
2532 + if (unlikely(dpa_bp == NULL)) {
2533 + dev_err(dev, "devm_kzalloc() failed\n");
2534 + return ERR_PTR(-ENOMEM);
2535 + }
2536 +
2537 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
2538 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
2539 +
2540 + dpa_bp->seed_cb = dpa_bp_priv_seed;
2541 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
2542 +
2543 + return dpa_bp;
2544 +}
2545 +
2546 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
2547 + * We won't be sending congestion notifications to FMan; for now, we just use
2548 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
2549 + * before they reach our ingress queues and eat up memory.
2550 + */
2551 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
2552 +{
2553 + struct qm_mcc_initcgr initcgr;
2554 + u32 cs_th;
2555 + int err;
2556 +
2557 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
2558 + if (err < 0) {
2559 + pr_err("Error %d allocating CGR ID\n", err);
2560 + goto out_error;
2561 + }
2562 +
2563 + /* Enable CS TD, but disable Congestion State Change Notifications. */
2564 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
2565 + initcgr.cgr.cscn_en = QM_CGR_EN;
2566 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
2567 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
2568 +
2569 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
2570 + initcgr.cgr.cstd_en = QM_CGR_EN;
2571 +
2572 + /* This is actually a hack, because this CGR will be associated with
2573 + * our affine SWP. However, we'll place our ingress FQs in it.
2574 + */
2575 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
2576 + &initcgr);
2577 + if (err < 0) {
2578 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
2579 + priv->ingress_cgr.cgrid);
2580 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2581 + goto out_error;
2582 + }
2583 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
2584 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
2585 +
2586 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
2587 + * range), but we have no common initialization path between the
2588 + * different variants of the DPAA Eth driver, so we do it here rather
2589 + * than modifying every other variant than "private Eth".
2590 + */
2591 + priv->use_ingress_cgr = true;
2592 +
2593 +out_error:
2594 + return err;
2595 +}
2596 +
2597 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
2598 + size_t count)
2599 +{
2600 + struct dpa_priv_s *priv = netdev_priv(net_dev);
2601 + int i;
2602 +
2603 + if (netif_msg_probe(priv))
2604 + dev_dbg(net_dev->dev.parent,
2605 + "Using private BM buffer pools\n");
2606 +
2607 + priv->bp_count = count;
2608 +
2609 + for (i = 0; i < count; i++) {
2610 + int err;
2611 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
2612 + if (err < 0) {
2613 + dpa_bp_free(priv);
2614 + priv->dpa_bp = NULL;
2615 + return err;
2616 + }
2617 +
2618 + priv->dpa_bp = &dpa_bp[i];
2619 + }
2620 +
2621 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
2622 + return 0;
2623 +}
2624 +
2625 +static const struct of_device_id dpa_match[];
2626 +
2627 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2628 +static int dpa_new_loop_id(void)
2629 +{
2630 + static int if_id;
2631 +
2632 + return if_id++;
2633 +}
2634 +#endif
2635 +
2636 +static int
2637 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
2638 +{
2639 + int err = 0, i, channel;
2640 + struct device *dev;
2641 + struct device_node *dpa_node;
2642 + struct dpa_bp *dpa_bp;
2643 + size_t count = 1;
2644 + struct net_device *net_dev = NULL;
2645 + struct dpa_priv_s *priv = NULL;
2646 + struct dpa_percpu_priv_s *percpu_priv;
2647 + struct fm_port_fqs port_fqs;
2648 + struct dpa_buffer_layout_s *buf_layout = NULL;
2649 + struct mac_device *mac_dev;
2650 +
2651 + dev = &_of_dev->dev;
2652 +
2653 + dpa_node = dev->of_node;
2654 +
2655 + if (!of_device_is_available(dpa_node))
2656 + return -ENODEV;
2657 +
2658 + /* Get the buffer pools assigned to this interface;
2659 + * run only once the default pool probing code
2660 + */
2661 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
2662 + dpa_priv_bp_probe(dev);
2663 + if (IS_ERR(dpa_bp))
2664 + return PTR_ERR(dpa_bp);
2665 +
2666 + /* Allocate this early, so we can store relevant information in
2667 + * the private area (needed by 1588 code in dpa_mac_probe)
2668 + */
2669 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
2670 + if (!net_dev) {
2671 + dev_err(dev, "alloc_etherdev_mq() failed\n");
2672 + goto alloc_etherdev_mq_failed;
2673 + }
2674 +
2675 + /* Do this here, so we can be verbose early */
2676 + SET_NETDEV_DEV(net_dev, dev);
2677 + dev_set_drvdata(dev, net_dev);
2678 +
2679 + priv = netdev_priv(net_dev);
2680 + priv->net_dev = net_dev;
2681 + strcpy(priv->if_type, "private");
2682 +
2683 + priv->msg_enable = netif_msg_init(debug, -1);
2684 +
2685 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2686 + priv->loop_id = dpa_new_loop_id();
2687 + priv->loop_to = -1; /* disabled by default */
2688 + dpa_loop_netdevs[priv->loop_id] = net_dev;
2689 +#endif
2690 +
2691 + mac_dev = dpa_mac_probe(_of_dev);
2692 + if (IS_ERR(mac_dev) || !mac_dev) {
2693 + err = PTR_ERR(mac_dev);
2694 + goto mac_probe_failed;
2695 + }
2696 +
2697 + /* We have physical ports, so we need to establish
2698 + * the buffer layout.
2699 + */
2700 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
2701 + GFP_KERNEL);
2702 + if (!buf_layout) {
2703 + dev_err(dev, "devm_kzalloc() failed\n");
2704 + goto alloc_failed;
2705 + }
2706 + dpa_set_buffers_layout(mac_dev, buf_layout);
2707 +
2708 + /* For private ports, need to compute the size of the default
2709 + * buffer pool, based on FMan port buffer layout;also update
2710 + * the maximum buffer size for private ports if necessary
2711 + */
2712 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
2713 +
2714 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
2715 + /* We only want to use jumbo frame optimization if we actually have
2716 + * L2 MAX FRM set for jumbo frames as well.
2717 + */
2718 +#ifndef CONFIG_PPC
2719 + if (likely(!dpaa_errata_a010022))
2720 +#endif
2721 + if(fm_get_max_frm() < 9600)
2722 + dev_warn(dev,
2723 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
2724 +#endif
2725 +
2726 + INIT_LIST_HEAD(&priv->dpa_fq_list);
2727 +
2728 + memset(&port_fqs, 0, sizeof(port_fqs));
2729 +
2730 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
2731 + if (!err)
2732 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
2733 + &port_fqs, true, TX);
2734 +
2735 + if (err < 0)
2736 + goto fq_probe_failed;
2737 +
2738 + /* bp init */
2739 +
2740 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
2741 +
2742 + if (err < 0)
2743 + goto bp_create_failed;
2744 +
2745 + priv->mac_dev = mac_dev;
2746 +
2747 + channel = dpa_get_channel();
2748 +
2749 + if (channel < 0) {
2750 + err = channel;
2751 + goto get_channel_failed;
2752 + }
2753 +
2754 + priv->channel = (uint16_t)channel;
2755 + dpaa_eth_add_channel(priv->channel);
2756 +
2757 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
2758 +
2759 + /* Create a congestion group for this netdev, with
2760 + * dynamically-allocated CGR ID.
2761 + * Must be executed after probing the MAC, but before
2762 + * assigning the egress FQs to the CGRs.
2763 + */
2764 + err = dpaa_eth_cgr_init(priv);
2765 + if (err < 0) {
2766 + dev_err(dev, "Error initializing CGR\n");
2767 + goto tx_cgr_init_failed;
2768 + }
2769 + err = dpaa_eth_priv_ingress_cgr_init(priv);
2770 + if (err < 0) {
2771 + dev_err(dev, "Error initializing ingress CGR\n");
2772 + goto rx_cgr_init_failed;
2773 + }
2774 +
2775 + /* Add the FQs to the interface, and make them active */
2776 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
2777 + if (err < 0)
2778 + goto fq_alloc_failed;
2779 +
2780 + priv->buf_layout = buf_layout;
2781 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
2782 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
2783 +
2784 + /* All real interfaces need their ports initialized */
2785 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
2786 + buf_layout, dev);
2787 +
2788 +#ifdef CONFIG_FMAN_PFC
2789 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
2790 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
2791 + mac_dev->port_dev[TX], i, i);
2792 + if (unlikely(err != 0)) {
2793 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
2794 + goto pfc_mapping_failed;
2795 + }
2796 + }
2797 +#endif
2798 +
2799 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
2800 +
2801 + if (priv->percpu_priv == NULL) {
2802 + dev_err(dev, "devm_alloc_percpu() failed\n");
2803 + err = -ENOMEM;
2804 + goto alloc_percpu_failed;
2805 + }
2806 + for_each_possible_cpu(i) {
2807 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
2808 + memset(percpu_priv, 0, sizeof(*percpu_priv));
2809 + }
2810 +
2811 + /* Initialize NAPI */
2812 + err = dpa_private_napi_add(net_dev);
2813 +
2814 + if (err < 0)
2815 + goto napi_add_failed;
2816 +
2817 + err = dpa_private_netdev_init(net_dev);
2818 +
2819 + if (err < 0)
2820 + goto netdev_init_failed;
2821 +
2822 + dpaa_eth_sysfs_init(&net_dev->dev);
2823 +
2824 +#ifdef CONFIG_PM
2825 + device_set_wakeup_capable(dev, true);
2826 +#endif
2827 +
2828 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
2829 +
2830 + return 0;
2831 +
2832 +netdev_init_failed:
2833 +napi_add_failed:
2834 + dpa_private_napi_del(net_dev);
2835 +alloc_percpu_failed:
2836 +#ifdef CONFIG_FMAN_PFC
2837 +pfc_mapping_failed:
2838 +#endif
2839 + dpa_fq_free(dev, &priv->dpa_fq_list);
2840 +fq_alloc_failed:
2841 + qman_delete_cgr_safe(&priv->ingress_cgr);
2842 + qman_release_cgrid(priv->ingress_cgr.cgrid);
2843 +rx_cgr_init_failed:
2844 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
2845 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
2846 +tx_cgr_init_failed:
2847 +get_channel_failed:
2848 + dpa_bp_free(priv);
2849 +bp_create_failed:
2850 +fq_probe_failed:
2851 +alloc_failed:
2852 +mac_probe_failed:
2853 + dev_set_drvdata(dev, NULL);
2854 + free_netdev(net_dev);
2855 +alloc_etherdev_mq_failed:
2856 + if (atomic_read(&dpa_bp->refs) == 0)
2857 + devm_kfree(dev, dpa_bp);
2858 +
2859 + return err;
2860 +}
2861 +
2862 +static const struct of_device_id dpa_match[] = {
2863 + {
2864 + .compatible = "fsl,dpa-ethernet"
2865 + },
2866 + {}
2867 +};
2868 +MODULE_DEVICE_TABLE(of, dpa_match);
2869 +
2870 +static struct platform_driver dpa_driver = {
2871 + .driver = {
2872 + .name = KBUILD_MODNAME,
2873 + .of_match_table = dpa_match,
2874 + .owner = THIS_MODULE,
2875 + .pm = DPAA_PM_OPS,
2876 + },
2877 + .probe = dpaa_eth_priv_probe,
2878 + .remove = dpa_remove
2879 +};
2880 +
2881 +#ifndef CONFIG_PPC
2882 +static bool __init __cold soc_has_errata_a010022(void)
2883 +{
2884 +#ifdef CONFIG_SOC_BUS
2885 + const struct soc_device_attribute soc_msi_matches[] = {
2886 + { .family = "QorIQ LS1043A",
2887 + .data = NULL },
2888 + { },
2889 + };
2890 +
2891 + if (soc_device_match(soc_msi_matches))
2892 + return true;
2893 +
2894 + return false;
2895 +#else
2896 + return true; /* cannot identify SoC */
2897 +#endif
2898 +}
2899 +#endif
2900 +
2901 +static int __init __cold dpa_load(void)
2902 +{
2903 + int _errno;
2904 +
2905 + pr_info(DPA_DESCRIPTION "\n");
2906 +
2907 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2908 + dpa_debugfs_module_init();
2909 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2910 +
2911 + /* initialise dpaa_eth mirror values */
2912 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
2913 + dpa_max_frm = fm_get_max_frm();
2914 + dpa_num_cpus = num_possible_cpus();
2915 +
2916 +#ifndef CONFIG_PPC
2917 + /* Detect if the current SoC requires the 4K alignment workaround */
2918 + dpaa_errata_a010022 = soc_has_errata_a010022();
2919 +#endif
2920 +
2921 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2922 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
2923 +#endif
2924 +
2925 + _errno = platform_driver_register(&dpa_driver);
2926 + if (unlikely(_errno < 0)) {
2927 + pr_err(KBUILD_MODNAME
2928 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
2929 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
2930 + }
2931 +
2932 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2933 + KBUILD_BASENAME".c", __func__);
2934 +
2935 + return _errno;
2936 +}
2937 +module_init(dpa_load);
2938 +
2939 +static void __exit __cold dpa_unload(void)
2940 +{
2941 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
2942 + KBUILD_BASENAME".c", __func__);
2943 +
2944 + platform_driver_unregister(&dpa_driver);
2945 +
2946 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
2947 + dpa_debugfs_module_exit();
2948 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
2949 +
2950 + /* Only one channel is used and needs to be relased after all
2951 + * interfaces are removed
2952 + */
2953 + dpa_release_channel();
2954 +
2955 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
2956 + KBUILD_BASENAME".c", __func__);
2957 +}
2958 +module_exit(dpa_unload);
2959 --- /dev/null
2960 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
2961 @@ -0,0 +1,687 @@
2962 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
2963 + *
2964 + * Redistribution and use in source and binary forms, with or without
2965 + * modification, are permitted provided that the following conditions are met:
2966 + * * Redistributions of source code must retain the above copyright
2967 + * notice, this list of conditions and the following disclaimer.
2968 + * * Redistributions in binary form must reproduce the above copyright
2969 + * notice, this list of conditions and the following disclaimer in the
2970 + * documentation and/or other materials provided with the distribution.
2971 + * * Neither the name of Freescale Semiconductor nor the
2972 + * names of its contributors may be used to endorse or promote products
2973 + * derived from this software without specific prior written permission.
2974 + *
2975 + *
2976 + * ALTERNATIVELY, this software may be distributed under the terms of the
2977 + * GNU General Public License ("GPL") as published by the Free Software
2978 + * Foundation, either version 2 of that License or (at your option) any
2979 + * later version.
2980 + *
2981 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
2982 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2983 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2984 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
2985 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2986 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2987 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2988 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2989 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2990 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2991 + */
2992 +
2993 +#ifndef __DPA_H
2994 +#define __DPA_H
2995 +
2996 +#include <linux/netdevice.h>
2997 +#include <linux/fsl_qman.h> /* struct qman_fq */
2998 +
2999 +#include "fm_ext.h"
3000 +#include "dpaa_eth_trace.h"
3001 +
3002 +extern int dpa_rx_extra_headroom;
3003 +extern int dpa_max_frm;
3004 +extern int dpa_num_cpus;
3005 +
3006 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
3007 +#define dpa_get_max_frm() dpa_max_frm
3008 +
3009 +#define dpa_get_max_mtu() \
3010 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
3011 +
3012 +#define __hot
3013 +
3014 +/* Simple enum of FQ types - used for array indexing */
3015 +enum port_type {RX, TX};
3016 +
3017 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
3018 +struct dpa_buffer_layout_s {
3019 + uint16_t priv_data_size;
3020 + bool parse_results;
3021 + bool time_stamp;
3022 + bool hash_results;
3023 + uint8_t manip_extra_space;
3024 + uint16_t data_align;
3025 +};
3026 +
3027 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3028 +#define DPA_BUG_ON(cond) BUG_ON(cond)
3029 +#else
3030 +#define DPA_BUG_ON(cond)
3031 +#endif
3032 +
3033 +#define DPA_TX_PRIV_DATA_SIZE 16
3034 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
3035 +#define DPA_TIME_STAMP_SIZE 8
3036 +#define DPA_HASH_RESULTS_SIZE 8
3037 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
3038 + dpa_get_rx_extra_headroom())
3039 +
3040 +#define FM_FD_STAT_RX_ERRORS \
3041 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
3042 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
3043 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
3044 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
3045 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
3046 +
3047 +#define FM_FD_STAT_TX_ERRORS \
3048 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
3049 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
3050 +
3051 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
3052 +/* The raw buffer size must be cacheline aligned.
3053 + * Normally we use 2K buffers.
3054 + */
3055 +#define DPA_BP_RAW_SIZE 2048
3056 +#else
3057 +/* For jumbo frame optimizations, use buffers large enough to accommodate
3058 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
3059 + * space to account for further alignments.
3060 + */
3061 +#define DPA_MAX_FRM_SIZE 9600
3062 +#ifdef CONFIG_PPC
3063 +#define DPA_BP_RAW_SIZE \
3064 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3065 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
3066 +#else /* CONFIG_PPC */
3067 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
3068 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
3069 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
3070 +#endif /* CONFIG_PPC */
3071 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
3072 +
3073 +/* This is what FMan is ever allowed to use.
3074 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
3075 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
3076 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
3077 + * half-page-aligned buffers (can we?), so we reserve some more space
3078 + * for start-of-buffer alignment.
3079 + */
3080 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
3081 + SMP_CACHE_BYTES)
3082 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
3083 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
3084 +
3085 +/* Maximum size of a buffer for which recycling is allowed.
3086 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
3087 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
3088 + * that skbs allocated by us will not fail to be recycled due to their size.
3089 + *
3090 + * For a requested size, the kernel allocator provides the next power of two
3091 + * sized block, which the stack will use as is, regardless of the actual size
3092 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
3093 + * supported frame size), set the recycling upper limit to 16K.
3094 + */
3095 +#define DPA_RECYCLE_MAX_SIZE 16384
3096 +
3097 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3098 +/*TODO: temporary for fman pcd testing */
3099 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
3100 +#endif
3101 +
3102 +#define DPAA_ETH_FQ_DELTA 0x10000
3103 +
3104 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
3105 + (((device_addr) & 0x1fffff) >> 6)
3106 +
3107 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
3108 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
3109 +
3110 +/* Largest value that the FQD's OAL field can hold.
3111 + * This is DPAA-1.x specific.
3112 + * TODO: This rather belongs in fsl_qman.h
3113 + */
3114 +#define FSL_QMAN_MAX_OAL 127
3115 +
3116 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
3117 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
3118 +
3119 +/* Default alignment for start of data in an Rx FD */
3120 +#define DPA_FD_DATA_ALIGNMENT 16
3121 +
3122 +/* Values for the L3R field of the FM Parse Results
3123 + */
3124 +/* L3 Type field: First IP Present IPv4 */
3125 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
3126 +/* L3 Type field: First IP Present IPv6 */
3127 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
3128 +
3129 +/* Values for the L4R field of the FM Parse Results
3130 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
3131 + */
3132 +/* L4 Type field: UDP */
3133 +#define FM_L4_PARSE_RESULT_UDP 0x40
3134 +/* L4 Type field: TCP */
3135 +#define FM_L4_PARSE_RESULT_TCP 0x20
3136 +/* FD status field indicating whether the FM Parser has attempted to validate
3137 + * the L4 csum of the frame.
3138 + * Note that having this bit set doesn't necessarily imply that the checksum
3139 + * is valid. One would have to check the parse results to find that out.
3140 + */
3141 +#define FM_FD_STAT_L4CV 0x00000004
3142 +
3143 +
3144 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
3145 +
3146 +/* Check if the parsed frame was found to be a TCP segment.
3147 + *
3148 + * @parse_result_ptr must be of type (fm_prs_result_t *).
3149 + */
3150 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
3151 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
3152 +
3153 +/* number of Tx queues to FMan */
3154 +#ifdef CONFIG_FMAN_PFC
3155 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
3156 +#else
3157 +#define DPAA_ETH_TX_QUEUES NR_CPUS
3158 +#endif
3159 +
3160 +#define DPAA_ETH_RX_QUEUES 128
3161 +
3162 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
3163 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
3164 + * was allocated by ourselves, respectively by the stack. In the former case,
3165 + * we could store the skb at negative offset; in the latter case, we can't,
3166 + * so we'll use 0 as offset.
3167 + *
3168 + * NB: @off is an offset from a (struct sk_buff **) pointer!
3169 + */
3170 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
3171 +{ \
3172 + skbh = (struct sk_buff **)addr; \
3173 + *(skbh + (off)) = skb; \
3174 +}
3175 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
3176 +{ \
3177 + skbh = (struct sk_buff **)addr; \
3178 + skb = *(skbh + (off)); \
3179 +}
3180 +
3181 +#ifdef CONFIG_PM
3182 +/* Magic Packet wakeup */
3183 +#define DPAA_WOL_MAGIC 0x00000001
3184 +#endif
3185 +
3186 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3187 +struct pcd_range {
3188 + uint32_t base;
3189 + uint32_t count;
3190 +};
3191 +#endif
3192 +
3193 +/* More detailed FQ types - used for fine-grained WQ assignments */
3194 +enum dpa_fq_type {
3195 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
3196 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
3197 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
3198 + FQ_TYPE_TX, /* "Real" Tx FQs */
3199 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
3200 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
3201 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
3202 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
3203 +};
3204 +
3205 +struct dpa_fq {
3206 + struct qman_fq fq_base;
3207 + struct list_head list;
3208 + struct net_device *net_dev;
3209 + bool init;
3210 + uint32_t fqid;
3211 + uint32_t flags;
3212 + uint16_t channel;
3213 + uint8_t wq;
3214 + enum dpa_fq_type fq_type;
3215 +};
3216 +
3217 +struct dpa_fq_cbs_t {
3218 + struct qman_fq rx_defq;
3219 + struct qman_fq tx_defq;
3220 + struct qman_fq rx_errq;
3221 + struct qman_fq tx_errq;
3222 + struct qman_fq egress_ern;
3223 +};
3224 +
3225 +struct fqid_cell {
3226 + uint32_t start;
3227 + uint32_t count;
3228 +};
3229 +
3230 +struct dpa_bp {
3231 + struct bman_pool *pool;
3232 + uint8_t bpid;
3233 + struct device *dev;
3234 + union {
3235 + /* The buffer pools used for the private ports are initialized
3236 + * with target_count buffers for each CPU; at runtime the
3237 + * number of buffers per CPU is constantly brought back to this
3238 + * level
3239 + */
3240 + int target_count;
3241 + /* The configured value for the number of buffers in the pool,
3242 + * used for shared port buffer pools
3243 + */
3244 + int config_count;
3245 + };
3246 + size_t size;
3247 + bool seed_pool;
3248 + /* physical address of the contiguous memory used by the pool to store
3249 + * the buffers
3250 + */
3251 + dma_addr_t paddr;
3252 + /* virtual address of the contiguous memory used by the pool to store
3253 + * the buffers
3254 + */
3255 + void __iomem *vaddr;
3256 + /* current number of buffers in the bpool alloted to this CPU */
3257 + int __percpu *percpu_count;
3258 + atomic_t refs;
3259 + /* some bpools need to be seeded before use by this cb */
3260 + int (*seed_cb)(struct dpa_bp *);
3261 + /* some bpools need to be emptied before freeing; this cb is used
3262 + * for freeing of individual buffers taken from the pool
3263 + */
3264 + void (*free_buf_cb)(void *addr);
3265 +};
3266 +
3267 +struct dpa_rx_errors {
3268 + u64 dme; /* DMA Error */
3269 + u64 fpe; /* Frame Physical Error */
3270 + u64 fse; /* Frame Size Error */
3271 + u64 phe; /* Header Error */
3272 + u64 cse; /* Checksum Validation Error */
3273 +};
3274 +
3275 +/* Counters for QMan ERN frames - one counter per rejection code */
3276 +struct dpa_ern_cnt {
3277 + u64 cg_tdrop; /* Congestion group taildrop */
3278 + u64 wred; /* WRED congestion */
3279 + u64 err_cond; /* Error condition */
3280 + u64 early_window; /* Order restoration, frame too early */
3281 + u64 late_window; /* Order restoration, frame too late */
3282 + u64 fq_tdrop; /* FQ taildrop */
3283 + u64 fq_retired; /* FQ is retired */
3284 + u64 orp_zero; /* ORP disabled */
3285 +};
3286 +
3287 +struct dpa_napi_portal {
3288 + struct napi_struct napi;
3289 + struct qman_portal *p;
3290 +};
3291 +
3292 +struct dpa_percpu_priv_s {
3293 + struct net_device *net_dev;
3294 + struct dpa_napi_portal *np;
3295 + u64 in_interrupt;
3296 + u64 tx_returned;
3297 + u64 tx_confirm;
3298 + /* fragmented (non-linear) skbuffs received from the stack */
3299 + u64 tx_frag_skbuffs;
3300 + /* number of S/G frames received */
3301 + u64 rx_sg;
3302 +
3303 + struct rtnl_link_stats64 stats;
3304 + struct dpa_rx_errors rx_errors;
3305 + struct dpa_ern_cnt ern_cnt;
3306 +};
3307 +
3308 +struct dpa_priv_s {
3309 + struct dpa_percpu_priv_s __percpu *percpu_priv;
3310 + struct dpa_bp *dpa_bp;
3311 + /* Store here the needed Tx headroom for convenience and speed
3312 + * (even though it can be computed based on the fields of buf_layout)
3313 + */
3314 + uint16_t tx_headroom;
3315 + struct net_device *net_dev;
3316 + struct mac_device *mac_dev;
3317 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
3318 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
3319 +
3320 + size_t bp_count;
3321 +
3322 + uint16_t channel; /* "fsl,qman-channel-id" */
3323 + struct list_head dpa_fq_list;
3324 +
3325 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3326 + struct dentry *debugfs_loop_file;
3327 +#endif
3328 +
3329 + uint32_t msg_enable; /* net_device message level */
3330 +#ifdef CONFIG_FSL_DPAA_1588
3331 + struct dpa_ptp_tsu *tsu;
3332 +#endif
3333 +
3334 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
3335 +/* TODO: this is temporary until pcd support is implemented in dpaa */
3336 + int priv_pcd_num_ranges;
3337 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
3338 +#endif
3339 +
3340 + struct {
3341 + /**
3342 + * All egress queues to a given net device belong to one
3343 + * (and the same) congestion group.
3344 + */
3345 + struct qman_cgr cgr;
3346 + /* If congested, when it began. Used for performance stats. */
3347 + u32 congestion_start_jiffies;
3348 + /* Number of jiffies the Tx port was congested. */
3349 + u32 congested_jiffies;
3350 + /**
3351 + * Counter for the number of times the CGR
3352 + * entered congestion state
3353 + */
3354 + u32 cgr_congested_count;
3355 + } cgr_data;
3356 + /* Use a per-port CGR for ingress traffic. */
3357 + bool use_ingress_cgr;
3358 + struct qman_cgr ingress_cgr;
3359 +
3360 +#ifdef CONFIG_FSL_DPAA_TS
3361 + bool ts_tx_en; /* Tx timestamping enabled */
3362 + bool ts_rx_en; /* Rx timestamping enabled */
3363 +#endif /* CONFIG_FSL_DPAA_TS */
3364 +
3365 + struct dpa_buffer_layout_s *buf_layout;
3366 + uint16_t rx_headroom;
3367 + char if_type[30];
3368 +
3369 + void *peer;
3370 +#ifdef CONFIG_PM
3371 + u32 wol;
3372 +#endif
3373 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3374 + int loop_id;
3375 + int loop_to;
3376 +#endif
3377 +#ifdef CONFIG_FSL_DPAA_CEETM
3378 + bool ceetm_en; /* CEETM QoS enabled */
3379 +#endif
3380 +};
3381 +
3382 +struct fm_port_fqs {
3383 + struct dpa_fq *tx_defq;
3384 + struct dpa_fq *tx_errq;
3385 + struct dpa_fq *rx_defq;
3386 + struct dpa_fq *rx_errq;
3387 +};
3388 +
3389 +
3390 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3391 +extern struct net_device *dpa_loop_netdevs[20];
3392 +#endif
3393 +
3394 +/* functions with different implementation for SG and non-SG: */
3395 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
3396 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
3397 +void __hot _dpa_rx(struct net_device *net_dev,
3398 + struct qman_portal *portal,
3399 + const struct dpa_priv_s *priv,
3400 + struct dpa_percpu_priv_s *percpu_priv,
3401 + const struct qm_fd *fd,
3402 + u32 fqid,
3403 + int *count_ptr);
3404 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
3405 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
3406 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
3407 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
3408 + const struct qm_fd *fd);
3409 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
3410 + const struct qm_fd *fd,
3411 + struct sk_buff *skb,
3412 + int *use_gro);
3413 +#ifndef CONFIG_FSL_DPAA_TS
3414 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
3415 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
3416 + uint32_t min_size,
3417 + uint16_t min_offset,
3418 + unsigned char **new_buf_start);
3419 +#endif
3420 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
3421 + struct sk_buff *skb, struct qm_fd *fd,
3422 + int *count_ptr, int *offset);
3423 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
3424 + struct sk_buff *skb, struct qm_fd *fd);
3425 +int __cold __attribute__((nonnull))
3426 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
3427 +
3428 +/* Turn on HW checksum computation for this outgoing frame.
3429 + * If the current protocol is not something we support in this regard
3430 + * (or if the stack has already computed the SW checksum), we do nothing.
3431 + *
3432 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
3433 + * otherwise.
3434 + *
3435 + * Note that this function may modify the fd->cmd field and the skb data buffer
3436 + * (the Parse Results area).
3437 + */
3438 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
3439 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
3440 +
3441 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
3442 + struct qman_portal *portal)
3443 +{
3444 + /* In case of threaded ISR for RT enable kernel,
3445 + * in_irq() does not return appropriate value, so use
3446 + * in_serving_softirq to distinguish softirq or irq context.
3447 + */
3448 + if (unlikely(in_irq() || !in_serving_softirq())) {
3449 + /* Disable QMan IRQ and invoke NAPI */
3450 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
3451 + if (likely(!ret)) {
3452 + const struct qman_portal_config *pc =
3453 + qman_p_get_portal_config(portal);
3454 + struct dpa_napi_portal *np =
3455 + &percpu_priv->np[pc->index];
3456 +
3457 + np->p = portal;
3458 + napi_schedule(&np->napi);
3459 + percpu_priv->in_interrupt++;
3460 + return 1;
3461 + }
3462 + }
3463 + return 0;
3464 +}
3465 +
3466 +static inline ssize_t __const __must_check __attribute__((nonnull))
3467 +dpa_fd_length(const struct qm_fd *fd)
3468 +{
3469 + return fd->length20;
3470 +}
3471 +
3472 +static inline ssize_t __const __must_check __attribute__((nonnull))
3473 +dpa_fd_offset(const struct qm_fd *fd)
3474 +{
3475 + return fd->offset;
3476 +}
3477 +
3478 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
3479 +{
3480 + uint16_t headroom;
3481 + /* The frame headroom must accommodate:
3482 + * - the driver private data area
3483 + * - parse results, hash results, timestamp if selected
3484 + * - manip extra space
3485 + * If either hash results or time stamp are selected, both will
3486 + * be copied to/from the frame headroom, as TS is located between PR and
3487 + * HR in the IC and IC copy size has a granularity of 16bytes
3488 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
3489 + *
3490 + * Also make sure the headroom is a multiple of data_align bytes
3491 + */
3492 + headroom = (uint16_t)(bl->priv_data_size +
3493 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
3494 + (bl->hash_results || bl->time_stamp ?
3495 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
3496 + bl->manip_extra_space);
3497 +
3498 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
3499 +}
3500 +
3501 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
3502 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
3503 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
3504 +
3505 +void dpaa_eth_sysfs_remove(struct device *dev);
3506 +void dpaa_eth_sysfs_init(struct device *dev);
3507 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
3508 +
3509 +void dpa_private_napi_del(struct net_device *net_dev);
3510 +
3511 +/* Equivalent to a memset(0), but works faster */
3512 +static inline void clear_fd(struct qm_fd *fd)
3513 +{
3514 + fd->opaque_addr = 0;
3515 + fd->opaque = 0;
3516 + fd->cmd = 0;
3517 +}
3518 +
3519 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
3520 + struct qman_fq *tx_fq)
3521 +{
3522 + int i;
3523 +
3524 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
3525 + if (priv->egress_fqs[i] == tx_fq)
3526 + return i;
3527 +
3528 + return -EINVAL;
3529 +}
3530 +
3531 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
3532 + struct rtnl_link_stats64 *percpu_stats,
3533 + struct qm_fd *fd, struct qman_fq *egress_fq,
3534 + struct qman_fq *conf_fq)
3535 +{
3536 + int err, i;
3537 +
3538 + if (fd->bpid == 0xff)
3539 + fd->cmd |= qman_fq_fqid(conf_fq);
3540 +
3541 + /* Trace this Tx fd */
3542 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
3543 +
3544 + for (i = 0; i < 100000; i++) {
3545 + err = qman_enqueue(egress_fq, fd, 0);
3546 + if (err != -EBUSY)
3547 + break;
3548 + }
3549 +
3550 + if (unlikely(err < 0)) {
3551 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
3552 + percpu_stats->tx_errors++;
3553 + percpu_stats->tx_fifo_errors++;
3554 + return err;
3555 + }
3556 +
3557 + percpu_stats->tx_packets++;
3558 + percpu_stats->tx_bytes += dpa_fd_length(fd);
3559 +
3560 + return 0;
3561 +}
3562 +
3563 +/* Use multiple WQs for FQ assignment:
3564 + * - Tx Confirmation queues go to WQ1.
3565 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
3566 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
3567 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
3568 + * to be scheduled, in case there are many more FQs in WQ3).
3569 + * This ensures that Tx-confirmed buffers are timely released. In particular,
3570 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
3571 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
3572 + * dequeue scheduling is round-robin.
3573 + */
3574 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
3575 +{
3576 + switch (fq->fq_type) {
3577 + case FQ_TYPE_TX_CONFIRM:
3578 + case FQ_TYPE_TX_CONF_MQ:
3579 + fq->wq = 1;
3580 + break;
3581 + case FQ_TYPE_RX_DEFAULT:
3582 + case FQ_TYPE_TX:
3583 + fq->wq = 3;
3584 + break;
3585 + case FQ_TYPE_RX_ERROR:
3586 + case FQ_TYPE_TX_ERROR:
3587 + case FQ_TYPE_RX_PCD_HI_PRIO:
3588 + fq->wq = 2;
3589 + break;
3590 + case FQ_TYPE_RX_PCD:
3591 + fq->wq = 5;
3592 + break;
3593 + default:
3594 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
3595 + fq->fq_type, fq->fqid);
3596 + }
3597 +}
3598 +
3599 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
3600 +/* Use in lieu of skb_get_queue_mapping() */
3601 +#ifdef CONFIG_FMAN_PFC
3602 +#define dpa_get_queue_mapping(skb) \
3603 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
3604 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
3605 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
3606 + dpa_num_cpus + smp_processor_id()));
3607 +
3608 +#else
3609 +#define dpa_get_queue_mapping(skb) \
3610 + raw_smp_processor_id()
3611 +#endif
3612 +#else
3613 +/* Use the queue selected by XPS */
3614 +#define dpa_get_queue_mapping(skb) \
3615 + skb_get_queue_mapping(skb)
3616 +#endif
3617 +
3618 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
3619 +struct ptp_priv_s {
3620 + struct device_node *node;
3621 + struct platform_device *of_dev;
3622 + struct ptp_clock *clock;
3623 + struct mac_device *mac_dev;
3624 +};
3625 +extern struct ptp_priv_s ptp_priv;
3626 +#endif
3627 +
3628 +static inline void _dpa_bp_free_pf(void *addr)
3629 +{
3630 + put_page(virt_to_head_page(addr));
3631 +}
3632 +
3633 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
3634 + * manifests itself at high traffic rates when frames cross 4K memory
3635 + * boundaries or when they are not aligned to 16 bytes; For the moment, we
3636 + * use a SW workaround to avoid frames larger than 4K or that exceed 4K
3637 + * alignments and to realign the frames to 16 bytes.
3638 + */
3639 +
3640 +#ifndef CONFIG_PPC
3641 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
3642 +#define NONREC_MARK 0x01
3643 +#define HAS_DMA_ISSUE(start, size) \
3644 + (((uintptr_t)(start) + (size)) > \
3645 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
3646 +#endif /* !CONFIG_PPC */
3647 +
3648 +#endif /* __DPA_H */
3649 --- /dev/null
3650 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
3651 @@ -0,0 +1,205 @@
3652 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3653 + *
3654 + * Redistribution and use in source and binary forms, with or without
3655 + * modification, are permitted provided that the following conditions are met:
3656 + * * Redistributions of source code must retain the above copyright
3657 + * notice, this list of conditions and the following disclaimer.
3658 + * * Redistributions in binary form must reproduce the above copyright
3659 + * notice, this list of conditions and the following disclaimer in the
3660 + * documentation and/or other materials provided with the distribution.
3661 + * * Neither the name of Freescale Semiconductor nor the
3662 + * names of its contributors may be used to endorse or promote products
3663 + * derived from this software without specific prior written permission.
3664 + *
3665 + *
3666 + * ALTERNATIVELY, this software may be distributed under the terms of the
3667 + * GNU General Public License ("GPL") as published by the Free Software
3668 + * Foundation, either version 2 of that License or (at your option) any
3669 + * later version.
3670 + *
3671 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3672 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3673 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3674 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3675 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3676 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3677 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3678 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3679 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3680 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3681 + */
3682 +
3683 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3684 +#define pr_fmt(fmt) \
3685 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3686 + KBUILD_BASENAME".c", __LINE__, __func__
3687 +#else
3688 +#define pr_fmt(fmt) \
3689 + KBUILD_MODNAME ": " fmt
3690 +#endif
3691 +
3692 +#include <linux/init.h>
3693 +#include <linux/module.h>
3694 +#include <linux/io.h>
3695 +#include <linux/of_platform.h>
3696 +#include <linux/of_net.h>
3697 +#include <linux/etherdevice.h>
3698 +#include <linux/kthread.h>
3699 +#include <linux/percpu.h>
3700 +#include <linux/highmem.h>
3701 +#include <linux/sort.h>
3702 +#include <linux/fsl_qman.h>
3703 +#include "dpaa_eth.h"
3704 +#include "dpaa_eth_common.h"
3705 +#include "dpaa_eth_base.h"
3706 +
3707 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
3708 +
3709 +MODULE_LICENSE("Dual BSD/GPL");
3710 +
3711 +uint8_t advanced_debug = -1;
3712 +module_param(advanced_debug, byte, S_IRUGO);
3713 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
3714 +EXPORT_SYMBOL(advanced_debug);
3715 +
3716 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
3717 +{
3718 + return ((struct dpa_bp *)dpa_bp0)->size -
3719 + ((struct dpa_bp *)dpa_bp1)->size;
3720 +}
3721 +
3722 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3723 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
3724 +{
3725 + int i, lenp, na, ns, err;
3726 + struct device *dev;
3727 + struct device_node *dev_node;
3728 + const __be32 *bpool_cfg;
3729 + struct dpa_bp *dpa_bp;
3730 + u32 bpid;
3731 +
3732 + dev = &_of_dev->dev;
3733 +
3734 + *count = of_count_phandle_with_args(dev->of_node,
3735 + "fsl,bman-buffer-pools", NULL);
3736 + if (*count < 1) {
3737 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
3738 + return ERR_PTR(-EINVAL);
3739 + }
3740 +
3741 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
3742 + if (dpa_bp == NULL) {
3743 + dev_err(dev, "devm_kzalloc() failed\n");
3744 + return ERR_PTR(-ENOMEM);
3745 + }
3746 +
3747 + dev_node = of_find_node_by_path("/");
3748 + if (unlikely(dev_node == NULL)) {
3749 + dev_err(dev, "of_find_node_by_path(/) failed\n");
3750 + return ERR_PTR(-EINVAL);
3751 + }
3752 +
3753 + na = of_n_addr_cells(dev_node);
3754 + ns = of_n_size_cells(dev_node);
3755 +
3756 + for (i = 0; i < *count; i++) {
3757 + of_node_put(dev_node);
3758 +
3759 + dev_node = of_parse_phandle(dev->of_node,
3760 + "fsl,bman-buffer-pools", i);
3761 + if (dev_node == NULL) {
3762 + dev_err(dev, "of_find_node_by_phandle() failed\n");
3763 + return ERR_PTR(-EFAULT);
3764 + }
3765 +
3766 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
3767 + dev_err(dev,
3768 + "!of_device_is_compatible(%s, fsl,bpool)\n",
3769 + dev_node->full_name);
3770 + dpa_bp = ERR_PTR(-EINVAL);
3771 + goto _return_of_node_put;
3772 + }
3773 +
3774 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
3775 + if (err) {
3776 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
3777 + dpa_bp = ERR_PTR(-EINVAL);
3778 + goto _return_of_node_put;
3779 + }
3780 + dpa_bp[i].bpid = (uint8_t)bpid;
3781 +
3782 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
3783 + &lenp);
3784 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
3785 + const uint32_t *seed_pool;
3786 +
3787 + dpa_bp[i].config_count =
3788 + (int)of_read_number(bpool_cfg, ns);
3789 + dpa_bp[i].size =
3790 + (size_t)of_read_number(bpool_cfg + ns, ns);
3791 + dpa_bp[i].paddr =
3792 + of_read_number(bpool_cfg + 2 * ns, na);
3793 +
3794 + seed_pool = of_get_property(dev_node,
3795 + "fsl,bpool-ethernet-seeds", &lenp);
3796 + dpa_bp[i].seed_pool = !!seed_pool;
3797 +
3798 + } else {
3799 + dev_err(dev,
3800 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
3801 + dev_node->full_name);
3802 + dpa_bp = ERR_PTR(-EINVAL);
3803 + goto _return_of_node_put;
3804 + }
3805 + }
3806 +
3807 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
3808 +
3809 + return dpa_bp;
3810 +
3811 +_return_of_node_put:
3812 + if (dev_node)
3813 + of_node_put(dev_node);
3814 +
3815 + return dpa_bp;
3816 +}
3817 +EXPORT_SYMBOL(dpa_bp_probe);
3818 +
3819 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3820 + size_t count)
3821 +{
3822 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3823 + int i;
3824 +
3825 + priv->dpa_bp = dpa_bp;
3826 + priv->bp_count = count;
3827 +
3828 + for (i = 0; i < count; i++) {
3829 + int err;
3830 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
3831 + if (err < 0) {
3832 + dpa_bp_free(priv);
3833 + priv->dpa_bp = NULL;
3834 + return err;
3835 + }
3836 + }
3837 +
3838 + return 0;
3839 +}
3840 +EXPORT_SYMBOL(dpa_bp_create);
3841 +
3842 +static int __init __cold dpa_advanced_load(void)
3843 +{
3844 + pr_info(DPA_DESCRIPTION "\n");
3845 +
3846 + return 0;
3847 +}
3848 +module_init(dpa_advanced_load);
3849 +
3850 +static void __exit __cold dpa_advanced_unload(void)
3851 +{
3852 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
3853 + KBUILD_BASENAME".c", __func__);
3854 +
3855 +}
3856 +module_exit(dpa_advanced_unload);
3857 --- /dev/null
3858 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
3859 @@ -0,0 +1,49 @@
3860 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
3861 + *
3862 + * Redistribution and use in source and binary forms, with or without
3863 + * modification, are permitted provided that the following conditions are met:
3864 + * * Redistributions of source code must retain the above copyright
3865 + * notice, this list of conditions and the following disclaimer.
3866 + * * Redistributions in binary form must reproduce the above copyright
3867 + * notice, this list of conditions and the following disclaimer in the
3868 + * documentation and/or other materials provided with the distribution.
3869 + * * Neither the name of Freescale Semiconductor nor the
3870 + * names of its contributors may be used to endorse or promote products
3871 + * derived from this software without specific prior written permission.
3872 + *
3873 + *
3874 + * ALTERNATIVELY, this software may be distributed under the terms of the
3875 + * GNU General Public License ("GPL") as published by the Free Software
3876 + * Foundation, either version 2 of that License or (at your option) any
3877 + * later version.
3878 + *
3879 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3880 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3881 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3882 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3883 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3884 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3885 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3886 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3887 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3888 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3889 + */
3890 +
3891 +#ifndef __DPAA_ETH_BASE_H
3892 +#define __DPAA_ETH_BASE_H
3893 +
3894 +#include <linux/etherdevice.h> /* struct net_device */
3895 +#include <linux/fsl_bman.h> /* struct bm_buffer */
3896 +#include <linux/of_platform.h> /* struct platform_device */
3897 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
3898 +
3899 +extern uint8_t advanced_debug;
3900 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
3901 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
3902 +
3903 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
3904 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
3905 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
3906 + size_t count);
3907 +
3908 +#endif /* __DPAA_ETH_BASE_H */
3909 --- /dev/null
3910 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
3911 @@ -0,0 +1,2115 @@
3912 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
3913 + *
3914 + * Redistribution and use in source and binary forms, with or without
3915 + * modification, are permitted provided that the following conditions are met:
3916 + * * Redistributions of source code must retain the above copyright
3917 + * notice, this list of conditions and the following disclaimer.
3918 + * * Redistributions in binary form must reproduce the above copyright
3919 + * notice, this list of conditions and the following disclaimer in the
3920 + * documentation and/or other materials provided with the distribution.
3921 + * * Neither the name of Freescale Semiconductor nor the
3922 + * names of its contributors may be used to endorse or promote products
3923 + * derived from this software without specific prior written permission.
3924 + *
3925 + *
3926 + * ALTERNATIVELY, this software may be distributed under the terms of the
3927 + * GNU General Public License ("GPL") as published by the Free Software
3928 + * Foundation, either version 2 of that License or (at your option) any
3929 + * later version.
3930 + *
3931 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3932 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3933 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3934 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3935 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3936 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3937 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3938 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3939 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3940 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3941 + */
3942 +
3943 +#include <linux/init.h>
3944 +#include "dpaa_eth_ceetm.h"
3945 +
3946 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
3947 +
3948 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
3949 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
3950 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
3951 +};
3952 +
3953 +struct Qdisc_ops ceetm_qdisc_ops;
3954 +
3955 +/* Obtain the DCP and the SP ids from the FMan port */
3956 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
3957 + unsigned int *sp_id)
3958 +{
3959 + uint32_t channel;
3960 + t_LnxWrpFmPortDev *port_dev;
3961 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
3962 + struct mac_device *mac_dev = dpa_priv->mac_dev;
3963 +
3964 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
3965 + channel = port_dev->txCh;
3966 +
3967 + *sp_id = channel & CHANNEL_SP_MASK;
3968 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
3969 +
3970 + if (channel < DCP0_MAX_CHANNEL) {
3971 + *dcp_id = qm_dc_portal_fman0;
3972 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
3973 + } else {
3974 + *dcp_id = qm_dc_portal_fman1;
3975 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
3976 + }
3977 +}
3978 +
3979 +/* Wait for the DPAA Eth driver WQ TX FQs to empty */
3980 +static void dpaa_drain_fqs(struct net_device *dev)
3981 +{
3982 + const struct dpa_priv_s *priv = netdev_priv(dev);
3983 + struct qm_mcr_queryfq_np np;
3984 + struct qman_fq *fq;
3985 + int ret, i;
3986 +
3987 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i ++) {
3988 + fq = priv->egress_fqs[i];
3989 + while (true) {
3990 + ret = qman_query_fq_np(fq, &np);
3991 + if (unlikely(ret)) {
3992 + pr_err(KBUILD_BASENAME
3993 + " : %s : unable to query FQ %x: %d\n",
3994 + __func__, fq->fqid, ret);
3995 + break;
3996 + }
3997 +
3998 + if (np.frm_cnt == 0)
3999 + break;
4000 + }
4001 + }
4002 +}
4003 +
4004 +/* Wait for the DPAA CEETM TX CQs to empty */
4005 +static void ceetm_drain_class(struct ceetm_class *cl)
4006 +{
4007 + struct qm_mcr_ceetm_cq_query cq_query;
4008 + struct qm_ceetm_cq *cq;
4009 + unsigned int idx;
4010 + int ret;
4011 +
4012 + if (!cl)
4013 + return;
4014 +
4015 + switch (cl->type) {
4016 + case CEETM_ROOT:
4017 + /* The ROOT classes aren't directly linked to CEETM CQs */
4018 + return;
4019 + case CEETM_PRIO:
4020 + cq = (struct qm_ceetm_cq*)cl->prio.cq;
4021 + break;
4022 + case CEETM_WBFS:
4023 + cq = (struct qm_ceetm_cq*)cl->wbfs.cq;
4024 + break;
4025 + }
4026 +
4027 + if (!cq || !cl->ch)
4028 + return;
4029 +
4030 + /* Build the query CQID by merging the channel and the CQ IDs */
4031 + idx = (cq->parent->idx << 4) | cq->idx;
4032 +
4033 + while (true) {
4034 + ret = qman_ceetm_query_cq(idx,
4035 + cl->ch->dcp_idx,
4036 + &cq_query);
4037 + if (unlikely(ret)) {
4038 + pr_err(KBUILD_BASENAME
4039 + " : %s : unable to query CQ %x: %d\n",
4040 + __func__, idx, ret);
4041 + break;
4042 + }
4043 +
4044 + if (cq_query.frm_cnt == 0)
4045 + break;
4046 + }
4047 +}
4048 +
4049 +/* Enqueue Rejection Notification callback */
4050 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
4051 + const struct qm_mr_entry *msg)
4052 +{
4053 + struct dpa_percpu_priv_s *dpa_percpu_priv;
4054 + struct ceetm_class_stats *cstats = NULL;
4055 + const struct dpa_priv_s *dpa_priv;
4056 + struct qm_fd fd = msg->ern.fd;
4057 + struct net_device *net_dev;
4058 + struct ceetm_fq *ceetm_fq;
4059 + struct ceetm_class *cls;
4060 + struct sk_buff *skb;
4061 +
4062 + ceetm_fq = container_of(fq, struct ceetm_fq, fq);
4063 + net_dev = ceetm_fq->net_dev;
4064 + dpa_priv = netdev_priv(net_dev);
4065 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
4066 +
4067 + /* Increment DPA counters */
4068 + dpa_percpu_priv->stats.tx_dropped++;
4069 + dpa_percpu_priv->stats.tx_fifo_errors++;
4070 + count_ern(dpa_percpu_priv, msg);
4071 +
4072 + /* Increment CEETM counters */
4073 + cls = ceetm_fq->ceetm_cls;
4074 + switch (cls->type) {
4075 + case CEETM_PRIO:
4076 + cstats = this_cpu_ptr(cls->prio.cstats);
4077 + break;
4078 + case CEETM_WBFS:
4079 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4080 + break;
4081 + }
4082 +
4083 + if (cstats)
4084 + cstats->ern_drop_count++;
4085 +
4086 + /* Release the buffers that were supposed to be recycled. */
4087 + if (fd.bpid != 0xff) {
4088 + dpa_fd_release(net_dev, &fd);
4089 + return;
4090 + }
4091 +
4092 + /* Release the frames that were supposed to return on the
4093 + * confirmation path.
4094 + */
4095 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
4096 + dev_kfree_skb_any(skb);
4097 +}
4098 +
4099 +/* Congestion State Change Notification callback */
4100 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
4101 +{
4102 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
4103 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
4104 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
4105 + struct ceetm_class_stats *cstats = NULL;
4106 +
4107 + switch (cls->type) {
4108 + case CEETM_PRIO:
4109 + cstats = this_cpu_ptr(cls->prio.cstats);
4110 + break;
4111 + case CEETM_WBFS:
4112 + cstats = this_cpu_ptr(cls->wbfs.cstats);
4113 + break;
4114 + }
4115 +
4116 + ceetm_fq->congested = congested;
4117 +
4118 + if (congested) {
4119 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
4120 + dpa_priv->cgr_data.cgr_congested_count++;
4121 + if (cstats)
4122 + cstats->congested_count++;
4123 + } else {
4124 + dpa_priv->cgr_data.congested_jiffies +=
4125 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
4126 + }
4127 +}
4128 +
4129 +/* Allocate a ceetm fq */
4130 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
4131 + struct ceetm_class *cls)
4132 +{
4133 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
4134 + if (!*fq)
4135 + return -ENOMEM;
4136 +
4137 + (*fq)->net_dev = dev;
4138 + (*fq)->ceetm_cls = cls;
4139 + (*fq)->congested = 0;
4140 + return 0;
4141 +}
4142 +
4143 +/* Configure a ceetm Class Congestion Group */
4144 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
4145 + struct qm_ceetm_channel *channel, unsigned int id,
4146 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
4147 +{
4148 + int err;
4149 + u32 cs_th;
4150 + u16 ccg_mask;
4151 + struct qm_ceetm_ccg_params ccg_params;
4152 +
4153 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
4154 + if (err)
4155 + return err;
4156 +
4157 + /* Configure the count mode (frames/bytes), enable congestion state
4158 + * notifications, configure the congestion entry and exit thresholds,
4159 + * enable tail-drop, configure the tail-drop mode, and set the
4160 + * overhead accounting limit
4161 + */
4162 + ccg_mask = QM_CCGR_WE_MODE |
4163 + QM_CCGR_WE_CSCN_EN |
4164 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
4165 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
4166 + QM_CCGR_WE_OAL;
4167 +
4168 + ccg_params.mode = 0; /* count bytes */
4169 + ccg_params.cscn_en = 1; /* generate notifications */
4170 + ccg_params.td_en = 1; /* enable tail-drop */
4171 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
4172 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
4173 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
4174 +
4175 + /* Set the congestion state thresholds according to the link speed */
4176 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
4177 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G;
4178 + else
4179 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G;
4180 +
4181 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
4182 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
4183 + cs_th * CEETM_CCGR_RATIO, 1);
4184 +
4185 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
4186 + if (err)
4187 + return err;
4188 +
4189 + return 0;
4190 +}
4191 +
4192 +/* Configure a ceetm Logical Frame Queue */
4193 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
4194 + struct qm_ceetm_lfq **lfq)
4195 +{
4196 + int err;
4197 + u64 context_a;
4198 + u32 context_b;
4199 +
4200 + err = qman_ceetm_lfq_claim(lfq, cq);
4201 + if (err)
4202 + return err;
4203 +
4204 + /* Get the former contexts in order to preserve context B */
4205 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
4206 + if (err)
4207 + return err;
4208 +
4209 + context_a = CEETM_CONTEXT_A;
4210 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
4211 + if (err)
4212 + return err;
4213 +
4214 + (*lfq)->ern = ceetm_ern;
4215 +
4216 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
4217 + if (err)
4218 + return err;
4219 +
4220 + return 0;
4221 +}
4222 +
4223 +/* Configure a prio ceetm class */
4224 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
4225 + struct net_device *dev,
4226 + unsigned int id)
4227 +{
4228 + int err;
4229 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4230 +
4231 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
4232 + if (err)
4233 + return err;
4234 +
4235 + /* Claim and configure the CCG */
4236 + err = ceetm_config_ccg(&cls->prio.ccg, cls->ch, id, cls->prio.fq,
4237 + dpa_priv);
4238 + if (err)
4239 + return err;
4240 +
4241 + /* Claim and configure the CQ */
4242 + err = qman_ceetm_cq_claim(&cls->prio.cq, cls->ch, id, cls->prio.ccg);
4243 + if (err)
4244 + return err;
4245 +
4246 + if (cls->shaped) {
4247 + err = qman_ceetm_channel_set_cq_cr_eligibility(cls->ch, id, 1);
4248 + if (err)
4249 + return err;
4250 +
4251 + err = qman_ceetm_channel_set_cq_er_eligibility(cls->ch, id, 1);
4252 + if (err)
4253 + return err;
4254 + }
4255 +
4256 + /* Claim and configure a LFQ */
4257 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
4258 + if (err)
4259 + return err;
4260 +
4261 + return 0;
4262 +}
4263 +
4264 +/* Configure a wbfs ceetm class */
4265 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
4266 + struct net_device *dev,
4267 + unsigned int id, int type)
4268 +{
4269 + int err;
4270 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4271 +
4272 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
4273 + if (err)
4274 + return err;
4275 +
4276 + /* Claim and configure the CCG */
4277 + err = ceetm_config_ccg(&cls->wbfs.ccg, cls->ch, id, cls->wbfs.fq,
4278 + dpa_priv);
4279 + if (err)
4280 + return err;
4281 +
4282 + /* Claim and configure the CQ */
4283 + if (type == WBFS_GRP_B)
4284 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, cls->ch, id,
4285 + cls->wbfs.ccg);
4286 + else
4287 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, cls->ch, id,
4288 + cls->wbfs.ccg);
4289 + if (err)
4290 + return err;
4291 +
4292 + /* Configure the CQ weight: real number multiplied by 100 to get rid
4293 + * of the fraction
4294 + */
4295 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
4296 + cls->wbfs.weight * 100);
4297 + if (err)
4298 + return err;
4299 +
4300 + /* Claim and configure a LFQ */
4301 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
4302 + if (err)
4303 + return err;
4304 +
4305 + return 0;
4306 +}
4307 +
4308 +/* Find class in qdisc hash table using given handle */
4309 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
4310 +{
4311 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4312 + struct Qdisc_class_common *clc;
4313 +
4314 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
4315 + __func__, handle, sch->handle);
4316 +
4317 + clc = qdisc_class_find(&priv->clhash, handle);
4318 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
4319 +}
4320 +
4321 +/* Insert a class in the qdisc's class hash */
4322 +static void ceetm_link_class(struct Qdisc *sch,
4323 + struct Qdisc_class_hash *clhash,
4324 + struct Qdisc_class_common *common)
4325 +{
4326 + sch_tree_lock(sch);
4327 + qdisc_class_hash_insert(clhash, common);
4328 + sch_tree_unlock(sch);
4329 + qdisc_class_hash_grow(sch, clhash);
4330 +}
4331 +
4332 +/* Destroy a ceetm class */
4333 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
4334 +{
4335 + struct net_device *dev = qdisc_dev(sch);
4336 +
4337 + if (!cl)
4338 + return;
4339 +
4340 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
4341 + __func__, cl->common.classid, sch->handle);
4342 +
4343 + switch (cl->type) {
4344 + case CEETM_ROOT:
4345 + if (cl->root.child) {
4346 + qdisc_destroy(cl->root.child);
4347 + cl->root.child = NULL;
4348 + }
4349 +
4350 + if (cl->ch && qman_ceetm_channel_release(cl->ch))
4351 + pr_err(KBUILD_BASENAME
4352 + " : %s : error releasing the channel %d\n",
4353 + __func__, cl->ch->idx);
4354 +
4355 + break;
4356 +
4357 + case CEETM_PRIO:
4358 + if (cl->prio.child) {
4359 + qdisc_destroy(cl->prio.child);
4360 + cl->prio.child = NULL;
4361 + }
4362 +
4363 + /* We must make sure the CQ is empty before releasing it.
4364 + * Pause all transmissions while we wait for it to drain.
4365 + */
4366 + netif_tx_stop_all_queues(dev);
4367 + ceetm_drain_class(cl);
4368 +
4369 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
4370 + pr_err(KBUILD_BASENAME
4371 + " : %s : error releasing the LFQ %d\n",
4372 + __func__, cl->prio.lfq->idx);
4373 +
4374 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
4375 + pr_err(KBUILD_BASENAME
4376 + " : %s : error releasing the CQ %d\n",
4377 + __func__, cl->prio.cq->idx);
4378 +
4379 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
4380 + pr_err(KBUILD_BASENAME
4381 + " : %s : error releasing the CCG %d\n",
4382 + __func__, cl->prio.ccg->idx);
4383 +
4384 + kfree(cl->prio.fq);
4385 +
4386 + if (cl->prio.cstats)
4387 + free_percpu(cl->prio.cstats);
4388 +
4389 + netif_tx_wake_all_queues(dev);
4390 + break;
4391 +
4392 + case CEETM_WBFS:
4393 + /* We must make sure the CQ is empty before releasing it.
4394 + * Pause all transmissions while we wait for it to drain.
4395 + */
4396 + netif_tx_stop_all_queues(dev);
4397 + ceetm_drain_class(cl);
4398 +
4399 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
4400 + pr_err(KBUILD_BASENAME
4401 + " : %s : error releasing the LFQ %d\n",
4402 + __func__, cl->wbfs.lfq->idx);
4403 +
4404 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
4405 + pr_err(KBUILD_BASENAME
4406 + " : %s : error releasing the CQ %d\n",
4407 + __func__, cl->wbfs.cq->idx);
4408 +
4409 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
4410 + pr_err(KBUILD_BASENAME
4411 + " : %s : error releasing the CCG %d\n",
4412 + __func__, cl->wbfs.ccg->idx);
4413 +
4414 + kfree(cl->wbfs.fq);
4415 +
4416 + if (cl->wbfs.cstats)
4417 + free_percpu(cl->wbfs.cstats);
4418 +
4419 + netif_tx_wake_all_queues(dev);
4420 + }
4421 +
4422 + tcf_destroy_chain(&cl->filter_list);
4423 + kfree(cl);
4424 +}
4425 +
4426 +/* Destroy a ceetm qdisc */
4427 +static void ceetm_destroy(struct Qdisc *sch)
4428 +{
4429 + unsigned int ntx, i;
4430 + struct hlist_node *next;
4431 + struct ceetm_class *cl;
4432 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4433 + struct net_device *dev = qdisc_dev(sch);
4434 +
4435 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
4436 + __func__, sch->handle);
4437 +
4438 + /* All filters need to be removed before destroying the classes */
4439 + tcf_destroy_chain(&priv->filter_list);
4440 +
4441 + for (i = 0; i < priv->clhash.hashsize; i++) {
4442 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode)
4443 + tcf_destroy_chain(&cl->filter_list);
4444 + }
4445 +
4446 + for (i = 0; i < priv->clhash.hashsize; i++) {
4447 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
4448 + common.hnode)
4449 + ceetm_cls_destroy(sch, cl);
4450 + }
4451 +
4452 + qdisc_class_hash_destroy(&priv->clhash);
4453 +
4454 + switch (priv->type) {
4455 + case CEETM_ROOT:
4456 + dpa_disable_ceetm(dev);
4457 +
4458 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
4459 + pr_err(KBUILD_BASENAME
4460 + " : %s : error releasing the LNI %d\n",
4461 + __func__, priv->root.lni->idx);
4462 +
4463 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
4464 + pr_err(KBUILD_BASENAME
4465 + " : %s : error releasing the SP %d\n",
4466 + __func__, priv->root.sp->idx);
4467 +
4468 + if (priv->root.qstats)
4469 + free_percpu(priv->root.qstats);
4470 +
4471 + if (!priv->root.qdiscs)
4472 + break;
4473 +
4474 + /* Destroy the pfifo qdiscs in case they haven't been attached
4475 + * to the netdev queues yet.
4476 + */
4477 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
4478 + if (priv->root.qdiscs[ntx])
4479 + qdisc_destroy(priv->root.qdiscs[ntx]);
4480 +
4481 + kfree(priv->root.qdiscs);
4482 + break;
4483 +
4484 + case CEETM_PRIO:
4485 + if (priv->prio.parent)
4486 + priv->prio.parent->root.child = NULL;
4487 + break;
4488 +
4489 + case CEETM_WBFS:
4490 + /* Reset the WBFS groups and priorities */
4491 + if (priv->wbfs.ch)
4492 + qman_ceetm_channel_set_group(priv->wbfs.ch, 1, 0, 0);
4493 +
4494 + if (priv->wbfs.parent)
4495 + priv->wbfs.parent->prio.child = NULL;
4496 + break;
4497 + }
4498 +}
4499 +
4500 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
4501 +{
4502 + struct Qdisc *qdisc;
4503 + unsigned int ntx, i;
4504 + struct nlattr *nest;
4505 + struct tc_ceetm_qopt qopt;
4506 + struct ceetm_qdisc_stats *qstats;
4507 + struct net_device *dev = qdisc_dev(sch);
4508 + struct ceetm_qdisc *priv = qdisc_priv(sch);
4509 +
4510 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4511 +
4512 + sch_tree_lock(sch);
4513 + memset(&qopt, 0, sizeof(qopt));
4514 + qopt.type = priv->type;
4515 + qopt.shaped = priv->shaped;
4516 +
4517 + switch (priv->type) {
4518 + case CEETM_ROOT:
4519 + /* Gather statistics from the underlying pfifo qdiscs */
4520 + sch->q.qlen = 0;
4521 + memset(&sch->bstats, 0, sizeof(sch->bstats));
4522 + memset(&sch->qstats, 0, sizeof(sch->qstats));
4523 +
4524 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
4525 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
4526 + sch->q.qlen += qdisc->q.qlen;
4527 + sch->bstats.bytes += qdisc->bstats.bytes;
4528 + sch->bstats.packets += qdisc->bstats.packets;
4529 + sch->qstats.qlen += qdisc->qstats.qlen;
4530 + sch->qstats.backlog += qdisc->qstats.backlog;
4531 + sch->qstats.drops += qdisc->qstats.drops;
4532 + sch->qstats.requeues += qdisc->qstats.requeues;
4533 + sch->qstats.overlimits += qdisc->qstats.overlimits;
4534 + }
4535 +
4536 + for_each_online_cpu(i) {
4537 + qstats = per_cpu_ptr(priv->root.qstats, i);
4538 + sch->qstats.drops += qstats->drops;
4539 + }
4540 +
4541 + qopt.rate = priv->root.rate;
4542 + qopt.ceil = priv->root.ceil;
4543 + qopt.overhead = priv->root.overhead;
4544 + break;
4545 +
4546 + case CEETM_PRIO:
4547 + qopt.qcount = priv->prio.qcount;
4548 + break;
4549 +
4550 + case CEETM_WBFS:
4551 + qopt.qcount = priv->wbfs.qcount;
4552 + qopt.cr = priv->wbfs.cr;
4553 + qopt.er = priv->wbfs.er;
4554 + break;
4555 +
4556 + default:
4557 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
4558 + sch_tree_unlock(sch);
4559 + return -EINVAL;
4560 + }
4561 +
4562 + nest = nla_nest_start(skb, TCA_OPTIONS);
4563 + if (!nest)
4564 + goto nla_put_failure;
4565 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
4566 + goto nla_put_failure;
4567 + nla_nest_end(skb, nest);
4568 +
4569 + sch_tree_unlock(sch);
4570 + return skb->len;
4571 +
4572 +nla_put_failure:
4573 + sch_tree_unlock(sch);
4574 + nla_nest_cancel(skb, nest);
4575 + return -EMSGSIZE;
4576 +}
4577 +
4578 +/* Configure a root ceetm qdisc */
4579 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
4580 + struct tc_ceetm_qopt *qopt)
4581 +{
4582 + struct netdev_queue *dev_queue;
4583 + struct Qdisc *qdisc;
4584 + enum qm_dc_portal dcp_id;
4585 + unsigned int i, sp_id, parent_id;
4586 + int err;
4587 + u64 bps;
4588 + struct qm_ceetm_sp *sp;
4589 + struct qm_ceetm_lni *lni;
4590 + struct net_device *dev = qdisc_dev(sch);
4591 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
4592 + struct mac_device *mac_dev = dpa_priv->mac_dev;
4593 +
4594 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4595 +
4596 + /* Validate inputs */
4597 + if (sch->parent != TC_H_ROOT) {
4598 + pr_err("CEETM: a root ceetm qdisc can not be attached to a class\n");
4599 + tcf_destroy_chain(&priv->filter_list);
4600 + qdisc_class_hash_destroy(&priv->clhash);
4601 + return -EINVAL;
4602 + }
4603 +
4604 + if (!mac_dev) {
4605 + pr_err("CEETM: the interface is lacking a mac\n");
4606 + err = -EINVAL;
4607 + goto err_init_root;
4608 + }
4609 +
4610 + /* Pre-allocate underlying pfifo qdiscs.
4611 + *
4612 + * We want to offload shaping and scheduling decisions to the hardware.
4613 + * The pfifo qdiscs will be attached to the netdev queues and will
4614 + * guide the traffic from the IP stack down to the driver with minimum
4615 + * interference.
4616 + *
4617 + * The CEETM qdiscs and classes will be crossed when the traffic
4618 + * reaches the driver.
4619 + */
4620 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
4621 + sizeof(priv->root.qdiscs[0]),
4622 + GFP_KERNEL);
4623 + if (!priv->root.qdiscs) {
4624 + err = -ENOMEM;
4625 + goto err_init_root;
4626 + }
4627 +
4628 + for (i = 0; i < dev->num_tx_queues; i++) {
4629 + dev_queue = netdev_get_tx_queue(dev, i);
4630 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
4631 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
4632 +
4633 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
4634 + parent_id);
4635 + if (!qdisc) {
4636 + err = -ENOMEM;
4637 + goto err_init_root;
4638 + }
4639 +
4640 + priv->root.qdiscs[i] = qdisc;
4641 + qdisc->flags |= TCQ_F_ONETXQUEUE;
4642 + }
4643 +
4644 + sch->flags |= TCQ_F_MQROOT;
4645 +
4646 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
4647 + if (!priv->root.qstats) {
4648 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4649 + __func__);
4650 + err = -ENOMEM;
4651 + goto err_init_root;
4652 + }
4653 +
4654 + priv->shaped = qopt->shaped;
4655 + priv->root.rate = qopt->rate;
4656 + priv->root.ceil = qopt->ceil;
4657 + priv->root.overhead = qopt->overhead;
4658 +
4659 + /* Claim the SP */
4660 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
4661 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
4662 + if (err) {
4663 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
4664 + __func__);
4665 + goto err_init_root;
4666 + }
4667 +
4668 + priv->root.sp = sp;
4669 +
4670 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
4671 + * are connected to the TX FMan ports
4672 + */
4673 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
4674 + if (err) {
4675 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
4676 + __func__);
4677 + goto err_init_root;
4678 + }
4679 +
4680 + priv->root.lni = lni;
4681 +
4682 + err = qman_ceetm_sp_set_lni(sp, lni);
4683 + if (err) {
4684 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
4685 + __func__);
4686 + goto err_init_root;
4687 + }
4688 +
4689 + lni->sp = sp;
4690 +
4691 + /* Configure the LNI shaper */
4692 + if (priv->shaped) {
4693 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
4694 + if (err) {
4695 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4696 + __func__);
4697 + goto err_init_root;
4698 + }
4699 +
4700 + bps = priv->root.rate << 3; /* Bps -> bps */
4701 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
4702 + if (err) {
4703 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4704 + __func__);
4705 + goto err_init_root;
4706 + }
4707 +
4708 + bps = priv->root.ceil << 3; /* Bps -> bps */
4709 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
4710 + if (err) {
4711 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
4712 + __func__);
4713 + goto err_init_root;
4714 + }
4715 + }
4716 +
4717 + /* TODO default configuration */
4718 +
4719 + dpa_enable_ceetm(dev);
4720 + return 0;
4721 +
4722 +err_init_root:
4723 + ceetm_destroy(sch);
4724 + return err;
4725 +}
4726 +
4727 +/* Configure a prio ceetm qdisc */
4728 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
4729 + struct tc_ceetm_qopt *qopt)
4730 +{
4731 + int err;
4732 + unsigned int i;
4733 + struct ceetm_class *parent_cl, *child_cl;
4734 + struct Qdisc *parent_qdisc;
4735 + struct net_device *dev = qdisc_dev(sch);
4736 +
4737 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4738 +
4739 + if (sch->parent == TC_H_ROOT) {
4740 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
4741 + err = -EINVAL;
4742 + goto err_init_prio;
4743 + }
4744 +
4745 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4746 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4747 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4748 + err = -EINVAL;
4749 + goto err_init_prio;
4750 + }
4751 +
4752 + /* Obtain the parent root ceetm_class */
4753 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4754 +
4755 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
4756 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
4757 + err = -EINVAL;
4758 + goto err_init_prio;
4759 + }
4760 +
4761 + priv->prio.parent = parent_cl;
4762 + parent_cl->root.child = sch;
4763 +
4764 + priv->shaped = parent_cl->shaped;
4765 + priv->prio.qcount = qopt->qcount;
4766 + priv->prio.ch = parent_cl->ch;
4767 +
4768 + /* Create and configure qcount child classes */
4769 + for (i = 0; i < priv->prio.qcount; i++) {
4770 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4771 + if (!child_cl) {
4772 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4773 + __func__);
4774 + err = -ENOMEM;
4775 + goto err_init_prio;
4776 + }
4777 +
4778 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
4779 + if (!child_cl->prio.cstats) {
4780 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4781 + __func__);
4782 + err = -ENOMEM;
4783 + goto err_init_prio_cls;
4784 + }
4785 +
4786 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4787 + child_cl->refcnt = 1;
4788 + child_cl->parent = sch;
4789 + child_cl->type = CEETM_PRIO;
4790 + child_cl->shaped = priv->shaped;
4791 + child_cl->prio.child = NULL;
4792 + child_cl->ch = priv->prio.ch;
4793 +
4794 + /* All shaped CQs have CR and ER enabled by default */
4795 + child_cl->prio.cr = child_cl->shaped;
4796 + child_cl->prio.er = child_cl->shaped;
4797 + child_cl->prio.fq = NULL;
4798 + child_cl->prio.cq = NULL;
4799 +
4800 + /* Configure the corresponding hardware CQ */
4801 + err = ceetm_config_prio_cls(child_cl, dev, i);
4802 + if (err) {
4803 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
4804 + __func__, child_cl->common.classid);
4805 + goto err_init_prio_cls;
4806 + }
4807 +
4808 + /* Add class handle in Qdisc */
4809 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
4810 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
4811 + __func__, child_cl->common.classid,
4812 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
4813 + }
4814 +
4815 + return 0;
4816 +
4817 +err_init_prio_cls:
4818 + ceetm_cls_destroy(sch, child_cl);
4819 +err_init_prio:
4820 + ceetm_destroy(sch);
4821 + return err;
4822 +}
4823 +
4824 +/* Configure a wbfs ceetm qdisc */
4825 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
4826 + struct tc_ceetm_qopt *qopt)
4827 +{
4828 + int err, group_b, small_group;
4829 + unsigned int i, id, prio_a, prio_b;
4830 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
4831 + struct Qdisc *parent_qdisc;
4832 + struct ceetm_qdisc *parent_priv;
4833 + struct net_device *dev = qdisc_dev(sch);
4834 +
4835 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
4836 +
4837 + /* Validate inputs */
4838 + if (sch->parent == TC_H_ROOT) {
4839 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
4840 + err = -EINVAL;
4841 + goto err_init_wbfs;
4842 + }
4843 +
4844 + /* Obtain the parent prio ceetm qdisc */
4845 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
4846 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
4847 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
4848 + err = -EINVAL;
4849 + goto err_init_wbfs;
4850 + }
4851 +
4852 + /* Obtain the parent prio ceetm class */
4853 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
4854 + parent_priv = qdisc_priv(parent_qdisc);
4855 +
4856 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
4857 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
4858 + err = -EINVAL;
4859 + goto err_init_wbfs;
4860 + }
4861 +
4862 + if (!qopt->qcount || !qopt->qweight[0]) {
4863 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
4864 + err = -EINVAL;
4865 + goto err_init_wbfs;
4866 + }
4867 +
4868 + priv->shaped = parent_cl->shaped;
4869 +
4870 + if (!priv->shaped && (qopt->cr || qopt->er)) {
4871 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
4872 + err = -EINVAL;
4873 + goto err_init_wbfs;
4874 + }
4875 +
4876 + if (priv->shaped && !(qopt->cr || qopt->er)) {
4877 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
4878 + err = -EINVAL;
4879 + goto err_init_wbfs;
4880 + }
4881 +
4882 + /* Obtain the parent root ceetm class */
4883 + root_cl = parent_priv->prio.parent;
4884 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
4885 + root_cl->root.wbfs_grp_large) {
4886 + pr_err("CEETM: no more wbfs classes are available\n");
4887 + err = -EINVAL;
4888 + goto err_init_wbfs;
4889 + }
4890 +
4891 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
4892 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
4893 + pr_err("CEETM: only %d wbfs classes are available\n",
4894 + CEETM_MIN_WBFS_QCOUNT);
4895 + err = -EINVAL;
4896 + goto err_init_wbfs;
4897 + }
4898 +
4899 + priv->wbfs.parent = parent_cl;
4900 + parent_cl->prio.child = sch;
4901 +
4902 + priv->wbfs.qcount = qopt->qcount;
4903 + priv->wbfs.cr = qopt->cr;
4904 + priv->wbfs.er = qopt->er;
4905 + priv->wbfs.ch = parent_cl->ch;
4906 +
4907 + /* Configure the hardware wbfs channel groups */
4908 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
4909 + /* Configure the large group A */
4910 + priv->wbfs.group_type = WBFS_GRP_LARGE;
4911 + small_group = false;
4912 + group_b = false;
4913 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4914 + prio_b = prio_a;
4915 +
4916 + } else if (root_cl->root.wbfs_grp_a) {
4917 + /* Configure the group B */
4918 + priv->wbfs.group_type = WBFS_GRP_B;
4919 +
4920 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
4921 + &prio_a, &prio_b);
4922 + if (err) {
4923 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4924 + __func__);
4925 + goto err_init_wbfs;
4926 + }
4927 +
4928 + small_group = true;
4929 + group_b = true;
4930 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
4931 + /* If group A isn't configured, configure it as group B */
4932 + prio_a = prio_a ? : prio_b;
4933 +
4934 + } else {
4935 + /* Configure the small group A */
4936 + priv->wbfs.group_type = WBFS_GRP_A;
4937 +
4938 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
4939 + &prio_a, &prio_b);
4940 + if (err) {
4941 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
4942 + __func__);
4943 + goto err_init_wbfs;
4944 + }
4945 +
4946 + small_group = true;
4947 + group_b = false;
4948 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
4949 + /* If group B isn't configured, configure it as group A */
4950 + prio_b = prio_b ? : prio_a;
4951 + }
4952 +
4953 + err = qman_ceetm_channel_set_group(priv->wbfs.ch, small_group, prio_a,
4954 + prio_b);
4955 + if (err)
4956 + goto err_init_wbfs;
4957 +
4958 + if (priv->shaped) {
4959 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
4960 + group_b,
4961 + priv->wbfs.cr);
4962 + if (err) {
4963 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
4964 + __func__);
4965 + goto err_init_wbfs;
4966 + }
4967 +
4968 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
4969 + group_b,
4970 + priv->wbfs.er);
4971 + if (err) {
4972 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
4973 + __func__);
4974 + goto err_init_wbfs;
4975 + }
4976 + }
4977 +
4978 + /* Create qcount child classes */
4979 + for (i = 0; i < priv->wbfs.qcount; i++) {
4980 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
4981 + if (!child_cl) {
4982 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
4983 + __func__);
4984 + err = -ENOMEM;
4985 + goto err_init_wbfs;
4986 + }
4987 +
4988 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
4989 + if (!child_cl->wbfs.cstats) {
4990 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
4991 + __func__);
4992 + err = -ENOMEM;
4993 + goto err_init_wbfs_cls;
4994 + }
4995 +
4996 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
4997 + child_cl->refcnt = 1;
4998 + child_cl->parent = sch;
4999 + child_cl->type = CEETM_WBFS;
5000 + child_cl->shaped = priv->shaped;
5001 + child_cl->wbfs.fq = NULL;
5002 + child_cl->wbfs.cq = NULL;
5003 + child_cl->wbfs.weight = qopt->qweight[i];
5004 + child_cl->ch = priv->wbfs.ch;
5005 +
5006 + if (priv->wbfs.group_type == WBFS_GRP_B)
5007 + id = WBFS_GRP_B_OFFSET + i;
5008 + else
5009 + id = WBFS_GRP_A_OFFSET + i;
5010 +
5011 + err = ceetm_config_wbfs_cls(child_cl, dev, id,
5012 + priv->wbfs.group_type);
5013 + if (err) {
5014 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5015 + __func__, child_cl->common.classid);
5016 + goto err_init_wbfs_cls;
5017 + }
5018 +
5019 + /* Add class handle in Qdisc */
5020 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
5021 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
5022 + __func__, child_cl->common.classid,
5023 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
5024 + }
5025 +
5026 + /* Signal the root class that a group has been configured */
5027 + switch (priv->wbfs.group_type) {
5028 + case WBFS_GRP_LARGE:
5029 + root_cl->root.wbfs_grp_large = true;
5030 + break;
5031 + case WBFS_GRP_A:
5032 + root_cl->root.wbfs_grp_a = true;
5033 + break;
5034 + case WBFS_GRP_B:
5035 + root_cl->root.wbfs_grp_b = true;
5036 + break;
5037 + }
5038 +
5039 + return 0;
5040 +
5041 +err_init_wbfs_cls:
5042 + ceetm_cls_destroy(sch, child_cl);
5043 +err_init_wbfs:
5044 + ceetm_destroy(sch);
5045 + return err;
5046 +}
5047 +
5048 +/* Configure a generic ceetm qdisc */
5049 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
5050 +{
5051 + struct tc_ceetm_qopt *qopt;
5052 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5053 + int ret;
5054 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5055 + struct net_device *dev = qdisc_dev(sch);
5056 +
5057 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5058 +
5059 + if (!netif_is_multiqueue(dev))
5060 + return -EOPNOTSUPP;
5061 +
5062 + if (!opt) {
5063 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5064 + return -EINVAL;
5065 + }
5066 +
5067 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5068 + if (ret < 0) {
5069 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5070 + return ret;
5071 + }
5072 +
5073 + if (!tb[TCA_CEETM_QOPS]) {
5074 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5075 + return -EINVAL;
5076 + }
5077 +
5078 + if (TC_H_MIN(sch->handle)) {
5079 + pr_err("CEETM: a qdisc should not have a minor\n");
5080 + return -EINVAL;
5081 + }
5082 +
5083 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5084 +
5085 + /* Initialize the class hash list. Each qdisc has its own class hash */
5086 + ret = qdisc_class_hash_init(&priv->clhash);
5087 + if (ret < 0) {
5088 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
5089 + __func__);
5090 + return ret;
5091 + }
5092 +
5093 + priv->type = qopt->type;
5094 +
5095 + switch (priv->type) {
5096 + case CEETM_ROOT:
5097 + netif_tx_stop_all_queues(dev);
5098 + dpaa_drain_fqs(dev);
5099 + ret = ceetm_init_root(sch, priv, qopt);
5100 + netif_tx_wake_all_queues(dev);
5101 + break;
5102 + case CEETM_PRIO:
5103 + ret = ceetm_init_prio(sch, priv, qopt);
5104 + break;
5105 + case CEETM_WBFS:
5106 + ret = ceetm_init_wbfs(sch, priv, qopt);
5107 + break;
5108 + default:
5109 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5110 + ceetm_destroy(sch);
5111 + ret = -EINVAL;
5112 + }
5113 +
5114 + return ret;
5115 +}
5116 +
5117 +/* Edit a root ceetm qdisc */
5118 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
5119 + struct net_device *dev,
5120 + struct tc_ceetm_qopt *qopt)
5121 +{
5122 + int err = 0;
5123 + u64 bps;
5124 +
5125 + if (priv->shaped != (bool)qopt->shaped) {
5126 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
5127 + priv->shaped ? "shaped" : "unshaped");
5128 + return -EINVAL;
5129 + }
5130 +
5131 + /* Nothing to modify for unshaped qdiscs */
5132 + if (!priv->shaped)
5133 + return 0;
5134 +
5135 + /* Configure the LNI shaper */
5136 + if (priv->root.overhead != qopt->overhead) {
5137 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
5138 + qopt->overhead);
5139 + if (err)
5140 + goto change_err;
5141 + priv->root.overhead = qopt->overhead;
5142 + }
5143 +
5144 + if (priv->root.rate != qopt->rate) {
5145 + bps = qopt->rate << 3; /* Bps -> bps */
5146 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
5147 + dev->mtu);
5148 + if (err)
5149 + goto change_err;
5150 + priv->root.rate = qopt->rate;
5151 + }
5152 +
5153 + if (priv->root.ceil != qopt->ceil) {
5154 + bps = qopt->ceil << 3; /* Bps -> bps */
5155 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
5156 + dev->mtu);
5157 + if (err)
5158 + goto change_err;
5159 + priv->root.ceil = qopt->ceil;
5160 + }
5161 +
5162 + return 0;
5163 +
5164 +change_err:
5165 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
5166 + __func__, sch->handle);
5167 + return err;
5168 +}
5169 +
5170 +/* Edit a wbfs ceetm qdisc */
5171 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
5172 + struct tc_ceetm_qopt *qopt)
5173 +{
5174 + int err;
5175 + bool group_b;
5176 +
5177 + if (qopt->qcount) {
5178 + pr_err("CEETM: the qcount can not be modified\n");
5179 + return -EINVAL;
5180 + }
5181 +
5182 + if (qopt->qweight[0]) {
5183 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
5184 + return -EINVAL;
5185 + }
5186 +
5187 + if (!priv->shaped && (qopt->cr || qopt->er)) {
5188 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
5189 + return -EINVAL;
5190 + }
5191 +
5192 + if (priv->shaped && !(qopt->cr || qopt->er)) {
5193 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
5194 + return -EINVAL;
5195 + }
5196 +
5197 + /* Nothing to modify for unshaped qdiscs */
5198 + if (!priv->shaped)
5199 + return 0;
5200 +
5201 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
5202 +
5203 + if (qopt->cr != priv->wbfs.cr) {
5204 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
5205 + group_b,
5206 + qopt->cr);
5207 + if (err)
5208 + goto change_err;
5209 + priv->wbfs.cr = qopt->cr;
5210 + }
5211 +
5212 + if (qopt->er != priv->wbfs.er) {
5213 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
5214 + group_b,
5215 + qopt->er);
5216 + if (err)
5217 + goto change_err;
5218 + priv->wbfs.er = qopt->er;
5219 + }
5220 +
5221 + return 0;
5222 +
5223 +change_err:
5224 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
5225 + __func__, sch->handle);
5226 + return err;
5227 +}
5228 +
5229 +/* Edit a ceetm qdisc */
5230 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
5231 +{
5232 + struct tc_ceetm_qopt *qopt;
5233 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
5234 + int ret;
5235 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5236 + struct net_device *dev = qdisc_dev(sch);
5237 +
5238 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5239 +
5240 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy);
5241 + if (ret < 0) {
5242 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5243 + return ret;
5244 + }
5245 +
5246 + if (!tb[TCA_CEETM_QOPS]) {
5247 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5248 + return -EINVAL;
5249 + }
5250 +
5251 + if (TC_H_MIN(sch->handle)) {
5252 + pr_err("CEETM: a qdisc should not have a minor\n");
5253 + return -EINVAL;
5254 + }
5255 +
5256 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
5257 +
5258 + if (priv->type != qopt->type) {
5259 + pr_err("CEETM: qdisc %X is not of the provided type\n",
5260 + sch->handle);
5261 + return -EINVAL;
5262 + }
5263 +
5264 + switch (priv->type) {
5265 + case CEETM_ROOT:
5266 + ret = ceetm_change_root(sch, priv, dev, qopt);
5267 + break;
5268 + case CEETM_PRIO:
5269 + pr_err("CEETM: prio qdiscs can not be modified\n");
5270 + ret = -EINVAL;
5271 + break;
5272 + case CEETM_WBFS:
5273 + ret = ceetm_change_wbfs(sch, priv, qopt);
5274 + break;
5275 + default:
5276 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
5277 + ret = -EINVAL;
5278 + }
5279 +
5280 + return ret;
5281 +}
5282 +
5283 +/* Graft the underlying pfifo qdiscs to the netdev queues.
5284 + * It's safe to remove our references at this point, since the kernel will
5285 + * destroy the qdiscs on its own and no cleanup from our part is required.
5286 + */
5287 +static void ceetm_attach(struct Qdisc *sch)
5288 +{
5289 + struct net_device *dev = qdisc_dev(sch);
5290 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5291 + struct Qdisc *qdisc, *old_qdisc;
5292 + unsigned int i;
5293 +
5294 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5295 +
5296 + for (i = 0; i < dev->num_tx_queues; i++) {
5297 + qdisc = priv->root.qdiscs[i];
5298 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
5299 + if (old_qdisc)
5300 + qdisc_destroy(old_qdisc);
5301 + }
5302 +
5303 + kfree(priv->root.qdiscs);
5304 + priv->root.qdiscs = NULL;
5305 +}
5306 +
5307 +static unsigned long ceetm_cls_get(struct Qdisc *sch, u32 classid)
5308 +{
5309 + struct ceetm_class *cl;
5310 +
5311 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5312 + __func__, classid, sch->handle);
5313 + cl = ceetm_find(classid, sch);
5314 +
5315 + if (cl)
5316 + cl->refcnt++; /* Will decrement in put() */
5317 + return (unsigned long)cl;
5318 +}
5319 +
5320 +static void ceetm_cls_put(struct Qdisc *sch, unsigned long arg)
5321 +{
5322 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5323 +
5324 + pr_debug(KBUILD_BASENAME " : %s : classid %X from qdisc %X\n",
5325 + __func__, cl->common.classid, sch->handle);
5326 + cl->refcnt--;
5327 +
5328 + if (cl->refcnt == 0)
5329 + ceetm_cls_destroy(sch, cl);
5330 +}
5331 +
5332 +static int ceetm_cls_change_root(struct ceetm_class *cl,
5333 + struct tc_ceetm_copt *copt,
5334 + struct net_device *dev)
5335 +{
5336 + int err;
5337 + u64 bps;
5338 +
5339 + if ((bool)copt->shaped != cl->shaped) {
5340 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
5341 + cl->shaped ? "shaped" : "unshaped");
5342 + return -EINVAL;
5343 + }
5344 +
5345 + if (cl->shaped && cl->root.rate != copt->rate) {
5346 + bps = copt->rate << 3; /* Bps -> bps */
5347 + err = qman_ceetm_channel_set_commit_rate_bps(cl->ch, bps,
5348 + dev->mtu);
5349 + if (err)
5350 + goto change_cls_err;
5351 + cl->root.rate = copt->rate;
5352 + }
5353 +
5354 + if (cl->shaped && cl->root.ceil != copt->ceil) {
5355 + bps = copt->ceil << 3; /* Bps -> bps */
5356 + err = qman_ceetm_channel_set_excess_rate_bps(cl->ch, bps,
5357 + dev->mtu);
5358 + if (err)
5359 + goto change_cls_err;
5360 + cl->root.ceil = copt->ceil;
5361 + }
5362 +
5363 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
5364 + err = qman_ceetm_channel_set_weight(cl->ch, copt->tbl);
5365 + if (err)
5366 + goto change_cls_err;
5367 + cl->root.tbl = copt->tbl;
5368 + }
5369 +
5370 + return 0;
5371 +
5372 +change_cls_err:
5373 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
5374 + __func__, cl->common.classid);
5375 + return err;
5376 +}
5377 +
5378 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
5379 + struct tc_ceetm_copt *copt)
5380 +{
5381 + int err;
5382 +
5383 + if (!cl->shaped && (copt->cr || copt->er)) {
5384 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
5385 + return -EINVAL;
5386 + }
5387 +
5388 + if (cl->prio.cr != (bool)copt->cr) {
5389 + err = qman_ceetm_channel_set_cq_cr_eligibility(
5390 + cl->prio.cq->parent,
5391 + cl->prio.cq->idx,
5392 + copt->cr);
5393 + if (err)
5394 + goto change_cls_err;
5395 + cl->prio.cr = copt->cr;
5396 + }
5397 +
5398 + if (cl->prio.er != (bool)copt->er) {
5399 + err = qman_ceetm_channel_set_cq_er_eligibility(
5400 + cl->prio.cq->parent,
5401 + cl->prio.cq->idx,
5402 + copt->er);
5403 + if (err)
5404 + goto change_cls_err;
5405 + cl->prio.er = copt->er;
5406 + }
5407 +
5408 + return 0;
5409 +
5410 +change_cls_err:
5411 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
5412 + __func__, cl->common.classid);
5413 + return err;
5414 +}
5415 +
5416 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
5417 + struct tc_ceetm_copt *copt)
5418 +{
5419 + int err;
5420 +
5421 + if (copt->weight != cl->wbfs.weight) {
5422 + /* Configure the CQ weight: real number multiplied by 100 to
5423 + * get rid of the fraction
5424 + */
5425 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
5426 + copt->weight * 100);
5427 +
5428 + if (err) {
5429 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
5430 + __func__, cl->common.classid);
5431 + return err;
5432 + }
5433 +
5434 + cl->wbfs.weight = copt->weight;
5435 + }
5436 +
5437 + return 0;
5438 +}
5439 +
5440 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
5441 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
5442 + struct nlattr **tca, unsigned long *arg)
5443 +{
5444 + int err;
5445 + u64 bps;
5446 + struct ceetm_qdisc *priv;
5447 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
5448 + struct nlattr *opt = tca[TCA_OPTIONS];
5449 + struct nlattr *tb[__TCA_CEETM_MAX];
5450 + struct tc_ceetm_copt *copt;
5451 + struct qm_ceetm_channel *channel;
5452 + struct net_device *dev = qdisc_dev(sch);
5453 +
5454 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
5455 + __func__, classid, sch->handle);
5456 +
5457 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
5458 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
5459 + return -EINVAL;
5460 + }
5461 +
5462 + priv = qdisc_priv(sch);
5463 +
5464 + if (!opt) {
5465 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5466 + return -EINVAL;
5467 + }
5468 +
5469 + if (!cl && sch->handle != parentid) {
5470 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
5471 + return -EINVAL;
5472 + }
5473 +
5474 + if (!cl && priv->type != CEETM_ROOT) {
5475 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5476 + return -EINVAL;
5477 + }
5478 +
5479 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy);
5480 + if (err < 0) {
5481 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5482 + return -EINVAL;
5483 + }
5484 +
5485 + if (!tb[TCA_CEETM_COPT]) {
5486 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
5487 + return -EINVAL;
5488 + }
5489 +
5490 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
5491 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
5492 + return -EINVAL;
5493 + }
5494 +
5495 + copt = nla_data(tb[TCA_CEETM_COPT]);
5496 +
5497 + /* Configure an existing ceetm class */
5498 + if (cl) {
5499 + if (copt->type != cl->type) {
5500 + pr_err("CEETM: class %X is not of the provided type\n",
5501 + cl->common.classid);
5502 + return -EINVAL;
5503 + }
5504 +
5505 + switch (copt->type) {
5506 + case CEETM_ROOT:
5507 + return ceetm_cls_change_root(cl, copt, dev);
5508 +
5509 + case CEETM_PRIO:
5510 + return ceetm_cls_change_prio(cl, copt);
5511 +
5512 + case CEETM_WBFS:
5513 + return ceetm_cls_change_wbfs(cl, copt);
5514 +
5515 + default:
5516 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
5517 + __func__);
5518 + return -EINVAL;
5519 + }
5520 + }
5521 +
5522 + /* Add a new root ceetm class */
5523 + if (copt->type != CEETM_ROOT) {
5524 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
5525 + return -EINVAL;
5526 + }
5527 +
5528 + if (copt->shaped && !priv->shaped) {
5529 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
5530 + return -EINVAL;
5531 + }
5532 +
5533 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
5534 + if (!cl)
5535 + return -ENOMEM;
5536 +
5537 + cl->type = copt->type;
5538 + cl->shaped = copt->shaped;
5539 + cl->root.rate = copt->rate;
5540 + cl->root.ceil = copt->ceil;
5541 + cl->root.tbl = copt->tbl;
5542 +
5543 + cl->common.classid = classid;
5544 + cl->refcnt = 1;
5545 + cl->parent = sch;
5546 + cl->root.child = NULL;
5547 + cl->root.wbfs_grp_a = false;
5548 + cl->root.wbfs_grp_b = false;
5549 + cl->root.wbfs_grp_large = false;
5550 +
5551 + /* Claim a CEETM channel */
5552 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
5553 + if (err) {
5554 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
5555 + __func__);
5556 + goto claim_err;
5557 + }
5558 +
5559 + cl->ch = channel;
5560 +
5561 + if (cl->shaped) {
5562 + /* Configure the channel shaper */
5563 + err = qman_ceetm_channel_enable_shaper(channel, 1);
5564 + if (err)
5565 + goto channel_err;
5566 +
5567 + bps = cl->root.rate << 3; /* Bps -> bps */
5568 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
5569 + dev->mtu);
5570 + if (err)
5571 + goto channel_err;
5572 +
5573 + bps = cl->root.ceil << 3; /* Bps -> bps */
5574 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
5575 + dev->mtu);
5576 + if (err)
5577 + goto channel_err;
5578 +
5579 + } else {
5580 + /* Configure the uFQ algorithm */
5581 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
5582 + if (err)
5583 + goto channel_err;
5584 + }
5585 +
5586 + /* Add class handle in Qdisc */
5587 + ceetm_link_class(sch, &priv->clhash, &cl->common);
5588 +
5589 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
5590 + __func__, classid, channel->idx);
5591 + *arg = (unsigned long)cl;
5592 + return 0;
5593 +
5594 +channel_err:
5595 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
5596 + __func__, channel->idx);
5597 + if (qman_ceetm_channel_release(channel))
5598 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
5599 + __func__, channel->idx);
5600 +claim_err:
5601 + kfree(cl);
5602 + return err;
5603 +}
5604 +
5605 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
5606 +{
5607 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5608 + struct ceetm_class *cl;
5609 + unsigned int i;
5610 +
5611 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
5612 +
5613 + if (arg->stop)
5614 + return;
5615 +
5616 + for (i = 0; i < priv->clhash.hashsize; i++) {
5617 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
5618 + if (arg->count < arg->skip) {
5619 + arg->count++;
5620 + continue;
5621 + }
5622 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
5623 + arg->stop = 1;
5624 + return;
5625 + }
5626 + arg->count++;
5627 + }
5628 + }
5629 +}
5630 +
5631 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
5632 + struct sk_buff *skb, struct tcmsg *tcm)
5633 +{
5634 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5635 + struct nlattr *nest;
5636 + struct tc_ceetm_copt copt;
5637 +
5638 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5639 + __func__, cl->common.classid, sch->handle);
5640 +
5641 + sch_tree_lock(sch);
5642 +
5643 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
5644 + tcm->tcm_handle = cl->common.classid;
5645 +
5646 + memset(&copt, 0, sizeof(copt));
5647 +
5648 + copt.shaped = cl->shaped;
5649 + copt.type = cl->type;
5650 +
5651 + switch (cl->type) {
5652 + case CEETM_ROOT:
5653 + if (cl->root.child)
5654 + tcm->tcm_info = cl->root.child->handle;
5655 +
5656 + copt.rate = cl->root.rate;
5657 + copt.ceil = cl->root.ceil;
5658 + copt.tbl = cl->root.tbl;
5659 + break;
5660 +
5661 + case CEETM_PRIO:
5662 + if (cl->prio.child)
5663 + tcm->tcm_info = cl->prio.child->handle;
5664 +
5665 + copt.cr = cl->prio.cr;
5666 + copt.er = cl->prio.er;
5667 + break;
5668 +
5669 + case CEETM_WBFS:
5670 + copt.weight = cl->wbfs.weight;
5671 + break;
5672 + }
5673 +
5674 + nest = nla_nest_start(skb, TCA_OPTIONS);
5675 + if (!nest)
5676 + goto nla_put_failure;
5677 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
5678 + goto nla_put_failure;
5679 + nla_nest_end(skb, nest);
5680 + sch_tree_unlock(sch);
5681 + return skb->len;
5682 +
5683 +nla_put_failure:
5684 + sch_tree_unlock(sch);
5685 + nla_nest_cancel(skb, nest);
5686 + return -EMSGSIZE;
5687 +}
5688 +
5689 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
5690 +{
5691 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5692 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5693 +
5694 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5695 + __func__, cl->common.classid, sch->handle);
5696 +
5697 + sch_tree_lock(sch);
5698 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
5699 + cl->refcnt--;
5700 +
5701 + /* The refcnt should be at least 1 since we have incremented it in
5702 + * get(). Will decrement again in put() where we will call destroy()
5703 + * to actually free the memory if it reaches 0.
5704 + */
5705 + WARN_ON(cl->refcnt == 0);
5706 +
5707 + sch_tree_unlock(sch);
5708 + return 0;
5709 +}
5710 +
5711 +/* Get the class' child qdisc, if any */
5712 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
5713 +{
5714 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5715 +
5716 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
5717 + __func__, cl->common.classid, sch->handle);
5718 +
5719 + switch (cl->type) {
5720 + case CEETM_ROOT:
5721 + return cl->root.child;
5722 +
5723 + case CEETM_PRIO:
5724 + return cl->prio.child;
5725 + }
5726 +
5727 + return NULL;
5728 +}
5729 +
5730 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
5731 + struct Qdisc *new, struct Qdisc **old)
5732 +{
5733 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
5734 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
5735 + return -EOPNOTSUPP;
5736 + }
5737 +
5738 + return 0;
5739 +}
5740 +
5741 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
5742 + struct gnet_dump *d)
5743 +{
5744 + unsigned int i;
5745 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5746 + struct gnet_stats_basic_packed tmp_bstats;
5747 + struct ceetm_class_stats *cstats = NULL;
5748 + struct qm_ceetm_cq *cq = NULL;
5749 + struct tc_ceetm_xstats xstats;
5750 +
5751 + memset(&xstats, 0, sizeof(xstats));
5752 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
5753 +
5754 + switch (cl->type) {
5755 + case CEETM_ROOT:
5756 + return 0;
5757 + case CEETM_PRIO:
5758 + cq = cl->prio.cq;
5759 + break;
5760 + case CEETM_WBFS:
5761 + cq = cl->wbfs.cq;
5762 + break;
5763 + }
5764 +
5765 + for_each_online_cpu(i) {
5766 + switch (cl->type) {
5767 + case CEETM_PRIO:
5768 + cstats = per_cpu_ptr(cl->prio.cstats, i);
5769 + break;
5770 + case CEETM_WBFS:
5771 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
5772 + break;
5773 + }
5774 +
5775 + if (cstats) {
5776 + xstats.ern_drop_count += cstats->ern_drop_count;
5777 + xstats.congested_count += cstats->congested_count;
5778 + tmp_bstats.bytes += cstats->bstats.bytes;
5779 + tmp_bstats.packets += cstats->bstats.packets;
5780 + }
5781 + }
5782 +
5783 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
5784 + d, NULL, &tmp_bstats) < 0)
5785 + return -1;
5786 +
5787 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
5788 + &xstats.frame_count,
5789 + &xstats.byte_count))
5790 + return -1;
5791 +
5792 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
5793 +}
5794 +
5795 +static struct tcf_proto **ceetm_tcf_chain(struct Qdisc *sch, unsigned long arg)
5796 +{
5797 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5798 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5799 + struct tcf_proto **fl = cl ? &cl->filter_list : &priv->filter_list;
5800 +
5801 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5802 + cl ? cl->common.classid : 0, sch->handle);
5803 + return fl;
5804 +}
5805 +
5806 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
5807 + u32 classid)
5808 +{
5809 + struct ceetm_class *cl = ceetm_find(classid, sch);
5810 +
5811 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5812 + cl ? cl->common.classid : 0, sch->handle);
5813 + return (unsigned long)cl;
5814 +}
5815 +
5816 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
5817 +{
5818 + struct ceetm_class *cl = (struct ceetm_class *)arg;
5819 +
5820 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
5821 + cl ? cl->common.classid : 0, sch->handle);
5822 +}
5823 +
5824 +const struct Qdisc_class_ops ceetm_cls_ops = {
5825 + .graft = ceetm_cls_graft,
5826 + .leaf = ceetm_cls_leaf,
5827 + .get = ceetm_cls_get,
5828 + .put = ceetm_cls_put,
5829 + .change = ceetm_cls_change,
5830 + .delete = ceetm_cls_delete,
5831 + .walk = ceetm_cls_walk,
5832 + .tcf_chain = ceetm_tcf_chain,
5833 + .bind_tcf = ceetm_tcf_bind,
5834 + .unbind_tcf = ceetm_tcf_unbind,
5835 + .dump = ceetm_cls_dump,
5836 + .dump_stats = ceetm_cls_dump_stats,
5837 +};
5838 +
5839 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
5840 + .id = "ceetm",
5841 + .priv_size = sizeof(struct ceetm_qdisc),
5842 + .cl_ops = &ceetm_cls_ops,
5843 + .init = ceetm_init,
5844 + .destroy = ceetm_destroy,
5845 + .change = ceetm_change,
5846 + .dump = ceetm_dump,
5847 + .attach = ceetm_attach,
5848 + .owner = THIS_MODULE,
5849 +};
5850 +
5851 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
5852 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
5853 + struct Qdisc *sch, int *qerr,
5854 + bool *act_drop)
5855 +{
5856 + struct ceetm_qdisc *priv = qdisc_priv(sch);
5857 + struct ceetm_class *cl = NULL, *wbfs_cl;
5858 + struct tcf_result res;
5859 + struct tcf_proto *tcf;
5860 + int result;
5861 +
5862 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
5863 + tcf = priv->filter_list;
5864 + while (tcf && (result = tc_classify(skb, tcf, &res, false)) >= 0) {
5865 +#ifdef CONFIG_NET_CLS_ACT
5866 + switch (result) {
5867 + case TC_ACT_QUEUED:
5868 + case TC_ACT_STOLEN:
5869 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
5870 + case TC_ACT_SHOT:
5871 + /* No valid class found due to action */
5872 + *act_drop = true;
5873 + return NULL;
5874 + }
5875 +#endif
5876 + cl = (void *)res.class;
5877 + if (!cl) {
5878 + if (res.classid == sch->handle) {
5879 + /* The filter leads to the qdisc */
5880 + /* TODO default qdisc */
5881 + return NULL;
5882 + }
5883 +
5884 + cl = ceetm_find(res.classid, sch);
5885 + if (!cl)
5886 + /* The filter leads to an invalid class */
5887 + break;
5888 + }
5889 +
5890 + /* The class might have its own filters attached */
5891 + tcf = cl->filter_list;
5892 + }
5893 +
5894 + if (!cl) {
5895 + /* No valid class found */
5896 + /* TODO default qdisc */
5897 + return NULL;
5898 + }
5899 +
5900 + switch (cl->type) {
5901 + case CEETM_ROOT:
5902 + if (cl->root.child) {
5903 + /* Run the prio qdisc classifiers */
5904 + return ceetm_classify(skb, cl->root.child, qerr,
5905 + act_drop);
5906 + } else {
5907 + /* The root class does not have a child prio qdisc */
5908 + /* TODO default qdisc */
5909 + return NULL;
5910 + }
5911 + case CEETM_PRIO:
5912 + if (cl->prio.child) {
5913 + /* If filters lead to a wbfs class, return it.
5914 + * Otherwise, return the prio class
5915 + */
5916 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
5917 + act_drop);
5918 + /* A NULL result might indicate either an erroneous
5919 + * filter, or no filters at all. We will assume the
5920 + * latter
5921 + */
5922 + return wbfs_cl ? : cl;
5923 + }
5924 + }
5925 +
5926 + /* For wbfs and childless prio classes, return the class directly */
5927 + return cl;
5928 +}
5929 +
5930 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
5931 +{
5932 + const int queue_mapping = dpa_get_queue_mapping(skb);
5933 + struct Qdisc *sch = net_dev->qdisc;
5934 + struct ceetm_class_stats *cstats;
5935 + struct ceetm_qdisc_stats *qstats;
5936 + struct dpa_priv_s *priv_dpa;
5937 + struct ceetm_fq *ceetm_fq;
5938 + struct ceetm_qdisc *priv;
5939 + struct qman_fq *conf_fq;
5940 + struct ceetm_class *cl;
5941 + spinlock_t *root_lock;
5942 + bool act_drop = false;
5943 + int ret;
5944 +
5945 + root_lock = qdisc_lock(sch);
5946 + priv = qdisc_priv(sch);
5947 + qstats = this_cpu_ptr(priv->root.qstats);
5948 +
5949 + spin_lock(root_lock);
5950 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
5951 + spin_unlock(root_lock);
5952 +
5953 +#ifdef CONFIG_NET_CLS_ACT
5954 + if (act_drop) {
5955 + if (ret & __NET_XMIT_BYPASS)
5956 + qstats->drops++;
5957 + goto drop;
5958 + }
5959 +#endif
5960 + /* TODO default class */
5961 + if (unlikely(!cl)) {
5962 + qstats->drops++;
5963 + goto drop;
5964 + }
5965 +
5966 + priv_dpa = netdev_priv(net_dev);
5967 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
5968 +
5969 + /* Choose the proper tx fq and update the basic stats (bytes and
5970 + * packets sent by the class)
5971 + */
5972 + switch (cl->type) {
5973 + case CEETM_PRIO:
5974 + ceetm_fq = cl->prio.fq;
5975 + cstats = this_cpu_ptr(cl->prio.cstats);
5976 + break;
5977 + case CEETM_WBFS:
5978 + ceetm_fq = cl->wbfs.fq;
5979 + cstats = this_cpu_ptr(cl->wbfs.cstats);
5980 + break;
5981 + default:
5982 + qstats->drops++;
5983 + goto drop;
5984 + }
5985 +
5986 + /* If the FQ is congested, avoid enqueuing the frame and dropping it
5987 + * when it returns on the ERN path. Drop it here directly instead.
5988 + */
5989 + if (unlikely(ceetm_fq->congested)) {
5990 + qstats->drops++;
5991 + goto drop;
5992 + }
5993 +
5994 + bstats_update(&cstats->bstats, skb);
5995 + return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq);
5996 +
5997 +drop:
5998 + dev_kfree_skb_any(skb);
5999 + return NET_XMIT_SUCCESS;
6000 +}
6001 +
6002 +static int __init ceetm_register(void)
6003 +{
6004 + int _errno = 0;
6005 +
6006 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
6007 +
6008 + _errno = register_qdisc(&ceetm_qdisc_ops);
6009 + if (unlikely(_errno))
6010 + pr_err(KBUILD_MODNAME
6011 + ": %s:%hu:%s(): register_qdisc() = %d\n",
6012 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
6013 +
6014 + return _errno;
6015 +}
6016 +
6017 +static void __exit ceetm_unregister(void)
6018 +{
6019 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
6020 + KBUILD_BASENAME ".c", __func__);
6021 +
6022 + unregister_qdisc(&ceetm_qdisc_ops);
6023 +}
6024 +
6025 +module_init(ceetm_register);
6026 +module_exit(ceetm_unregister);
6027 --- /dev/null
6028 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
6029 @@ -0,0 +1,240 @@
6030 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
6031 + *
6032 + * Redistribution and use in source and binary forms, with or without
6033 + * modification, are permitted provided that the following conditions are met:
6034 + * * Redistributions of source code must retain the above copyright
6035 + * notice, this list of conditions and the following disclaimer.
6036 + * * Redistributions in binary form must reproduce the above copyright
6037 + * notice, this list of conditions and the following disclaimer in the
6038 + * documentation and/or other materials provided with the distribution.
6039 + * * Neither the name of Freescale Semiconductor nor the
6040 + * names of its contributors may be used to endorse or promote products
6041 + * derived from this software without specific prior written permission.
6042 + *
6043 + *
6044 + * ALTERNATIVELY, this software may be distributed under the terms of the
6045 + * GNU General Public License ("GPL") as published by the Free Software
6046 + * Foundation, either version 2 of that License or (at your option) any
6047 + * later version.
6048 + *
6049 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6050 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6051 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6052 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6053 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6054 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6055 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6056 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6057 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6058 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6059 + */
6060 +
6061 +#ifndef __DPAA_ETH_CEETM_H
6062 +#define __DPAA_ETH_CEETM_H
6063 +
6064 +#include <net/pkt_sched.h>
6065 +#include <net/pkt_cls.h>
6066 +#include <net/netlink.h>
6067 +#include <lnxwrp_fm.h>
6068 +
6069 +#include "mac.h"
6070 +#include "dpaa_eth_common.h"
6071 +
6072 +/* Mask to determine the sub-portal id from a channel number */
6073 +#define CHANNEL_SP_MASK 0x1f
6074 +/* The number of the last channel that services DCP0, connected to FMan 0.
6075 + * Value validated for B4 and T series platforms.
6076 + */
6077 +#define DCP0_MAX_CHANNEL 0x80f
6078 +/* A2V=1 - field A2 is valid
6079 + * A0V=1 - field A0 is valid - enables frame confirmation
6080 + * OVOM=1 - override operation mode bits with values from A2
6081 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
6082 + * NL=0 - the BMI releases all the internal buffers
6083 + */
6084 +#define CEETM_CONTEXT_A 0x1a00000080000000
6085 +/* The ratio between the superior and inferior congestion state thresholds. The
6086 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
6087 + * scheduling).
6088 + */
6089 +#define CEETM_CCGR_RATIO 0.875
6090 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
6091 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
6092 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
6093 + * hex).
6094 + */
6095 +#define PFIFO_MIN_OFFSET 0x21
6096 +
6097 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
6098 +#define CEETM_MAX_PRIO_QCOUNT 8
6099 +#define CEETM_MAX_WBFS_QCOUNT 8
6100 +#define CEETM_MIN_WBFS_QCOUNT 4
6101 +
6102 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
6103 + * and/or 12-15 for group B).
6104 + */
6105 +#define WBFS_GRP_A_OFFSET 8
6106 +#define WBFS_GRP_B_OFFSET 12
6107 +
6108 +#define WBFS_GRP_A 1
6109 +#define WBFS_GRP_B 2
6110 +#define WBFS_GRP_LARGE 3
6111 +
6112 +enum {
6113 + TCA_CEETM_UNSPEC,
6114 + TCA_CEETM_COPT,
6115 + TCA_CEETM_QOPS,
6116 + __TCA_CEETM_MAX,
6117 +};
6118 +
6119 +/* CEETM configuration types */
6120 +enum {
6121 + CEETM_ROOT = 1,
6122 + CEETM_PRIO,
6123 + CEETM_WBFS
6124 +};
6125 +
6126 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
6127 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
6128 +
6129 +struct ceetm_class;
6130 +struct ceetm_qdisc_stats;
6131 +struct ceetm_class_stats;
6132 +
6133 +struct ceetm_fq {
6134 + struct qman_fq fq;
6135 + struct net_device *net_dev;
6136 + struct ceetm_class *ceetm_cls;
6137 + int congested; /* Congestion status */
6138 +};
6139 +
6140 +struct root_q {
6141 + struct Qdisc **qdiscs;
6142 + __u16 overhead;
6143 + __u32 rate;
6144 + __u32 ceil;
6145 + struct qm_ceetm_sp *sp;
6146 + struct qm_ceetm_lni *lni;
6147 + struct ceetm_qdisc_stats __percpu *qstats;
6148 +};
6149 +
6150 +struct prio_q {
6151 + __u16 qcount;
6152 + struct ceetm_class *parent;
6153 + struct qm_ceetm_channel *ch;
6154 +};
6155 +
6156 +struct wbfs_q {
6157 + __u16 qcount;
6158 + int group_type;
6159 + struct ceetm_class *parent;
6160 + struct qm_ceetm_channel *ch;
6161 + __u16 cr;
6162 + __u16 er;
6163 +};
6164 +
6165 +struct ceetm_qdisc {
6166 + int type; /* LNI/CHNL/WBFS */
6167 + bool shaped;
6168 + union {
6169 + struct root_q root;
6170 + struct prio_q prio;
6171 + struct wbfs_q wbfs;
6172 + };
6173 + struct Qdisc_class_hash clhash;
6174 + struct tcf_proto *filter_list; /* qdisc attached filters */
6175 +};
6176 +
6177 +/* CEETM Qdisc configuration parameters */
6178 +struct tc_ceetm_qopt {
6179 + __u32 type;
6180 + __u16 shaped;
6181 + __u16 qcount;
6182 + __u16 overhead;
6183 + __u32 rate;
6184 + __u32 ceil;
6185 + __u16 cr;
6186 + __u16 er;
6187 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
6188 +};
6189 +
6190 +struct root_c {
6191 + unsigned int rate;
6192 + unsigned int ceil;
6193 + unsigned int tbl;
6194 + bool wbfs_grp_a;
6195 + bool wbfs_grp_b;
6196 + bool wbfs_grp_large;
6197 + struct Qdisc *child;
6198 +};
6199 +
6200 +struct prio_c {
6201 + bool cr;
6202 + bool er;
6203 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6204 + struct qm_ceetm_lfq *lfq;
6205 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6206 + struct qm_ceetm_ccg *ccg;
6207 + /* only one wbfs can be linked to one priority CQ */
6208 + struct Qdisc *child;
6209 + struct ceetm_class_stats __percpu *cstats;
6210 +};
6211 +
6212 +struct wbfs_c {
6213 + __u8 weight; /* The weight of the class between 1 and 248 */
6214 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
6215 + struct qm_ceetm_lfq *lfq;
6216 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
6217 + struct qm_ceetm_ccg *ccg;
6218 + struct ceetm_class_stats __percpu *cstats;
6219 +};
6220 +
6221 +struct ceetm_class {
6222 + struct Qdisc_class_common common;
6223 + int refcnt; /* usage count of this class */
6224 + struct tcf_proto *filter_list; /* class attached filters */
6225 + struct Qdisc *parent;
6226 + struct qm_ceetm_channel *ch;
6227 + bool shaped;
6228 + int type; /* ROOT/PRIO/WBFS */
6229 + union {
6230 + struct root_c root;
6231 + struct prio_c prio;
6232 + struct wbfs_c wbfs;
6233 + };
6234 +};
6235 +
6236 +/* CEETM Class configuration parameters */
6237 +struct tc_ceetm_copt {
6238 + __u32 type;
6239 + __u16 shaped;
6240 + __u32 rate;
6241 + __u32 ceil;
6242 + __u16 tbl;
6243 + __u16 cr;
6244 + __u16 er;
6245 + __u8 weight;
6246 +};
6247 +
6248 +/* CEETM stats */
6249 +struct ceetm_qdisc_stats {
6250 + __u32 drops;
6251 +};
6252 +
6253 +struct ceetm_class_stats {
6254 + /* Software counters */
6255 + struct gnet_stats_basic_packed bstats;
6256 + __u32 ern_drop_count;
6257 + __u32 congested_count;
6258 +};
6259 +
6260 +struct tc_ceetm_xstats {
6261 + __u32 ern_drop_count;
6262 + __u32 congested_count;
6263 + /* Hardware counters */
6264 + __u64 frame_count;
6265 + __u64 byte_count;
6266 +};
6267 +
6268 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
6269 +#endif
6270 --- /dev/null
6271 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
6272 @@ -0,0 +1,1802 @@
6273 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
6274 + *
6275 + * Redistribution and use in source and binary forms, with or without
6276 + * modification, are permitted provided that the following conditions are met:
6277 + * * Redistributions of source code must retain the above copyright
6278 + * notice, this list of conditions and the following disclaimer.
6279 + * * Redistributions in binary form must reproduce the above copyright
6280 + * notice, this list of conditions and the following disclaimer in the
6281 + * documentation and/or other materials provided with the distribution.
6282 + * * Neither the name of Freescale Semiconductor nor the
6283 + * names of its contributors may be used to endorse or promote products
6284 + * derived from this software without specific prior written permission.
6285 + *
6286 + *
6287 + * ALTERNATIVELY, this software may be distributed under the terms of the
6288 + * GNU General Public License ("GPL") as published by the Free Software
6289 + * Foundation, either version 2 of that License or (at your option) any
6290 + * later version.
6291 + *
6292 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
6293 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
6294 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6295 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
6296 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
6297 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
6298 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6299 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6300 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
6301 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6302 + */
6303 +
6304 +#include <linux/init.h>
6305 +#include <linux/module.h>
6306 +#include <linux/of_platform.h>
6307 +#include <linux/of_net.h>
6308 +#include <linux/etherdevice.h>
6309 +#include <linux/kthread.h>
6310 +#include <linux/percpu.h>
6311 +#include <linux/highmem.h>
6312 +#include <linux/sort.h>
6313 +#include <linux/fsl_qman.h>
6314 +#include <linux/ip.h>
6315 +#include <linux/ipv6.h>
6316 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
6317 +#include "dpaa_eth.h"
6318 +#include "dpaa_eth_common.h"
6319 +#ifdef CONFIG_FSL_DPAA_1588
6320 +#include "dpaa_1588.h"
6321 +#endif
6322 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6323 +#include "dpaa_debugfs.h"
6324 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6325 +#include "mac.h"
6326 +
6327 +/* Size in bytes of the FQ taildrop threshold */
6328 +#define DPA_FQ_TD 0x200000
6329 +
6330 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6331 +struct ptp_priv_s ptp_priv;
6332 +#endif
6333 +
6334 +static struct dpa_bp *dpa_bp_array[64];
6335 +
6336 +int dpa_max_frm;
6337 +EXPORT_SYMBOL(dpa_max_frm);
6338 +
6339 +int dpa_rx_extra_headroom;
6340 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
6341 +
6342 +int dpa_num_cpus = NR_CPUS;
6343 +
6344 +static const struct fqid_cell tx_confirm_fqids[] = {
6345 + {0, DPAA_ETH_TX_QUEUES}
6346 +};
6347 +
6348 +static struct fqid_cell default_fqids[][3] = {
6349 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
6350 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
6351 +};
6352 +
6353 +static const char fsl_qman_frame_queues[][25] = {
6354 + [RX] = "fsl,qman-frame-queues-rx",
6355 + [TX] = "fsl,qman-frame-queues-tx"
6356 +};
6357 +#ifdef CONFIG_FSL_DPAA_HOOKS
6358 +/* A set of callbacks for hooking into the fastpath at different points. */
6359 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
6360 +EXPORT_SYMBOL(dpaa_eth_hooks);
6361 +/* This function should only be called on the probe paths, since it makes no
6362 + * effort to guarantee consistency of the destination hooks structure.
6363 + */
6364 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
6365 +{
6366 + if (hooks)
6367 + dpaa_eth_hooks = *hooks;
6368 + else
6369 + pr_err("NULL pointer to hooks!\n");
6370 +}
6371 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
6372 +#endif
6373 +
6374 +int dpa_netdev_init(struct net_device *net_dev,
6375 + const uint8_t *mac_addr,
6376 + uint16_t tx_timeout)
6377 +{
6378 + int err;
6379 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6380 + struct device *dev = net_dev->dev.parent;
6381 +
6382 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
6383 +
6384 + net_dev->features |= net_dev->hw_features;
6385 + net_dev->vlan_features = net_dev->features;
6386 +
6387 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
6388 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
6389 +
6390 + net_dev->ethtool_ops = &dpa_ethtool_ops;
6391 +
6392 + net_dev->needed_headroom = priv->tx_headroom;
6393 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
6394 +
6395 + err = register_netdev(net_dev);
6396 + if (err < 0) {
6397 + dev_err(dev, "register_netdev() = %d\n", err);
6398 + return err;
6399 + }
6400 +
6401 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6402 + /* create debugfs entry for this net_device */
6403 + err = dpa_netdev_debugfs_create(net_dev);
6404 + if (err) {
6405 + unregister_netdev(net_dev);
6406 + return err;
6407 + }
6408 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6409 +
6410 + return 0;
6411 +}
6412 +EXPORT_SYMBOL(dpa_netdev_init);
6413 +
6414 +int __cold dpa_start(struct net_device *net_dev)
6415 +{
6416 + int err, i;
6417 + struct dpa_priv_s *priv;
6418 + struct mac_device *mac_dev;
6419 +
6420 + priv = netdev_priv(net_dev);
6421 + mac_dev = priv->mac_dev;
6422 +
6423 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
6424 + if (err < 0) {
6425 + if (netif_msg_ifup(priv))
6426 + netdev_err(net_dev, "init_phy() = %d\n", err);
6427 + return err;
6428 + }
6429 +
6430 + for_each_port_device(i, mac_dev->port_dev) {
6431 + err = fm_port_enable(mac_dev->port_dev[i]);
6432 + if (err)
6433 + goto mac_start_failed;
6434 + }
6435 +
6436 + err = priv->mac_dev->start(mac_dev);
6437 + if (err < 0) {
6438 + if (netif_msg_ifup(priv))
6439 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
6440 + goto mac_start_failed;
6441 + }
6442 +
6443 + netif_tx_start_all_queues(net_dev);
6444 +
6445 + return 0;
6446 +
6447 +mac_start_failed:
6448 + for_each_port_device(i, mac_dev->port_dev)
6449 + fm_port_disable(mac_dev->port_dev[i]);
6450 +
6451 + return err;
6452 +}
6453 +EXPORT_SYMBOL(dpa_start);
6454 +
6455 +int __cold dpa_stop(struct net_device *net_dev)
6456 +{
6457 + int _errno, i, err;
6458 + struct dpa_priv_s *priv;
6459 + struct mac_device *mac_dev;
6460 +
6461 + priv = netdev_priv(net_dev);
6462 + mac_dev = priv->mac_dev;
6463 +
6464 + netif_tx_stop_all_queues(net_dev);
6465 + /* Allow the Fman (Tx) port to process in-flight frames before we
6466 + * try switching it off.
6467 + */
6468 + usleep_range(5000, 10000);
6469 +
6470 + _errno = mac_dev->stop(mac_dev);
6471 + if (unlikely(_errno < 0))
6472 + if (netif_msg_ifdown(priv))
6473 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
6474 + _errno);
6475 +
6476 + for_each_port_device(i, mac_dev->port_dev) {
6477 + err = fm_port_disable(mac_dev->port_dev[i]);
6478 + _errno = err ? err : _errno;
6479 + }
6480 +
6481 + if (mac_dev->phy_dev)
6482 + phy_disconnect(mac_dev->phy_dev);
6483 + mac_dev->phy_dev = NULL;
6484 +
6485 + return _errno;
6486 +}
6487 +EXPORT_SYMBOL(dpa_stop);
6488 +
6489 +void __cold dpa_timeout(struct net_device *net_dev)
6490 +{
6491 + const struct dpa_priv_s *priv;
6492 + struct dpa_percpu_priv_s *percpu_priv;
6493 +
6494 + priv = netdev_priv(net_dev);
6495 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
6496 +
6497 + if (netif_msg_timer(priv))
6498 + netdev_crit(net_dev, "Transmit timeout!\n");
6499 +
6500 + percpu_priv->stats.tx_errors++;
6501 +}
6502 +EXPORT_SYMBOL(dpa_timeout);
6503 +
6504 +/* net_device */
6505 +
6506 +/**
6507 + * @param net_dev the device for which statistics are calculated
6508 + * @param stats the function fills this structure with the device's statistics
6509 + * @return the address of the structure containing the statistics
6510 + *
6511 + * Calculates the statistics for the given device by adding the statistics
6512 + * collected by each CPU.
6513 + */
6514 +struct rtnl_link_stats64 __cold
6515 +*dpa_get_stats64(struct net_device *net_dev,
6516 + struct rtnl_link_stats64 *stats)
6517 +{
6518 + struct dpa_priv_s *priv = netdev_priv(net_dev);
6519 + u64 *cpustats;
6520 + u64 *netstats = (u64 *)stats;
6521 + int i, j;
6522 + struct dpa_percpu_priv_s *percpu_priv;
6523 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
6524 +
6525 + for_each_possible_cpu(i) {
6526 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
6527 +
6528 + cpustats = (u64 *)&percpu_priv->stats;
6529 +
6530 + for (j = 0; j < numstats; j++)
6531 + netstats[j] += cpustats[j];
6532 + }
6533 + return stats;
6534 +}
6535 +EXPORT_SYMBOL(dpa_get_stats64);
6536 +
6537 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu)
6538 +{
6539 + int max_mtu = dpa_get_max_mtu();
6540 +
6541 +#ifndef CONFIG_PPC
6542 + /* Due to the A010022 FMan errata, we can not use contig frames larger
6543 + * than 4K, nor S/G frames. We need to prevent the user from setting a
6544 + * large MTU.
6545 + */
6546 + if (unlikely(dpaa_errata_a010022))
6547 + max_mtu = DPA_BP_RAW_SIZE;
6548 +#endif
6549 +
6550 + /* Make sure we don't exceed the Ethernet controller's MAXFRM */
6551 + if (new_mtu < 68 || new_mtu > max_mtu) {
6552 + netdev_err(net_dev, "Invalid L3 mtu %d (must be between %d and %d).\n",
6553 + new_mtu, 68, max_mtu);
6554 + return -EINVAL;
6555 + }
6556 + net_dev->mtu = new_mtu;
6557 +
6558 + return 0;
6559 +}
6560 +EXPORT_SYMBOL(dpa_change_mtu);
6561 +
6562 +/* .ndo_init callback */
6563 +int dpa_ndo_init(struct net_device *net_dev)
6564 +{
6565 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
6566 + * we choose conservatively and let the user explicitly set a higher
6567 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
6568 + * in the same LAN.
6569 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
6570 + * start with the maximum allowed.
6571 + */
6572 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
6573 +
6574 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
6575 + net_dev->mtu = init_mtu;
6576 +
6577 + return 0;
6578 +}
6579 +EXPORT_SYMBOL(dpa_ndo_init);
6580 +
6581 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
6582 +{
6583 + /* Not much to do here for now */
6584 + dev->features = features;
6585 + return 0;
6586 +}
6587 +EXPORT_SYMBOL(dpa_set_features);
6588 +
6589 +netdev_features_t dpa_fix_features(struct net_device *dev,
6590 + netdev_features_t features)
6591 +{
6592 + netdev_features_t unsupported_features = 0;
6593 +
6594 + /* In theory we should never be requested to enable features that
6595 + * we didn't set in netdev->features and netdev->hw_features at probe
6596 + * time, but double check just to be on the safe side.
6597 + * We don't support enabling Rx csum through ethtool yet
6598 + */
6599 + unsupported_features |= NETIF_F_RXCSUM;
6600 +
6601 + features &= ~unsupported_features;
6602 +
6603 + return features;
6604 +}
6605 +EXPORT_SYMBOL(dpa_fix_features);
6606 +
6607 +#ifdef CONFIG_FSL_DPAA_TS
6608 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
6609 + const void *data)
6610 +{
6611 + u64 *ts, ns;
6612 +
6613 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
6614 + data);
6615 +
6616 + if (!ts || *ts == 0)
6617 + return 0;
6618 +
6619 + be64_to_cpus(ts);
6620 +
6621 + /* multiple DPA_PTP_NOMINAL_FREQ_PERIOD_NS for case of non power of 2 */
6622 + ns = *ts << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT;
6623 +
6624 + return ns;
6625 +}
6626 +
6627 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
6628 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
6629 +{
6630 + u64 ns;
6631 +
6632 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
6633 +
6634 + if (ns == 0)
6635 + return -EINVAL;
6636 +
6637 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
6638 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
6639 +
6640 + return 0;
6641 +}
6642 +
6643 +static void dpa_ts_tx_enable(struct net_device *dev)
6644 +{
6645 + struct dpa_priv_s *priv = netdev_priv(dev);
6646 + struct mac_device *mac_dev = priv->mac_dev;
6647 +
6648 + if (mac_dev->fm_rtc_enable)
6649 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6650 + if (mac_dev->ptp_enable)
6651 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6652 +
6653 + priv->ts_tx_en = true;
6654 +}
6655 +
6656 +static void dpa_ts_tx_disable(struct net_device *dev)
6657 +{
6658 + struct dpa_priv_s *priv = netdev_priv(dev);
6659 +
6660 +#if 0
6661 +/* the RTC might be needed by the Rx Ts, cannot disable here
6662 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6663 + */
6664 + struct mac_device *mac_dev = priv->mac_dev;
6665 +
6666 + if (mac_dev->fm_rtc_disable)
6667 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6668 +
6669 + if (mac_dev->ptp_disable)
6670 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6671 +#endif
6672 +
6673 + priv->ts_tx_en = false;
6674 +}
6675 +
6676 +static void dpa_ts_rx_enable(struct net_device *dev)
6677 +{
6678 + struct dpa_priv_s *priv = netdev_priv(dev);
6679 + struct mac_device *mac_dev = priv->mac_dev;
6680 +
6681 + if (mac_dev->fm_rtc_enable)
6682 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
6683 + if (mac_dev->ptp_enable)
6684 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
6685 +
6686 + priv->ts_rx_en = true;
6687 +}
6688 +
6689 +static void dpa_ts_rx_disable(struct net_device *dev)
6690 +{
6691 + struct dpa_priv_s *priv = netdev_priv(dev);
6692 +
6693 +#if 0
6694 +/* the RTC might be needed by the Tx Ts, cannot disable here
6695 + * no separate ptp_disable API for Rx/Tx, cannot disable here
6696 + */
6697 + struct mac_device *mac_dev = priv->mac_dev;
6698 +
6699 + if (mac_dev->fm_rtc_disable)
6700 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
6701 +
6702 + if (mac_dev->ptp_disable)
6703 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
6704 +#endif
6705 +
6706 + priv->ts_rx_en = false;
6707 +}
6708 +
6709 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6710 +{
6711 + struct hwtstamp_config config;
6712 +
6713 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
6714 + return -EFAULT;
6715 +
6716 + switch (config.tx_type) {
6717 + case HWTSTAMP_TX_OFF:
6718 + dpa_ts_tx_disable(dev);
6719 + break;
6720 + case HWTSTAMP_TX_ON:
6721 + dpa_ts_tx_enable(dev);
6722 + break;
6723 + default:
6724 + return -ERANGE;
6725 + }
6726 +
6727 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
6728 + dpa_ts_rx_disable(dev);
6729 + else {
6730 + dpa_ts_rx_enable(dev);
6731 + /* TS is set for all frame types, not only those requested */
6732 + config.rx_filter = HWTSTAMP_FILTER_ALL;
6733 + }
6734 +
6735 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
6736 + -EFAULT : 0;
6737 +}
6738 +#endif /* CONFIG_FSL_DPAA_TS */
6739 +
6740 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6741 +{
6742 +#ifdef CONFIG_FSL_DPAA_1588
6743 + struct dpa_priv_s *priv = netdev_priv(dev);
6744 +#endif
6745 + int ret = -EINVAL;
6746 +
6747 + if (!netif_running(dev))
6748 + return -EINVAL;
6749 +
6750 + if (cmd == SIOCGMIIREG) {
6751 + if (!dev->phydev)
6752 + ret = -EINVAL;
6753 + else
6754 + ret = phy_mii_ioctl(dev->phydev, rq, cmd);
6755 + }
6756 +
6757 +#ifdef CONFIG_FSL_DPAA_TS
6758 + if (cmd == SIOCSHWTSTAMP)
6759 + return dpa_ts_ioctl(dev, rq, cmd);
6760 +#endif /* CONFIG_FSL_DPAA_TS */
6761 +
6762 +#ifdef CONFIG_FSL_DPAA_1588
6763 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
6764 + if (priv->tsu && priv->tsu->valid)
6765 + ret = dpa_ioctl_1588(dev, rq, cmd);
6766 + else
6767 + ret = -ENODEV;
6768 + }
6769 +#endif
6770 +
6771 + return ret;
6772 +}
6773 +EXPORT_SYMBOL(dpa_ioctl);
6774 +
6775 +int __cold dpa_remove(struct platform_device *of_dev)
6776 +{
6777 + int err;
6778 + struct device *dev;
6779 + struct net_device *net_dev;
6780 + struct dpa_priv_s *priv;
6781 +
6782 + dev = &of_dev->dev;
6783 + net_dev = dev_get_drvdata(dev);
6784 +
6785 + priv = netdev_priv(net_dev);
6786 +
6787 + dpaa_eth_sysfs_remove(dev);
6788 +
6789 + dev_set_drvdata(dev, NULL);
6790 + unregister_netdev(net_dev);
6791 +
6792 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
6793 +
6794 + qman_delete_cgr_safe(&priv->ingress_cgr);
6795 + qman_release_cgrid(priv->ingress_cgr.cgrid);
6796 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
6797 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
6798 +
6799 + dpa_private_napi_del(net_dev);
6800 +
6801 + dpa_bp_free(priv);
6802 +
6803 + if (priv->buf_layout)
6804 + devm_kfree(dev, priv->buf_layout);
6805 +
6806 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
6807 + /* remove debugfs entry for this net_device */
6808 + dpa_netdev_debugfs_remove(net_dev);
6809 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
6810 +
6811 +#ifdef CONFIG_FSL_DPAA_1588
6812 + if (priv->tsu && priv->tsu->valid)
6813 + dpa_ptp_cleanup(priv);
6814 +#endif
6815 +
6816 + free_netdev(net_dev);
6817 +
6818 + return err;
6819 +}
6820 +EXPORT_SYMBOL(dpa_remove);
6821 +
6822 +struct mac_device * __cold __must_check
6823 +__attribute__((nonnull))
6824 +dpa_mac_probe(struct platform_device *_of_dev)
6825 +{
6826 + struct device *dpa_dev, *dev;
6827 + struct device_node *mac_node;
6828 + struct platform_device *of_dev;
6829 + struct mac_device *mac_dev;
6830 +#ifdef CONFIG_FSL_DPAA_1588
6831 + int lenp;
6832 + const phandle *phandle_prop;
6833 + struct net_device *net_dev = NULL;
6834 + struct dpa_priv_s *priv = NULL;
6835 + struct device_node *timer_node;
6836 +#endif
6837 + dpa_dev = &_of_dev->dev;
6838 +
6839 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
6840 + if (unlikely(mac_node == NULL)) {
6841 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
6842 + return ERR_PTR(-EFAULT);
6843 + }
6844 +
6845 + of_dev = of_find_device_by_node(mac_node);
6846 + if (unlikely(of_dev == NULL)) {
6847 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
6848 + mac_node->full_name);
6849 + of_node_put(mac_node);
6850 + return ERR_PTR(-EINVAL);
6851 + }
6852 + of_node_put(mac_node);
6853 +
6854 + dev = &of_dev->dev;
6855 +
6856 + mac_dev = dev_get_drvdata(dev);
6857 + if (unlikely(mac_dev == NULL)) {
6858 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
6859 + dev_name(dev));
6860 + return ERR_PTR(-EINVAL);
6861 + }
6862 +
6863 +#ifdef CONFIG_FSL_DPAA_1588
6864 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
6865 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6866 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6867 + (mac_dev->speed == SPEED_1000)))) {
6868 + timer_node = of_find_node_by_phandle(*phandle_prop);
6869 + if (timer_node)
6870 + net_dev = dev_get_drvdata(dpa_dev);
6871 + if (timer_node && net_dev) {
6872 + priv = netdev_priv(net_dev);
6873 + if (!dpa_ptp_init(priv))
6874 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
6875 + mac_node->full_name);
6876 + }
6877 + }
6878 +#endif
6879 +
6880 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
6881 + if ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
6882 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
6883 + (mac_dev->speed == SPEED_1000))) {
6884 + ptp_priv.node = of_parse_phandle(mac_node, "ptp-timer", 0);
6885 + if (ptp_priv.node) {
6886 + ptp_priv.of_dev = of_find_device_by_node(ptp_priv.node);
6887 + if (unlikely(ptp_priv.of_dev == NULL)) {
6888 + dev_err(dpa_dev,
6889 + "Cannot find device represented by timer_node\n");
6890 + of_node_put(ptp_priv.node);
6891 + return ERR_PTR(-EINVAL);
6892 + }
6893 + ptp_priv.mac_dev = mac_dev;
6894 + }
6895 + }
6896 +#endif
6897 + return mac_dev;
6898 +}
6899 +EXPORT_SYMBOL(dpa_mac_probe);
6900 +
6901 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
6902 +{
6903 + const struct dpa_priv_s *priv;
6904 + int _errno;
6905 + struct mac_device *mac_dev;
6906 +
6907 + priv = netdev_priv(net_dev);
6908 +
6909 + _errno = eth_mac_addr(net_dev, addr);
6910 + if (_errno < 0) {
6911 + if (netif_msg_drv(priv))
6912 + netdev_err(net_dev,
6913 + "eth_mac_addr() = %d\n",
6914 + _errno);
6915 + return _errno;
6916 + }
6917 +
6918 + mac_dev = priv->mac_dev;
6919 +
6920 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
6921 + net_dev->dev_addr);
6922 + if (_errno < 0) {
6923 + if (netif_msg_drv(priv))
6924 + netdev_err(net_dev,
6925 + "mac_dev->change_addr() = %d\n",
6926 + _errno);
6927 + return _errno;
6928 + }
6929 +
6930 + return 0;
6931 +}
6932 +EXPORT_SYMBOL(dpa_set_mac_address);
6933 +
6934 +void dpa_set_rx_mode(struct net_device *net_dev)
6935 +{
6936 + int _errno;
6937 + const struct dpa_priv_s *priv;
6938 +
6939 + priv = netdev_priv(net_dev);
6940 +
6941 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
6942 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
6943 + _errno = priv->mac_dev->set_promisc(
6944 + priv->mac_dev->get_mac_handle(priv->mac_dev),
6945 + priv->mac_dev->promisc);
6946 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6947 + netdev_err(net_dev,
6948 + "mac_dev->set_promisc() = %d\n",
6949 + _errno);
6950 + }
6951 +
6952 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
6953 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
6954 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
6955 +}
6956 +EXPORT_SYMBOL(dpa_set_rx_mode);
6957 +
6958 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
6959 + struct dpa_buffer_layout_s *layout)
6960 +{
6961 + struct fm_port_params params;
6962 +
6963 + /* Rx */
6964 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
6965 + layout[RX].parse_results = true;
6966 + layout[RX].hash_results = true;
6967 +#ifdef CONFIG_FSL_DPAA_TS
6968 + layout[RX].time_stamp = true;
6969 +#endif
6970 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
6971 + layout[RX].manip_extra_space = params.manip_extra_space;
6972 + /* a value of zero for data alignment means "don't care", so align to
6973 + * a non-zero value to prevent FMD from using its own default
6974 + */
6975 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6976 +
6977 + /* Tx */
6978 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
6979 + layout[TX].parse_results = true;
6980 + layout[TX].hash_results = true;
6981 +#ifdef CONFIG_FSL_DPAA_TS
6982 + layout[TX].time_stamp = true;
6983 +#endif
6984 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
6985 + layout[TX].manip_extra_space = params.manip_extra_space;
6986 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
6987 +}
6988 +EXPORT_SYMBOL(dpa_set_buffers_layout);
6989 +
6990 +int __attribute__((nonnull))
6991 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev)
6992 +{
6993 + int err;
6994 + struct bman_pool_params bp_params;
6995 +
6996 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
6997 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
6998 + return -EINVAL;
6999 + }
7000 +
7001 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
7002 +#ifdef CONFIG_FMAN_PFC
7003 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
7004 + bp_params.thresholds[0] = bp_params.thresholds[2] =
7005 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
7006 + bp_params.thresholds[1] = bp_params.thresholds[3] =
7007 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
7008 +#endif
7009 +
7010 + /* If the pool is already specified, we only create one per bpid */
7011 + if (dpa_bpid2pool_use(dpa_bp->bpid))
7012 + return 0;
7013 +
7014 + if (dpa_bp->bpid == 0)
7015 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
7016 + else
7017 + bp_params.bpid = dpa_bp->bpid;
7018 +
7019 + dpa_bp->pool = bman_new_pool(&bp_params);
7020 + if (unlikely(dpa_bp->pool == NULL)) {
7021 + pr_err("bman_new_pool() failed\n");
7022 + return -ENODEV;
7023 + }
7024 +
7025 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
7026 +
7027 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
7028 + if (err) {
7029 + pr_err("dma_coerce_mask_and_coherent() failed\n");
7030 + goto bman_free_pool;
7031 + }
7032 +
7033 + dpa_bp->dev = dev;
7034 +
7035 + if (dpa_bp->seed_cb) {
7036 + err = dpa_bp->seed_cb(dpa_bp);
7037 + if (err)
7038 + goto bman_free_pool;
7039 + }
7040 +
7041 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
7042 +
7043 + return 0;
7044 +
7045 +bman_free_pool:
7046 + bman_free_pool(dpa_bp->pool);
7047 +
7048 + return err;
7049 +}
7050 +EXPORT_SYMBOL(dpa_bp_alloc);
7051 +
7052 +void dpa_bp_drain(struct dpa_bp *bp)
7053 +{
7054 + int ret, num = 8;
7055 +
7056 + do {
7057 + struct bm_buffer bmb[8];
7058 + int i;
7059 +
7060 + ret = bman_acquire(bp->pool, bmb, num, 0);
7061 + if (ret < 0) {
7062 + if (num == 8) {
7063 + /* we have less than 8 buffers left;
7064 + * drain them one by one
7065 + */
7066 + num = 1;
7067 + ret = 1;
7068 + continue;
7069 + } else {
7070 + /* Pool is fully drained */
7071 + break;
7072 + }
7073 + }
7074 +
7075 + for (i = 0; i < num; i++) {
7076 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
7077 +
7078 + dma_unmap_single(bp->dev, addr, bp->size,
7079 + DMA_BIDIRECTIONAL);
7080 +
7081 + bp->free_buf_cb(phys_to_virt(addr));
7082 + }
7083 + } while (ret > 0);
7084 +}
7085 +EXPORT_SYMBOL(dpa_bp_drain);
7086 +
7087 +static void __cold __attribute__((nonnull))
7088 +_dpa_bp_free(struct dpa_bp *dpa_bp)
7089 +{
7090 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
7091 +
7092 + /* the mapping between bpid and dpa_bp is done very late in the
7093 + * allocation procedure; if something failed before the mapping, the bp
7094 + * was not configured, therefore we don't need the below instructions
7095 + */
7096 + if (!bp)
7097 + return;
7098 +
7099 + if (!atomic_dec_and_test(&bp->refs))
7100 + return;
7101 +
7102 + if (bp->free_buf_cb)
7103 + dpa_bp_drain(bp);
7104 +
7105 + dpa_bp_array[bp->bpid] = NULL;
7106 + bman_free_pool(bp->pool);
7107 +}
7108 +
7109 +void __cold __attribute__((nonnull))
7110 +dpa_bp_free(struct dpa_priv_s *priv)
7111 +{
7112 + int i;
7113 +
7114 + if (priv->dpa_bp)
7115 + for (i = 0; i < priv->bp_count; i++)
7116 + _dpa_bp_free(&priv->dpa_bp[i]);
7117 +}
7118 +EXPORT_SYMBOL(dpa_bp_free);
7119 +
7120 +struct dpa_bp *dpa_bpid2pool(int bpid)
7121 +{
7122 + return dpa_bp_array[bpid];
7123 +}
7124 +EXPORT_SYMBOL(dpa_bpid2pool);
7125 +
7126 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
7127 +{
7128 + dpa_bp_array[bpid] = dpa_bp;
7129 + atomic_set(&dpa_bp->refs, 1);
7130 +}
7131 +
7132 +bool dpa_bpid2pool_use(int bpid)
7133 +{
7134 + if (dpa_bpid2pool(bpid)) {
7135 + atomic_inc(&dpa_bp_array[bpid]->refs);
7136 + return true;
7137 + }
7138 +
7139 + return false;
7140 +}
7141 +
7142 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
7143 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
7144 + void *accel_priv, select_queue_fallback_t fallback)
7145 +{
7146 + return dpa_get_queue_mapping(skb);
7147 +}
7148 +EXPORT_SYMBOL(dpa_select_queue);
7149 +#endif
7150 +
7151 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
7152 + u32 fq_start,
7153 + u32 fq_count,
7154 + struct list_head *list,
7155 + enum dpa_fq_type fq_type)
7156 +{
7157 + int i;
7158 + struct dpa_fq *dpa_fq;
7159 +
7160 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
7161 + if (dpa_fq == NULL)
7162 + return NULL;
7163 +
7164 + for (i = 0; i < fq_count; i++) {
7165 + dpa_fq[i].fq_type = fq_type;
7166 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
7167 + dpa_fq[i].fqid = fq_start ?
7168 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
7169 + else
7170 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
7171 +
7172 + list_add_tail(&dpa_fq[i].list, list);
7173 + }
7174 +
7175 +#ifdef CONFIG_FMAN_PFC
7176 + if (fq_type == FQ_TYPE_TX)
7177 + for (i = 0; i < fq_count; i++)
7178 + dpa_fq[i].wq = i / dpa_num_cpus;
7179 + else
7180 +#endif
7181 + for (i = 0; i < fq_count; i++)
7182 + _dpa_assign_wq(dpa_fq + i);
7183 +
7184 + return dpa_fq;
7185 +}
7186 +EXPORT_SYMBOL(dpa_fq_alloc);
7187 +
7188 +/* Probing of FQs for MACful ports */
7189 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
7190 + struct fm_port_fqs *port_fqs,
7191 + bool alloc_tx_conf_fqs,
7192 + enum port_type ptype)
7193 +{
7194 + struct fqid_cell *fqids = NULL;
7195 + const void *fqids_off = NULL;
7196 + struct dpa_fq *dpa_fq = NULL;
7197 + struct device_node *np = dev->of_node;
7198 + int num_ranges;
7199 + int i, lenp;
7200 +
7201 + if (ptype == TX && alloc_tx_conf_fqs) {
7202 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
7203 + tx_confirm_fqids->count, list,
7204 + FQ_TYPE_TX_CONF_MQ))
7205 + goto fq_alloc_failed;
7206 + }
7207 +
7208 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
7209 + if (fqids_off == NULL) {
7210 + /* No dts definition, so use the defaults. */
7211 + fqids = default_fqids[ptype];
7212 + num_ranges = 3;
7213 + } else {
7214 + num_ranges = lenp / sizeof(*fqids);
7215 +
7216 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
7217 + GFP_KERNEL);
7218 + if (fqids == NULL)
7219 + goto fqids_alloc_failed;
7220 +
7221 + /* convert to CPU endianess */
7222 + for (i = 0; i < num_ranges; i++) {
7223 + fqids[i].start = be32_to_cpup(fqids_off +
7224 + i * sizeof(*fqids));
7225 + fqids[i].count = be32_to_cpup(fqids_off +
7226 + i * sizeof(*fqids) + sizeof(__be32));
7227 + }
7228 + }
7229 +
7230 + for (i = 0; i < num_ranges; i++) {
7231 + switch (i) {
7232 + case 0:
7233 + /* The first queue is the error queue */
7234 + if (fqids[i].count != 1)
7235 + goto invalid_error_queue;
7236 +
7237 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7238 + fqids[i].count, list,
7239 + ptype == RX ?
7240 + FQ_TYPE_RX_ERROR :
7241 + FQ_TYPE_TX_ERROR);
7242 + if (dpa_fq == NULL)
7243 + goto fq_alloc_failed;
7244 +
7245 + if (ptype == RX)
7246 + port_fqs->rx_errq = &dpa_fq[0];
7247 + else
7248 + port_fqs->tx_errq = &dpa_fq[0];
7249 + break;
7250 + case 1:
7251 + /* the second queue is the default queue */
7252 + if (fqids[i].count != 1)
7253 + goto invalid_default_queue;
7254 +
7255 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
7256 + fqids[i].count, list,
7257 + ptype == RX ?
7258 + FQ_TYPE_RX_DEFAULT :
7259 + FQ_TYPE_TX_CONFIRM);
7260 + if (dpa_fq == NULL)
7261 + goto fq_alloc_failed;
7262 +
7263 + if (ptype == RX)
7264 + port_fqs->rx_defq = &dpa_fq[0];
7265 + else
7266 + port_fqs->tx_defq = &dpa_fq[0];
7267 + break;
7268 + default:
7269 + /* all subsequent queues are either RX* PCD or Tx */
7270 + if (ptype == RX) {
7271 + if (!dpa_fq_alloc(dev, fqids[i].start,
7272 + fqids[i].count, list,
7273 + FQ_TYPE_RX_PCD) ||
7274 + !dpa_fq_alloc(dev, fqids[i].start,
7275 + fqids[i].count, list,
7276 + FQ_TYPE_RX_PCD_HI_PRIO))
7277 + goto fq_alloc_failed;
7278 + } else {
7279 + if (!dpa_fq_alloc(dev, fqids[i].start,
7280 + fqids[i].count, list,
7281 + FQ_TYPE_TX))
7282 + goto fq_alloc_failed;
7283 + }
7284 + break;
7285 + }
7286 + }
7287 +
7288 + return 0;
7289 +
7290 +fq_alloc_failed:
7291 +fqids_alloc_failed:
7292 + dev_err(dev, "Cannot allocate memory for frame queues\n");
7293 + return -ENOMEM;
7294 +
7295 +invalid_default_queue:
7296 +invalid_error_queue:
7297 + dev_err(dev, "Too many default or error queues\n");
7298 + return -EINVAL;
7299 +}
7300 +EXPORT_SYMBOL(dpa_fq_probe_mac);
7301 +
7302 +static u32 rx_pool_channel;
7303 +static DEFINE_SPINLOCK(rx_pool_channel_init);
7304 +
7305 +int dpa_get_channel(void)
7306 +{
7307 + spin_lock(&rx_pool_channel_init);
7308 + if (!rx_pool_channel) {
7309 + u32 pool;
7310 + int ret = qman_alloc_pool(&pool);
7311 + if (!ret)
7312 + rx_pool_channel = pool;
7313 + }
7314 + spin_unlock(&rx_pool_channel_init);
7315 + if (!rx_pool_channel)
7316 + return -ENOMEM;
7317 + return rx_pool_channel;
7318 +}
7319 +EXPORT_SYMBOL(dpa_get_channel);
7320 +
7321 +void dpa_release_channel(void)
7322 +{
7323 + qman_release_pool(rx_pool_channel);
7324 +}
7325 +EXPORT_SYMBOL(dpa_release_channel);
7326 +
7327 +void dpaa_eth_add_channel(u16 channel)
7328 +{
7329 + const cpumask_t *cpus = qman_affine_cpus();
7330 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
7331 + int cpu;
7332 + struct qman_portal *portal;
7333 +
7334 + for_each_cpu(cpu, cpus) {
7335 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
7336 + qman_p_static_dequeue_add(portal, pool);
7337 + }
7338 +}
7339 +EXPORT_SYMBOL(dpaa_eth_add_channel);
7340 +
7341 +/**
7342 + * Congestion group state change notification callback.
7343 + * Stops the device's egress queues while they are congested and
7344 + * wakes them upon exiting congested state.
7345 + * Also updates some CGR-related stats.
7346 + */
7347 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
7348 +
7349 + int congested)
7350 +{
7351 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
7352 + struct dpa_priv_s, cgr_data.cgr);
7353 +
7354 + if (congested) {
7355 + priv->cgr_data.congestion_start_jiffies = jiffies;
7356 + netif_tx_stop_all_queues(priv->net_dev);
7357 + priv->cgr_data.cgr_congested_count++;
7358 + } else {
7359 + priv->cgr_data.congested_jiffies +=
7360 + (jiffies - priv->cgr_data.congestion_start_jiffies);
7361 + netif_tx_wake_all_queues(priv->net_dev);
7362 + }
7363 +}
7364 +
7365 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
7366 +{
7367 + struct qm_mcc_initcgr initcgr;
7368 + u32 cs_th;
7369 + int err;
7370 +
7371 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
7372 + if (err < 0) {
7373 + pr_err("Error %d allocating CGR ID\n", err);
7374 + goto out_error;
7375 + }
7376 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
7377 +
7378 + /* Enable Congestion State Change Notifications and CS taildrop */
7379 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
7380 + initcgr.cgr.cscn_en = QM_CGR_EN;
7381 +
7382 + /* Set different thresholds based on the MAC speed.
7383 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
7384 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
7385 + * In such cases, we ought to reconfigure the threshold, too.
7386 + */
7387 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
7388 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
7389 + else
7390 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
7391 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
7392 +
7393 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
7394 + initcgr.cgr.cstd_en = QM_CGR_EN;
7395 +
7396 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
7397 + &initcgr);
7398 + if (err < 0) {
7399 + pr_err("Error %d creating CGR with ID %d\n", err,
7400 + priv->cgr_data.cgr.cgrid);
7401 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
7402 + goto out_error;
7403 + }
7404 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
7405 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
7406 + priv->cgr_data.cgr.chan);
7407 +
7408 +out_error:
7409 + return err;
7410 +}
7411 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
7412 +
7413 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
7414 + struct dpa_fq *fq,
7415 + const struct qman_fq *template)
7416 +{
7417 + fq->fq_base = *template;
7418 + fq->net_dev = priv->net_dev;
7419 +
7420 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
7421 + fq->channel = priv->channel;
7422 +}
7423 +
7424 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
7425 + struct dpa_fq *fq,
7426 + struct fm_port *port,
7427 + const struct qman_fq *template)
7428 +{
7429 + fq->fq_base = *template;
7430 + fq->net_dev = priv->net_dev;
7431 +
7432 + if (port) {
7433 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
7434 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
7435 + } else {
7436 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
7437 + }
7438 +}
7439 +
7440 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
7441 + struct fm_port *tx_port)
7442 +{
7443 + struct dpa_fq *fq;
7444 + uint16_t portals[NR_CPUS];
7445 + int cpu, portal_cnt = 0, num_portals = 0;
7446 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
7447 + const cpumask_t *affine_cpus = qman_affine_cpus();
7448 + int egress_cnt = 0, conf_cnt = 0;
7449 +
7450 + /* Prepare for PCD FQs init */
7451 + for_each_cpu(cpu, affine_cpus)
7452 + portals[num_portals++] = qman_affine_channel(cpu);
7453 + if (num_portals == 0)
7454 + dev_err(priv->net_dev->dev.parent,
7455 + "No Qman software (affine) channels found");
7456 +
7457 + pcd_fqid = (priv->mac_dev) ?
7458 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
7459 + pcd_fqid_hi_prio = (priv->mac_dev) ?
7460 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
7461 +
7462 + /* Initialize each FQ in the list */
7463 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7464 + switch (fq->fq_type) {
7465 + case FQ_TYPE_RX_DEFAULT:
7466 + BUG_ON(!priv->mac_dev);
7467 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7468 + break;
7469 + case FQ_TYPE_RX_ERROR:
7470 + BUG_ON(!priv->mac_dev);
7471 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
7472 + break;
7473 + case FQ_TYPE_RX_PCD:
7474 + /* For MACless we can't have dynamic Rx queues */
7475 + BUG_ON(!priv->mac_dev && !fq->fqid);
7476 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7477 + if (!fq->fqid)
7478 + fq->fqid = pcd_fqid++;
7479 + fq->channel = portals[portal_cnt];
7480 + portal_cnt = (portal_cnt + 1) % num_portals;
7481 + break;
7482 + case FQ_TYPE_RX_PCD_HI_PRIO:
7483 + /* For MACless we can't have dynamic Hi Pri Rx queues */
7484 + BUG_ON(!priv->mac_dev && !fq->fqid);
7485 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
7486 + if (!fq->fqid)
7487 + fq->fqid = pcd_fqid_hi_prio++;
7488 + fq->channel = portals[portal_cnt];
7489 + portal_cnt = (portal_cnt + 1) % num_portals;
7490 + break;
7491 + case FQ_TYPE_TX:
7492 + dpa_setup_egress(priv, fq, tx_port,
7493 + &fq_cbs->egress_ern);
7494 + /* If we have more Tx queues than the number of cores,
7495 + * just ignore the extra ones.
7496 + */
7497 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
7498 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7499 + break;
7500 + case FQ_TYPE_TX_CONFIRM:
7501 + BUG_ON(!priv->mac_dev);
7502 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7503 + break;
7504 + case FQ_TYPE_TX_CONF_MQ:
7505 + BUG_ON(!priv->mac_dev);
7506 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
7507 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
7508 + break;
7509 + case FQ_TYPE_TX_ERROR:
7510 + BUG_ON(!priv->mac_dev);
7511 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
7512 + break;
7513 + default:
7514 + dev_warn(priv->net_dev->dev.parent,
7515 + "Unknown FQ type detected!\n");
7516 + break;
7517 + }
7518 + }
7519 +
7520 + /* The number of Tx queues may be smaller than the number of cores, if
7521 + * the Tx queue range is specified in the device tree instead of being
7522 + * dynamically allocated.
7523 + * Make sure all CPUs receive a corresponding Tx queue.
7524 + */
7525 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
7526 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
7527 + if (fq->fq_type != FQ_TYPE_TX)
7528 + continue;
7529 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
7530 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
7531 + break;
7532 + }
7533 + }
7534 +}
7535 +EXPORT_SYMBOL(dpa_fq_setup);
7536 +
7537 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
7538 +{
7539 + int _errno;
7540 + const struct dpa_priv_s *priv;
7541 + struct device *dev;
7542 + struct qman_fq *fq;
7543 + struct qm_mcc_initfq initfq;
7544 + struct qman_fq *confq;
7545 + int queue_id;
7546 +
7547 + priv = netdev_priv(dpa_fq->net_dev);
7548 + dev = dpa_fq->net_dev->dev.parent;
7549 +
7550 + if (dpa_fq->fqid == 0)
7551 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
7552 +
7553 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
7554 +
7555 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
7556 + if (_errno) {
7557 + dev_err(dev, "qman_create_fq() failed\n");
7558 + return _errno;
7559 + }
7560 + fq = &dpa_fq->fq_base;
7561 +
7562 + if (dpa_fq->init) {
7563 + memset(&initfq, 0, sizeof(initfq));
7564 +
7565 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
7566 + /* FIXME: why would we want to keep an empty FQ in cache? */
7567 + initfq.fqd.fq_ctrl = QM_FQCTRL_PREFERINCACHE;
7568 +
7569 + /* Try to reduce the number of portal interrupts for
7570 + * Tx Confirmation FQs.
7571 + */
7572 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
7573 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
7574 +
7575 + /* FQ placement */
7576 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
7577 +
7578 + initfq.fqd.dest.channel = dpa_fq->channel;
7579 + initfq.fqd.dest.wq = dpa_fq->wq;
7580 +
7581 + /* Put all egress queues in a congestion group of their own.
7582 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
7583 + * rather than Tx - but they nonetheless account for the
7584 + * memory footprint on behalf of egress traffic. We therefore
7585 + * place them in the netdev's CGR, along with the Tx FQs.
7586 + */
7587 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
7588 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
7589 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
7590 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7591 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7592 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
7593 + /* Set a fixed overhead accounting, in an attempt to
7594 + * reduce the impact of fixed-size skb shells and the
7595 + * driver's needed headroom on system memory. This is
7596 + * especially the case when the egress traffic is
7597 + * composed of small datagrams.
7598 + * Unfortunately, QMan's OAL value is capped to an
7599 + * insufficient value, but even that is better than
7600 + * no overhead accounting at all.
7601 + */
7602 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7603 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7604 + initfq.fqd.oac_init.oal =
7605 + (signed char)(min(sizeof(struct sk_buff) +
7606 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7607 + }
7608 +
7609 + if (td_enable) {
7610 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
7611 + qm_fqd_taildrop_set(&initfq.fqd.td,
7612 + DPA_FQ_TD, 1);
7613 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
7614 + }
7615 +
7616 + /* Configure the Tx confirmation queue, now that we know
7617 + * which Tx queue it pairs with.
7618 + */
7619 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
7620 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
7621 + if (queue_id >= 0) {
7622 + confq = priv->conf_fqs[queue_id];
7623 + if (confq) {
7624 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7625 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
7626 + * A2V=1 (contextA A2 field is valid)
7627 + * A0V=1 (contextA A0 field is valid)
7628 + * B0V=1 (contextB field is valid)
7629 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
7630 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
7631 + */
7632 + initfq.fqd.context_a.hi = 0x1e000000;
7633 + initfq.fqd.context_a.lo = 0x80000000;
7634 + }
7635 + }
7636 + }
7637 +
7638 + /* Put all *private* ingress queues in our "ingress CGR". */
7639 + if (priv->use_ingress_cgr &&
7640 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
7641 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
7642 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
7643 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
7644 + initfq.we_mask |= QM_INITFQ_WE_CGID;
7645 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
7646 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
7647 + /* Set a fixed overhead accounting, just like for the
7648 + * egress CGR.
7649 + */
7650 + initfq.we_mask |= QM_INITFQ_WE_OAC;
7651 + initfq.fqd.oac_init.oac = QM_OAC_CG;
7652 + initfq.fqd.oac_init.oal =
7653 + (signed char)(min(sizeof(struct sk_buff) +
7654 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
7655 + }
7656 +
7657 + /* Initialization common to all ingress queues */
7658 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
7659 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
7660 + initfq.fqd.fq_ctrl |=
7661 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
7662 + initfq.fqd.context_a.stashing.exclusive =
7663 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
7664 + QM_STASHING_EXCL_ANNOTATION;
7665 + initfq.fqd.context_a.stashing.data_cl = 2;
7666 + initfq.fqd.context_a.stashing.annotation_cl = 1;
7667 + initfq.fqd.context_a.stashing.context_cl =
7668 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
7669 + }
7670 +
7671 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
7672 + if (_errno < 0) {
7673 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
7674 + dpa_fq->init = 0;
7675 + } else {
7676 + dev_err(dev, "qman_init_fq(%u) = %d\n",
7677 + qman_fq_fqid(fq), _errno);
7678 + qman_destroy_fq(fq, 0);
7679 + }
7680 + return _errno;
7681 + }
7682 + }
7683 +
7684 + dpa_fq->fqid = qman_fq_fqid(fq);
7685 +
7686 + return 0;
7687 +}
7688 +EXPORT_SYMBOL(dpa_fq_init);
7689 +
7690 +int __cold __attribute__((nonnull))
7691 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
7692 +{
7693 + int _errno, __errno;
7694 + struct dpa_fq *dpa_fq;
7695 + const struct dpa_priv_s *priv;
7696 +
7697 + _errno = 0;
7698 +
7699 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
7700 + priv = netdev_priv(dpa_fq->net_dev);
7701 +
7702 + if (dpa_fq->init) {
7703 + _errno = qman_retire_fq(fq, NULL);
7704 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
7705 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
7706 + qman_fq_fqid(fq), _errno);
7707 +
7708 + __errno = qman_oos_fq(fq);
7709 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
7710 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
7711 + qman_fq_fqid(fq), __errno);
7712 + if (_errno >= 0)
7713 + _errno = __errno;
7714 + }
7715 + }
7716 +
7717 + qman_destroy_fq(fq, 0);
7718 + list_del(&dpa_fq->list);
7719 +
7720 + return _errno;
7721 +}
7722 +EXPORT_SYMBOL(_dpa_fq_free);
7723 +
7724 +int __cold __attribute__((nonnull))
7725 +dpa_fq_free(struct device *dev, struct list_head *list)
7726 +{
7727 + int _errno, __errno;
7728 + struct dpa_fq *dpa_fq, *tmp;
7729 +
7730 + _errno = 0;
7731 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7732 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
7733 + if (unlikely(__errno < 0) && _errno >= 0)
7734 + _errno = __errno;
7735 + }
7736 +
7737 + return _errno;
7738 +}
7739 +EXPORT_SYMBOL(dpa_fq_free);
7740 +
7741 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
7742 +{
7743 + int _errno, __errno;
7744 + struct dpa_fq *dpa_fq, *tmp;
7745 + static bool print_msg __read_mostly;
7746 +
7747 + _errno = 0;
7748 + print_msg = true;
7749 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
7750 + __errno = dpa_fq_init(dpa_fq, td_enable);
7751 + if (unlikely(__errno < 0) && _errno >= 0) {
7752 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
7753 + if (print_msg) {
7754 + dev_warn(dev,
7755 + "Skip RX PCD High Priority FQs initialization\n");
7756 + print_msg = false;
7757 + }
7758 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
7759 + dev_warn(dev,
7760 + "Error freeing frame queues\n");
7761 + } else {
7762 + _errno = __errno;
7763 + break;
7764 + }
7765 + }
7766 + }
7767 +
7768 + return _errno;
7769 +}
7770 +EXPORT_SYMBOL(dpa_fqs_init);
7771 +static void
7772 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
7773 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
7774 +{
7775 + struct fm_port_params tx_port_param;
7776 + bool frag_enabled = false;
7777 +
7778 + memset(&tx_port_param, 0, sizeof(tx_port_param));
7779 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
7780 + buf_layout, frag_enabled);
7781 +}
7782 +
7783 +static void
7784 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
7785 + struct dpa_fq *errq, struct dpa_fq *defq,
7786 + struct dpa_buffer_layout_s *buf_layout)
7787 +{
7788 + struct fm_port_params rx_port_param;
7789 + int i;
7790 + bool frag_enabled = false;
7791 +
7792 + memset(&rx_port_param, 0, sizeof(rx_port_param));
7793 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
7794 + rx_port_param.num_pools = (uint8_t)count;
7795 + for (i = 0; i < count; i++) {
7796 + if (i >= rx_port_param.num_pools)
7797 + break;
7798 + rx_port_param.pool_param[i].id = bp[i].bpid;
7799 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
7800 + }
7801 +
7802 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
7803 + buf_layout, frag_enabled);
7804 +}
7805 +
7806 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
7807 +/* Defined as weak, to be implemented by fman pcd tester. */
7808 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
7809 +__attribute__((weak));
7810 +
7811 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
7812 +#else
7813 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
7814 +
7815 +int dpa_free_pcd_fqids(struct device *, uint32_t);
7816 +
7817 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
7818 +
7819 +
7820 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
7821 + uint8_t alignment, uint32_t *base_fqid)
7822 +{
7823 + dev_crit(dev, "callback not implemented!\n");
7824 +
7825 + return 0;
7826 +}
7827 +
7828 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
7829 +{
7830 +
7831 + dev_crit(dev, "callback not implemented!\n");
7832 +
7833 + return 0;
7834 +}
7835 +
7836 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
7837 + struct dpa_bp *bp, size_t count,
7838 + struct fm_port_fqs *port_fqs,
7839 + struct dpa_buffer_layout_s *buf_layout,
7840 + struct device *dev)
7841 +{
7842 + struct fm_port_pcd_param rx_port_pcd_param;
7843 + struct fm_port *rxport = mac_dev->port_dev[RX];
7844 + struct fm_port *txport = mac_dev->port_dev[TX];
7845 +
7846 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
7847 + port_fqs->tx_defq, &buf_layout[TX]);
7848 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
7849 + port_fqs->rx_defq, &buf_layout[RX]);
7850 +
7851 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
7852 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
7853 + rx_port_pcd_param.dev = dev;
7854 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
7855 +}
7856 +EXPORT_SYMBOL(dpaa_eth_init_ports);
7857 +
7858 +void dpa_release_sgt(struct qm_sg_entry *sgt)
7859 +{
7860 + struct dpa_bp *dpa_bp;
7861 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
7862 + uint8_t i = 0, j;
7863 +
7864 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
7865 +
7866 + do {
7867 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
7868 + DPA_BUG_ON(!dpa_bp);
7869 +
7870 + j = 0;
7871 + do {
7872 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
7873 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
7874 +
7875 + j++; i++;
7876 + } while (j < ARRAY_SIZE(bmb) &&
7877 + !qm_sg_entry_get_final(&sgt[i-1]) &&
7878 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
7879 + qm_sg_entry_get_bpid(&sgt[i]));
7880 +
7881 + while (bman_release(dpa_bp->pool, bmb, j, 0))
7882 + cpu_relax();
7883 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
7884 +}
7885 +EXPORT_SYMBOL(dpa_release_sgt);
7886 +
7887 +void __attribute__((nonnull))
7888 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
7889 +{
7890 + struct qm_sg_entry *sgt;
7891 + struct dpa_bp *dpa_bp;
7892 + struct bm_buffer bmb;
7893 + dma_addr_t addr;
7894 + void *vaddr;
7895 +
7896 + bmb.opaque = 0;
7897 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
7898 +
7899 + dpa_bp = dpa_bpid2pool(fd->bpid);
7900 + DPA_BUG_ON(!dpa_bp);
7901 +
7902 + if (fd->format == qm_fd_sg) {
7903 + vaddr = phys_to_virt(qm_fd_addr(fd));
7904 + sgt = vaddr + dpa_fd_offset(fd);
7905 +
7906 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
7907 + DMA_BIDIRECTIONAL);
7908 +
7909 + dpa_release_sgt(sgt);
7910 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
7911 + DMA_BIDIRECTIONAL);
7912 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
7913 + dev_err(dpa_bp->dev, "DMA mapping failed");
7914 + return;
7915 + }
7916 + bm_buffer_set64(&bmb, addr);
7917 + }
7918 +
7919 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
7920 + cpu_relax();
7921 +}
7922 +EXPORT_SYMBOL(dpa_fd_release);
7923 +
7924 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
7925 + const struct qm_mr_entry *msg)
7926 +{
7927 + switch (msg->ern.rc & QM_MR_RC_MASK) {
7928 + case QM_MR_RC_CGR_TAILDROP:
7929 + percpu_priv->ern_cnt.cg_tdrop++;
7930 + break;
7931 + case QM_MR_RC_WRED:
7932 + percpu_priv->ern_cnt.wred++;
7933 + break;
7934 + case QM_MR_RC_ERROR:
7935 + percpu_priv->ern_cnt.err_cond++;
7936 + break;
7937 + case QM_MR_RC_ORPWINDOW_EARLY:
7938 + percpu_priv->ern_cnt.early_window++;
7939 + break;
7940 + case QM_MR_RC_ORPWINDOW_LATE:
7941 + percpu_priv->ern_cnt.late_window++;
7942 + break;
7943 + case QM_MR_RC_FQ_TAILDROP:
7944 + percpu_priv->ern_cnt.fq_tdrop++;
7945 + break;
7946 + case QM_MR_RC_ORPWINDOW_RETIRED:
7947 + percpu_priv->ern_cnt.fq_retired++;
7948 + break;
7949 + case QM_MR_RC_ORP_ZERO:
7950 + percpu_priv->ern_cnt.orp_zero++;
7951 + break;
7952 + }
7953 +}
7954 +EXPORT_SYMBOL(count_ern);
7955 +
7956 +/**
7957 + * Turn on HW checksum computation for this outgoing frame.
7958 + * If the current protocol is not something we support in this regard
7959 + * (or if the stack has already computed the SW checksum), we do nothing.
7960 + *
7961 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
7962 + * otherwise.
7963 + *
7964 + * Note that this function may modify the fd->cmd field and the skb data buffer
7965 + * (the Parse Results area).
7966 + */
7967 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
7968 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
7969 +{
7970 + fm_prs_result_t *parse_result;
7971 + struct iphdr *iph;
7972 + struct ipv6hdr *ipv6h = NULL;
7973 + u8 l4_proto;
7974 + u16 ethertype = ntohs(skb->protocol);
7975 + int retval = 0;
7976 +
7977 + if (skb->ip_summed != CHECKSUM_PARTIAL)
7978 + return 0;
7979 +
7980 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
7981 + * L4 alone from the FM configuration anyway.
7982 + */
7983 +
7984 + /* Fill in some fields of the Parse Results array, so the FMan
7985 + * can find them as if they came from the FMan Parser.
7986 + */
7987 + parse_result = (fm_prs_result_t *)parse_results;
7988 +
7989 + /* If we're dealing with VLAN, get the real Ethernet type */
7990 + if (ethertype == ETH_P_8021Q) {
7991 + /* We can't always assume the MAC header is set correctly
7992 + * by the stack, so reset to beginning of skb->data
7993 + */
7994 + skb_reset_mac_header(skb);
7995 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
7996 + }
7997 +
7998 + /* Fill in the relevant L3 parse result fields
7999 + * and read the L4 protocol type
8000 + */
8001 + switch (ethertype) {
8002 + case ETH_P_IP:
8003 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
8004 + iph = ip_hdr(skb);
8005 + DPA_BUG_ON(iph == NULL);
8006 + l4_proto = iph->protocol;
8007 + break;
8008 + case ETH_P_IPV6:
8009 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
8010 + ipv6h = ipv6_hdr(skb);
8011 + DPA_BUG_ON(ipv6h == NULL);
8012 + l4_proto = ipv6h->nexthdr;
8013 + break;
8014 + default:
8015 + /* We shouldn't even be here */
8016 + if (netif_msg_tx_err(priv) && net_ratelimit())
8017 + netdev_alert(priv->net_dev,
8018 + "Can't compute HW csum for L3 proto 0x%x\n",
8019 + ntohs(skb->protocol));
8020 + retval = -EIO;
8021 + goto return_error;
8022 + }
8023 +
8024 + /* Fill in the relevant L4 parse result fields */
8025 + switch (l4_proto) {
8026 + case IPPROTO_UDP:
8027 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
8028 + break;
8029 + case IPPROTO_TCP:
8030 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
8031 + break;
8032 + default:
8033 + /* This can as well be a BUG() */
8034 + if (netif_msg_tx_err(priv) && net_ratelimit())
8035 + netdev_alert(priv->net_dev,
8036 + "Can't compute HW csum for L4 proto 0x%x\n",
8037 + l4_proto);
8038 + retval = -EIO;
8039 + goto return_error;
8040 + }
8041 +
8042 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
8043 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
8044 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
8045 +
8046 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
8047 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
8048 +
8049 + /* On P1023 and similar platforms fd->cmd interpretation could
8050 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
8051 + * is not set so we do not need to check; in the future, if/when
8052 + * using context_a we need to check this bit
8053 + */
8054 +
8055 +return_error:
8056 + return retval;
8057 +}
8058 +EXPORT_SYMBOL(dpa_enable_tx_csum);
8059 +
8060 +#ifdef CONFIG_FSL_DPAA_CEETM
8061 +void dpa_enable_ceetm(struct net_device *dev)
8062 +{
8063 + struct dpa_priv_s *priv = netdev_priv(dev);
8064 + priv->ceetm_en = true;
8065 +}
8066 +EXPORT_SYMBOL(dpa_enable_ceetm);
8067 +
8068 +void dpa_disable_ceetm(struct net_device *dev)
8069 +{
8070 + struct dpa_priv_s *priv = netdev_priv(dev);
8071 + priv->ceetm_en = false;
8072 +}
8073 +EXPORT_SYMBOL(dpa_disable_ceetm);
8074 +#endif
8075 --- /dev/null
8076 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
8077 @@ -0,0 +1,225 @@
8078 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
8079 + *
8080 + * Redistribution and use in source and binary forms, with or without
8081 + * modification, are permitted provided that the following conditions are met:
8082 + * * Redistributions of source code must retain the above copyright
8083 + * notice, this list of conditions and the following disclaimer.
8084 + * * Redistributions in binary form must reproduce the above copyright
8085 + * notice, this list of conditions and the following disclaimer in the
8086 + * documentation and/or other materials provided with the distribution.
8087 + * * Neither the name of Freescale Semiconductor nor the
8088 + * names of its contributors may be used to endorse or promote products
8089 + * derived from this software without specific prior written permission.
8090 + *
8091 + *
8092 + * ALTERNATIVELY, this software may be distributed under the terms of the
8093 + * GNU General Public License ("GPL") as published by the Free Software
8094 + * Foundation, either version 2 of that License or (at your option) any
8095 + * later version.
8096 + *
8097 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8098 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8099 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8100 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8101 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8102 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8103 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8104 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8105 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8106 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8107 + */
8108 +
8109 +#ifndef __DPAA_ETH_COMMON_H
8110 +#define __DPAA_ETH_COMMON_H
8111 +
8112 +#include <linux/etherdevice.h> /* struct net_device */
8113 +#include <linux/fsl_bman.h> /* struct bm_buffer */
8114 +#include <linux/of_platform.h> /* struct platform_device */
8115 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
8116 +
8117 +#include "dpaa_eth.h"
8118 +#include "lnxwrp_fsl_fman.h"
8119 +
8120 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
8121 + frag_enabled) \
8122 +{ \
8123 + param.errq = errq_id; \
8124 + param.defq = defq_id; \
8125 + param.priv_data_size = buf_layout->priv_data_size; \
8126 + param.parse_results = buf_layout->parse_results; \
8127 + param.hash_results = buf_layout->hash_results; \
8128 + param.frag_enable = frag_enabled; \
8129 + param.time_stamp = buf_layout->time_stamp; \
8130 + param.manip_extra_space = buf_layout->manip_extra_space; \
8131 + param.data_align = buf_layout->data_align; \
8132 + fm_set_##type##_port_params(port, &param); \
8133 +}
8134 +
8135 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
8136 +
8137 +#define DPA_SGT_ENTRIES_THRESHOLD DPA_SGT_MAX_ENTRIES
8138 +
8139 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
8140 +
8141 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
8142 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
8143 + (_errno == -EIO))
8144 +/* return codes for the dpaa-eth hooks */
8145 +enum dpaa_eth_hook_result {
8146 + /* fd/skb was retained by the hook.
8147 + *
8148 + * On the Rx path, this means the Ethernet driver will _not_
8149 + * deliver the skb to the stack. Instead, the hook implementation
8150 + * is expected to properly dispose of the skb.
8151 + *
8152 + * On the Tx path, the Ethernet driver's dpa_tx() function will
8153 + * immediately return NETDEV_TX_OK. The hook implementation is expected
8154 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
8155 + * unless you know exactly what you're doing!
8156 + *
8157 + * On the confirmation/error paths, the Ethernet driver will _not_
8158 + * perform any fd cleanup, nor update the interface statistics.
8159 + */
8160 + DPAA_ETH_STOLEN,
8161 + /* fd/skb was returned to the Ethernet driver for regular processing.
8162 + * The hook is not allowed to, for instance, reallocate the skb (as if
8163 + * by linearizing, copying, cloning or reallocating the headroom).
8164 + */
8165 + DPAA_ETH_CONTINUE
8166 +};
8167 +
8168 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
8169 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
8170 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
8171 + struct sk_buff *skb, struct net_device *net_dev);
8172 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
8173 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
8174 +
8175 +/* used in napi related functions */
8176 +extern u16 qman_portal_max;
8177 +
8178 +/* from dpa_ethtool.c */
8179 +extern const struct ethtool_ops dpa_ethtool_ops;
8180 +
8181 +#ifdef CONFIG_FSL_DPAA_HOOKS
8182 +/* Various hooks used for unit-testing and/or fastpath optimizations.
8183 + * Currently only one set of such hooks is supported.
8184 + */
8185 +struct dpaa_eth_hooks_s {
8186 + /* Invoked on the Tx private path, immediately after receiving the skb
8187 + * from the stack.
8188 + */
8189 + dpaa_eth_egress_hook_t tx;
8190 +
8191 + /* Invoked on the Rx private path, right before passing the skb
8192 + * up the stack. At that point, the packet's protocol id has already
8193 + * been set. The skb's data pointer is now at the L3 header, and
8194 + * skb->mac_header points to the L2 header. skb->len has been adjusted
8195 + * to be the length of L3+payload (i.e., the length of the
8196 + * original frame minus the L2 header len).
8197 + * For more details on what the skb looks like, see eth_type_trans().
8198 + */
8199 + dpaa_eth_ingress_hook_t rx_default;
8200 +
8201 + /* Driver hook for the Rx error private path. */
8202 + dpaa_eth_confirm_hook_t rx_error;
8203 + /* Driver hook for the Tx confirmation private path. */
8204 + dpaa_eth_confirm_hook_t tx_confirm;
8205 + /* Driver hook for the Tx error private path. */
8206 + dpaa_eth_confirm_hook_t tx_error;
8207 +};
8208 +
8209 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
8210 +
8211 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
8212 +#endif
8213 +
8214 +int dpa_netdev_init(struct net_device *net_dev,
8215 + const uint8_t *mac_addr,
8216 + uint16_t tx_timeout);
8217 +int __cold dpa_start(struct net_device *net_dev);
8218 +int __cold dpa_stop(struct net_device *net_dev);
8219 +void __cold dpa_timeout(struct net_device *net_dev);
8220 +struct rtnl_link_stats64 __cold
8221 +*dpa_get_stats64(struct net_device *net_dev,
8222 + struct rtnl_link_stats64 *stats);
8223 +int dpa_change_mtu(struct net_device *net_dev, int new_mtu);
8224 +int dpa_ndo_init(struct net_device *net_dev);
8225 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
8226 +netdev_features_t dpa_fix_features(struct net_device *dev,
8227 + netdev_features_t features);
8228 +#ifdef CONFIG_FSL_DPAA_TS
8229 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
8230 + enum port_type rx_tx, const void *data);
8231 +/* Updates the skb shared hw timestamp from the hardware timestamp */
8232 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8233 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
8234 +#endif /* CONFIG_FSL_DPAA_TS */
8235 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
8236 +int __cold dpa_remove(struct platform_device *of_dev);
8237 +struct mac_device * __cold __must_check
8238 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
8239 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
8240 +void dpa_set_rx_mode(struct net_device *net_dev);
8241 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8242 + struct dpa_buffer_layout_s *layout);
8243 +int __attribute__((nonnull))
8244 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev);
8245 +void __cold __attribute__((nonnull))
8246 +dpa_bp_free(struct dpa_priv_s *priv);
8247 +struct dpa_bp *dpa_bpid2pool(int bpid);
8248 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
8249 +bool dpa_bpid2pool_use(int bpid);
8250 +void dpa_bp_drain(struct dpa_bp *bp);
8251 +#ifdef CONFIG_FSL_DPAA_ETH_USE_NDO_SELECT_QUEUE
8252 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
8253 + void *accel_priv, select_queue_fallback_t fallback);
8254 +#endif
8255 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
8256 + u32 fq_start,
8257 + u32 fq_count,
8258 + struct list_head *list,
8259 + enum dpa_fq_type fq_type);
8260 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
8261 + struct fm_port_fqs *port_fqs,
8262 + bool tx_conf_fqs_per_core,
8263 + enum port_type ptype);
8264 +int dpa_get_channel(void);
8265 +void dpa_release_channel(void);
8266 +void dpaa_eth_add_channel(u16 channel);
8267 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
8268 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
8269 + struct fm_port *tx_port);
8270 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
8271 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
8272 +int __cold __attribute__((nonnull))
8273 +dpa_fq_free(struct device *dev, struct list_head *list);
8274 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
8275 + struct dpa_bp *bp, size_t count,
8276 + struct fm_port_fqs *port_fqs,
8277 + struct dpa_buffer_layout_s *buf_layout,
8278 + struct device *dev);
8279 +void dpa_release_sgt(struct qm_sg_entry *sgt);
8280 +void __attribute__((nonnull))
8281 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
8282 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
8283 + const struct qm_mr_entry *msg);
8284 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
8285 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
8286 +#ifdef CONFIG_FSL_DPAA_CEETM
8287 +void dpa_enable_ceetm(struct net_device *dev);
8288 +void dpa_disable_ceetm(struct net_device *dev);
8289 +#endif
8290 +struct proxy_device {
8291 + struct mac_device *mac_dev;
8292 +};
8293 +
8294 +/* mac device control functions exposed by proxy interface*/
8295 +int dpa_proxy_start(struct net_device *net_dev);
8296 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
8297 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8298 + struct net_device *net_dev);
8299 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8300 + struct net_device *net_dev);
8301 +
8302 +#endif /* __DPAA_ETH_COMMON_H */
8303 --- /dev/null
8304 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
8305 @@ -0,0 +1,381 @@
8306 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
8307 + *
8308 + * Redistribution and use in source and binary forms, with or without
8309 + * modification, are permitted provided that the following conditions are met:
8310 + * * Redistributions of source code must retain the above copyright
8311 + * notice, this list of conditions and the following disclaimer.
8312 + * * Redistributions in binary form must reproduce the above copyright
8313 + * notice, this list of conditions and the following disclaimer in the
8314 + * documentation and/or other materials provided with the distribution.
8315 + * * Neither the name of Freescale Semiconductor nor the
8316 + * names of its contributors may be used to endorse or promote products
8317 + * derived from this software without specific prior written permission.
8318 + *
8319 + *
8320 + * ALTERNATIVELY, this software may be distributed under the terms of the
8321 + * GNU General Public License ("GPL") as published by the Free Software
8322 + * Foundation, either version 2 of that License or (at your option) any
8323 + * later version.
8324 + *
8325 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8326 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8327 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8328 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8329 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8330 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8331 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8332 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8333 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8334 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8335 + */
8336 +
8337 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8338 +#define pr_fmt(fmt) \
8339 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8340 + KBUILD_BASENAME".c", __LINE__, __func__
8341 +#else
8342 +#define pr_fmt(fmt) \
8343 + KBUILD_MODNAME ": " fmt
8344 +#endif
8345 +
8346 +#include <linux/init.h>
8347 +#include <linux/module.h>
8348 +#include <linux/of_platform.h>
8349 +#include "dpaa_eth.h"
8350 +#include "dpaa_eth_common.h"
8351 +#include "dpaa_eth_base.h"
8352 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
8353 +#include "mac.h"
8354 +
8355 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
8356 +
8357 +MODULE_LICENSE("Dual BSD/GPL");
8358 +
8359 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
8360 +
8361 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
8362 +#ifdef CONFIG_PM
8363 +
8364 +static int proxy_suspend(struct device *dev)
8365 +{
8366 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8367 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8368 + int err = 0;
8369 +
8370 + err = fm_port_suspend(mac_dev->port_dev[RX]);
8371 + if (err)
8372 + goto port_suspend_failed;
8373 +
8374 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8375 + if (err)
8376 + err = fm_port_resume(mac_dev->port_dev[RX]);
8377 +
8378 +port_suspend_failed:
8379 + return err;
8380 +}
8381 +
8382 +static int proxy_resume(struct device *dev)
8383 +{
8384 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8385 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8386 + int err = 0;
8387 +
8388 + err = fm_port_resume(mac_dev->port_dev[TX]);
8389 + if (err)
8390 + goto port_resume_failed;
8391 +
8392 + err = fm_port_resume(mac_dev->port_dev[RX]);
8393 + if (err)
8394 + err = fm_port_suspend(mac_dev->port_dev[TX]);
8395 +
8396 +port_resume_failed:
8397 + return err;
8398 +}
8399 +
8400 +static const struct dev_pm_ops proxy_pm_ops = {
8401 + .suspend = proxy_suspend,
8402 + .resume = proxy_resume,
8403 +};
8404 +
8405 +#define PROXY_PM_OPS (&proxy_pm_ops)
8406 +
8407 +#else /* CONFIG_PM */
8408 +
8409 +#define PROXY_PM_OPS NULL
8410 +
8411 +#endif /* CONFIG_PM */
8412 +
8413 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
8414 +{
8415 + int err = 0, i;
8416 + struct device *dev;
8417 + struct device_node *dpa_node;
8418 + struct dpa_bp *dpa_bp;
8419 + struct list_head proxy_fq_list;
8420 + size_t count;
8421 + struct fm_port_fqs port_fqs;
8422 + struct dpa_buffer_layout_s *buf_layout = NULL;
8423 + struct mac_device *mac_dev;
8424 + struct proxy_device *proxy_dev;
8425 +
8426 + dev = &_of_dev->dev;
8427 +
8428 + dpa_node = dev->of_node;
8429 +
8430 + if (!of_device_is_available(dpa_node))
8431 + return -ENODEV;
8432 +
8433 + /* Get the buffer pools assigned to this interface */
8434 + dpa_bp = dpa_bp_probe(_of_dev, &count);
8435 + if (IS_ERR(dpa_bp))
8436 + return PTR_ERR(dpa_bp);
8437 +
8438 + mac_dev = dpa_mac_probe(_of_dev);
8439 + if (IS_ERR(mac_dev))
8440 + return PTR_ERR(mac_dev);
8441 +
8442 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
8443 + if (!proxy_dev) {
8444 + dev_err(dev, "devm_kzalloc() failed\n");
8445 + return -ENOMEM;
8446 + }
8447 +
8448 + proxy_dev->mac_dev = mac_dev;
8449 + dev_set_drvdata(dev, proxy_dev);
8450 +
8451 + /* We have physical ports, so we need to establish
8452 + * the buffer layout.
8453 + */
8454 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
8455 + GFP_KERNEL);
8456 + if (!buf_layout) {
8457 + dev_err(dev, "devm_kzalloc() failed\n");
8458 + return -ENOMEM;
8459 + }
8460 + dpa_set_buffers_layout(mac_dev, buf_layout);
8461 +
8462 + INIT_LIST_HEAD(&proxy_fq_list);
8463 +
8464 + memset(&port_fqs, 0, sizeof(port_fqs));
8465 +
8466 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
8467 + if (!err)
8468 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
8469 + TX);
8470 + if (err < 0) {
8471 + devm_kfree(dev, buf_layout);
8472 + return err;
8473 + }
8474 +
8475 + /* Proxy initializer - Just configures the MAC on behalf of
8476 + * another partition.
8477 + */
8478 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
8479 + buf_layout, dev);
8480 +
8481 + /* Proxy interfaces need to be started, and the allocated
8482 + * memory freed
8483 + */
8484 + devm_kfree(dev, buf_layout);
8485 + devm_kfree(dev, dpa_bp);
8486 +
8487 + /* Free FQ structures */
8488 + devm_kfree(dev, port_fqs.rx_defq);
8489 + devm_kfree(dev, port_fqs.rx_errq);
8490 + devm_kfree(dev, port_fqs.tx_defq);
8491 + devm_kfree(dev, port_fqs.tx_errq);
8492 +
8493 + for_each_port_device(i, mac_dev->port_dev) {
8494 + err = fm_port_enable(mac_dev->port_dev[i]);
8495 + if (err)
8496 + goto port_enable_fail;
8497 + }
8498 +
8499 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
8500 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
8501 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
8502 +
8503 + return 0; /* Proxy interface initialization ended */
8504 +
8505 +port_enable_fail:
8506 + for_each_port_device(i, mac_dev->port_dev)
8507 + fm_port_disable(mac_dev->port_dev[i]);
8508 + dpa_eth_proxy_remove(_of_dev);
8509 +
8510 + return err;
8511 +}
8512 +
8513 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
8514 + struct net_device *net_dev)
8515 +{
8516 + struct mac_device *mac_dev;
8517 + int _errno;
8518 +
8519 + mac_dev = proxy_dev->mac_dev;
8520 +
8521 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8522 + net_dev->dev_addr);
8523 + if (_errno < 0)
8524 + return _errno;
8525 +
8526 + return 0;
8527 +}
8528 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
8529 +
8530 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
8531 + struct net_device *net_dev)
8532 +{
8533 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8534 + int _errno;
8535 +
8536 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
8537 + mac_dev->promisc = !mac_dev->promisc;
8538 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
8539 + mac_dev->promisc);
8540 + if (unlikely(_errno < 0))
8541 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
8542 + _errno);
8543 + }
8544 +
8545 + _errno = mac_dev->set_multi(net_dev, mac_dev);
8546 + if (unlikely(_errno < 0))
8547 + return _errno;
8548 +
8549 + return 0;
8550 +}
8551 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
8552 +
8553 +int dpa_proxy_start(struct net_device *net_dev)
8554 +{
8555 + struct mac_device *mac_dev;
8556 + const struct dpa_priv_s *priv;
8557 + struct proxy_device *proxy_dev;
8558 + int _errno;
8559 + int i;
8560 +
8561 + priv = netdev_priv(net_dev);
8562 + proxy_dev = (struct proxy_device *)priv->peer;
8563 + mac_dev = proxy_dev->mac_dev;
8564 +
8565 + _errno = mac_dev->init_phy(net_dev, mac_dev);
8566 + if (_errno < 0) {
8567 + if (netif_msg_drv(priv))
8568 + netdev_err(net_dev, "init_phy() = %d\n",
8569 + _errno);
8570 + return _errno;
8571 + }
8572 +
8573 + for_each_port_device(i, mac_dev->port_dev) {
8574 + _errno = fm_port_enable(mac_dev->port_dev[i]);
8575 + if (_errno)
8576 + goto port_enable_fail;
8577 + }
8578 +
8579 + _errno = mac_dev->start(mac_dev);
8580 + if (_errno < 0) {
8581 + if (netif_msg_drv(priv))
8582 + netdev_err(net_dev, "mac_dev->start() = %d\n",
8583 + _errno);
8584 + goto port_enable_fail;
8585 + }
8586 +
8587 + return _errno;
8588 +
8589 +port_enable_fail:
8590 + for_each_port_device(i, mac_dev->port_dev)
8591 + fm_port_disable(mac_dev->port_dev[i]);
8592 +
8593 + return _errno;
8594 +}
8595 +EXPORT_SYMBOL(dpa_proxy_start);
8596 +
8597 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
8598 +{
8599 + struct mac_device *mac_dev = proxy_dev->mac_dev;
8600 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
8601 + int _errno, i, err;
8602 +
8603 + _errno = mac_dev->stop(mac_dev);
8604 + if (_errno < 0) {
8605 + if (netif_msg_drv(priv))
8606 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8607 + _errno);
8608 + return _errno;
8609 + }
8610 +
8611 + for_each_port_device(i, mac_dev->port_dev) {
8612 + err = fm_port_disable(mac_dev->port_dev[i]);
8613 + _errno = err ? err : _errno;
8614 + }
8615 +
8616 + if (mac_dev->phy_dev)
8617 + phy_disconnect(mac_dev->phy_dev);
8618 + mac_dev->phy_dev = NULL;
8619 +
8620 + return _errno;
8621 +}
8622 +EXPORT_SYMBOL(dpa_proxy_stop);
8623 +
8624 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
8625 +{
8626 + struct device *dev = &of_dev->dev;
8627 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
8628 +
8629 + kfree(proxy_dev);
8630 +
8631 + dev_set_drvdata(dev, NULL);
8632 +
8633 + return 0;
8634 +}
8635 +
8636 +static const struct of_device_id dpa_proxy_match[] = {
8637 + {
8638 + .compatible = "fsl,dpa-ethernet-init"
8639 + },
8640 + {}
8641 +};
8642 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
8643 +
8644 +static struct platform_driver dpa_proxy_driver = {
8645 + .driver = {
8646 + .name = KBUILD_MODNAME "-proxy",
8647 + .of_match_table = dpa_proxy_match,
8648 + .owner = THIS_MODULE,
8649 + .pm = PROXY_PM_OPS,
8650 + },
8651 + .probe = dpaa_eth_proxy_probe,
8652 + .remove = dpa_eth_proxy_remove
8653 +};
8654 +
8655 +static int __init __cold dpa_proxy_load(void)
8656 +{
8657 + int _errno;
8658 +
8659 + pr_info(DPA_DESCRIPTION "\n");
8660 +
8661 + /* Initialize dpaa_eth mirror values */
8662 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
8663 + dpa_max_frm = fm_get_max_frm();
8664 +
8665 + _errno = platform_driver_register(&dpa_proxy_driver);
8666 + if (unlikely(_errno < 0)) {
8667 + pr_err(KBUILD_MODNAME
8668 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
8669 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
8670 + }
8671 +
8672 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8673 + KBUILD_BASENAME".c", __func__);
8674 +
8675 + return _errno;
8676 +}
8677 +module_init(dpa_proxy_load);
8678 +
8679 +static void __exit __cold dpa_proxy_unload(void)
8680 +{
8681 + platform_driver_unregister(&dpa_proxy_driver);
8682 +
8683 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
8684 + KBUILD_BASENAME".c", __func__);
8685 +}
8686 +module_exit(dpa_proxy_unload);
8687 --- /dev/null
8688 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
8689 @@ -0,0 +1,1193 @@
8690 +/* Copyright 2012 Freescale Semiconductor Inc.
8691 + *
8692 + * Redistribution and use in source and binary forms, with or without
8693 + * modification, are permitted provided that the following conditions are met:
8694 + * * Redistributions of source code must retain the above copyright
8695 + * notice, this list of conditions and the following disclaimer.
8696 + * * Redistributions in binary form must reproduce the above copyright
8697 + * notice, this list of conditions and the following disclaimer in the
8698 + * documentation and/or other materials provided with the distribution.
8699 + * * Neither the name of Freescale Semiconductor nor the
8700 + * names of its contributors may be used to endorse or promote products
8701 + * derived from this software without specific prior written permission.
8702 + *
8703 + *
8704 + * ALTERNATIVELY, this software may be distributed under the terms of the
8705 + * GNU General Public License ("GPL") as published by the Free Software
8706 + * Foundation, either version 2 of that License or (at your option) any
8707 + * later version.
8708 + *
8709 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8710 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8711 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8712 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8713 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8714 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8715 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8716 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8717 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8718 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8719 + */
8720 +
8721 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
8722 +#define pr_fmt(fmt) \
8723 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
8724 + KBUILD_BASENAME".c", __LINE__, __func__
8725 +#else
8726 +#define pr_fmt(fmt) \
8727 + KBUILD_MODNAME ": " fmt
8728 +#endif
8729 +
8730 +#include <linux/init.h>
8731 +#include <linux/skbuff.h>
8732 +#include <linux/highmem.h>
8733 +#include <linux/fsl_bman.h>
8734 +#include <net/sock.h>
8735 +
8736 +#include "dpaa_eth.h"
8737 +#include "dpaa_eth_common.h"
8738 +#ifdef CONFIG_FSL_DPAA_1588
8739 +#include "dpaa_1588.h"
8740 +#endif
8741 +#ifdef CONFIG_FSL_DPAA_CEETM
8742 +#include "dpaa_eth_ceetm.h"
8743 +#endif
8744 +
8745 +/* DMA map and add a page frag back into the bpool.
8746 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
8747 + * specifically for fitting into @dpa_bp.
8748 + */
8749 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
8750 + int *count_ptr)
8751 +{
8752 + struct bm_buffer bmb;
8753 + dma_addr_t addr;
8754 +
8755 + bmb.opaque = 0;
8756 +
8757 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
8758 + DMA_BIDIRECTIONAL);
8759 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
8760 + dev_err(dpa_bp->dev, "DMA mapping failed");
8761 + return;
8762 + }
8763 +
8764 + bm_buffer_set64(&bmb, addr);
8765 +
8766 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
8767 + cpu_relax();
8768 +
8769 + (*count_ptr)++;
8770 +}
8771 +
8772 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
8773 +{
8774 + struct bm_buffer bmb[8];
8775 + void *new_buf;
8776 + dma_addr_t addr;
8777 + uint8_t i;
8778 + struct device *dev = dpa_bp->dev;
8779 + struct sk_buff *skb, **skbh;
8780 +
8781 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
8782 +
8783 + for (i = 0; i < 8; i++) {
8784 + /* We'll prepend the skb back-pointer; can't use the DPA
8785 + * priv space, because FMan will overwrite it (from offset 0)
8786 + * if it ends up being the second, third, etc. fragment
8787 + * in a S/G frame.
8788 + *
8789 + * We only need enough space to store a pointer, but allocate
8790 + * an entire cacheline for performance reasons.
8791 + */
8792 +#ifndef CONFIG_PPC
8793 + if (unlikely(dpaa_errata_a010022)) {
8794 + struct page *new_page = alloc_page(GFP_ATOMIC);
8795 + if (unlikely(!new_page))
8796 + goto netdev_alloc_failed;
8797 + new_buf = page_address(new_page);
8798 + }
8799 + else
8800 +#endif
8801 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
8802 +
8803 + if (unlikely(!new_buf))
8804 + goto netdev_alloc_failed;
8805 + new_buf = PTR_ALIGN(new_buf + SMP_CACHE_BYTES, SMP_CACHE_BYTES);
8806 +
8807 + skb = build_skb(new_buf, DPA_SKB_SIZE(dpa_bp->size) +
8808 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
8809 + if (unlikely(!skb)) {
8810 + put_page(virt_to_head_page(new_buf));
8811 + goto build_skb_failed;
8812 + }
8813 +
8814 + /* Store the skb back-pointer before the start of the buffer.
8815 + * Otherwise it will be overwritten by the FMan.
8816 + */
8817 + DPA_WRITE_SKB_PTR(skb, skbh, new_buf, -1);
8818 +
8819 + addr = dma_map_single(dev, new_buf,
8820 + dpa_bp->size, DMA_BIDIRECTIONAL);
8821 + if (unlikely(dma_mapping_error(dev, addr)))
8822 + goto dma_map_failed;
8823 +
8824 + bm_buffer_set64(&bmb[i], addr);
8825 + }
8826 +
8827 +release_bufs:
8828 + /* Release the buffers. In case bman is busy, keep trying
8829 + * until successful. bman_release() is guaranteed to succeed
8830 + * in a reasonable amount of time
8831 + */
8832 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
8833 + cpu_relax();
8834 + return i;
8835 +
8836 +dma_map_failed:
8837 + kfree_skb(skb);
8838 +
8839 +build_skb_failed:
8840 +netdev_alloc_failed:
8841 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
8842 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
8843 +
8844 + bm_buffer_set64(&bmb[i], 0);
8845 + /* Avoid releasing a completely null buffer; bman_release() requires
8846 + * at least one buffer.
8847 + */
8848 + if (likely(i))
8849 + goto release_bufs;
8850 +
8851 + return 0;
8852 +}
8853 +
8854 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
8855 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
8856 +{
8857 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
8858 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
8859 +}
8860 +
8861 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
8862 +{
8863 + int i;
8864 +
8865 + /* Give each CPU an allotment of "config_count" buffers */
8866 + for_each_possible_cpu(i) {
8867 + int j;
8868 +
8869 + /* Although we access another CPU's counters here
8870 + * we do it at boot time so it is safe
8871 + */
8872 + for (j = 0; j < dpa_bp->config_count; j += 8)
8873 + dpa_bp_add_8_bufs(dpa_bp, i);
8874 + }
8875 + return 0;
8876 +}
8877 +EXPORT_SYMBOL(dpa_bp_priv_seed);
8878 +
8879 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
8880 + * REFILL_THRESHOLD.
8881 + */
8882 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
8883 +{
8884 + int count = *countptr;
8885 + int new_bufs;
8886 +
8887 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
8888 + do {
8889 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
8890 + if (unlikely(!new_bufs)) {
8891 + /* Avoid looping forever if we've temporarily
8892 + * run out of memory. We'll try again at the
8893 + * next NAPI cycle.
8894 + */
8895 + break;
8896 + }
8897 + count += new_bufs;
8898 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
8899 +
8900 + *countptr = count;
8901 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
8902 + return -ENOMEM;
8903 + }
8904 +
8905 + return 0;
8906 +}
8907 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
8908 +
8909 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
8910 + * either contiguous frames or scatter/gather ones.
8911 + * Skb freeing is not handled here.
8912 + *
8913 + * This function may be called on error paths in the Tx function, so guard
8914 + * against cases when not all fd relevant fields were filled in.
8915 + *
8916 + * Return the skb backpointer, since for S/G frames the buffer containing it
8917 + * gets freed here.
8918 + */
8919 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
8920 + const struct qm_fd *fd)
8921 +{
8922 + const struct qm_sg_entry *sgt;
8923 + int i;
8924 + struct dpa_bp *dpa_bp = priv->dpa_bp;
8925 + dma_addr_t addr = qm_fd_addr(fd);
8926 + dma_addr_t sg_addr;
8927 + struct sk_buff **skbh;
8928 + struct sk_buff *skb = NULL;
8929 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
8930 + int nr_frags;
8931 + int sg_len;
8932 +
8933 + /* retrieve skb back pointer */
8934 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
8935 +
8936 + if (unlikely(fd->format == qm_fd_sg)) {
8937 + nr_frags = skb_shinfo(skb)->nr_frags;
8938 + dma_unmap_single(dpa_bp->dev, addr, dpa_fd_offset(fd) +
8939 + sizeof(struct qm_sg_entry) * (1 + nr_frags),
8940 + dma_dir);
8941 +
8942 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
8943 + * it's from lowmem.
8944 + */
8945 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
8946 +#ifdef CONFIG_FSL_DPAA_1588
8947 + if (priv->tsu && priv->tsu->valid &&
8948 + priv->tsu->hwts_tx_en_ioctl)
8949 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8950 +#endif
8951 +#ifdef CONFIG_FSL_DPAA_TS
8952 + if (unlikely(priv->ts_tx_en &&
8953 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8954 + struct skb_shared_hwtstamps shhwtstamps;
8955 +
8956 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8957 + skb_tstamp_tx(skb, &shhwtstamps);
8958 + }
8959 +#endif /* CONFIG_FSL_DPAA_TS */
8960 +
8961 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
8962 + sg_addr = qm_sg_addr(&sgt[0]);
8963 + sg_len = qm_sg_entry_get_len(&sgt[0]);
8964 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8965 +
8966 + /* remaining pages were mapped with dma_map_page() */
8967 + for (i = 1; i <= nr_frags; i++) {
8968 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
8969 + sg_addr = qm_sg_addr(&sgt[i]);
8970 + sg_len = qm_sg_entry_get_len(&sgt[i]);
8971 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
8972 + }
8973 +
8974 + /* Free the page frag that we allocated on Tx */
8975 + put_page(virt_to_head_page(sgt));
8976 + } else {
8977 + dma_unmap_single(dpa_bp->dev, addr,
8978 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
8979 +#ifdef CONFIG_FSL_DPAA_TS
8980 + /* get the timestamp for non-SG frames */
8981 +#ifdef CONFIG_FSL_DPAA_1588
8982 + if (priv->tsu && priv->tsu->valid &&
8983 + priv->tsu->hwts_tx_en_ioctl)
8984 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
8985 +#endif
8986 + if (unlikely(priv->ts_tx_en &&
8987 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
8988 + struct skb_shared_hwtstamps shhwtstamps;
8989 +
8990 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
8991 + skb_tstamp_tx(skb, &shhwtstamps);
8992 + }
8993 +#endif
8994 + }
8995 +
8996 + return skb;
8997 +}
8998 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
8999 +
9000 +#ifndef CONFIG_FSL_DPAA_TS
9001 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
9002 +{
9003 +#ifndef CONFIG_PPC
9004 + /* Do no recycle skbs realigned by the errata workaround */
9005 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
9006 + return false;
9007 +#endif
9008 +
9009 + /* No recycling possible if skb buffer is kmalloc'ed */
9010 + if (skb->head_frag == 0)
9011 + return false;
9012 +
9013 + /* or if it's an userspace buffer */
9014 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
9015 + return false;
9016 +
9017 + /* or if it's cloned or shared */
9018 + if (skb_shared(skb) || skb_cloned(skb) ||
9019 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
9020 + return false;
9021 +
9022 + return true;
9023 +}
9024 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
9025 +
9026 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
9027 + uint32_t min_size,
9028 + uint16_t min_offset,
9029 + unsigned char **new_buf_start)
9030 +{
9031 + unsigned char *new;
9032 +
9033 + /* In order to recycle a buffer, the following conditions must be met:
9034 + * - buffer size no less than the buffer pool size
9035 + * - buffer size no higher than an upper limit (to avoid moving too much
9036 + * system memory to the buffer pools)
9037 + * - buffer address aligned to cacheline bytes
9038 + * - offset of data from start of buffer no lower than a minimum value
9039 + * - offset of data from start of buffer no higher than a maximum value
9040 + * - the skb back-pointer is stored safely
9041 + */
9042 +
9043 + /* guarantee both the minimum size and the minimum data offset */
9044 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
9045 +
9046 + /* left align to the nearest cacheline */
9047 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
9048 +
9049 + /* Make sure there is enough space to store the skb back-pointer in
9050 + * the headroom, right before the start of the buffer.
9051 + *
9052 + * Guarantee that both maximum size and maximum data offsets aren't
9053 + * crossed.
9054 + */
9055 + if (likely(new >= (skb->head + sizeof(void *)) &&
9056 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
9057 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
9058 + *new_buf_start = new;
9059 + return true;
9060 + }
9061 +
9062 + return false;
9063 +}
9064 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
9065 +#endif
9066 +
9067 +/* Build a linear skb around the received buffer.
9068 + * We are guaranteed there is enough room at the end of the data buffer to
9069 + * accommodate the shared info area of the skb.
9070 + */
9071 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
9072 + const struct qm_fd *fd, int *use_gro)
9073 +{
9074 + dma_addr_t addr = qm_fd_addr(fd);
9075 + ssize_t fd_off = dpa_fd_offset(fd);
9076 + void *vaddr;
9077 + const fm_prs_result_t *parse_results;
9078 + struct sk_buff *skb = NULL, **skbh;
9079 +
9080 + vaddr = phys_to_virt(addr);
9081 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9082 +
9083 + /* Retrieve the skb and adjust data and tail pointers, to make sure
9084 + * forwarded skbs will have enough space on Tx if extra headers
9085 + * are added.
9086 + */
9087 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
9088 +
9089 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
9090 + /* When using jumbo Rx buffers, we risk having frames dropped due to
9091 + * the socket backlog reaching its maximum allowed size.
9092 + * Use the frame length for the skb truesize instead of the buffer
9093 + * size, as this is the size of the data that actually gets copied to
9094 + * userspace.
9095 + * The stack may increase the payload. In this case, it will want to
9096 + * warn us that the frame length is larger than the truesize. We
9097 + * bypass the warning.
9098 + */
9099 +#ifndef CONFIG_PPC
9100 + /* We do not support Jumbo frames on LS1043 and thus we edit
9101 + * the skb truesize only when the 4k errata is not present.
9102 + */
9103 + if (likely(!dpaa_errata_a010022))
9104 +#endif
9105 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
9106 +#endif
9107 +
9108 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9109 + skb_reserve(skb, fd_off);
9110 + skb_put(skb, dpa_fd_length(fd));
9111 +
9112 + /* Peek at the parse results for csum validation */
9113 + parse_results = (const fm_prs_result_t *)(vaddr +
9114 + DPA_RX_PRIV_DATA_SIZE);
9115 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
9116 +
9117 +#ifdef CONFIG_FSL_DPAA_1588
9118 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
9119 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9120 +#endif
9121 +#ifdef CONFIG_FSL_DPAA_TS
9122 + if (priv->ts_rx_en)
9123 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9124 +#endif /* CONFIG_FSL_DPAA_TS */
9125 +
9126 + return skb;
9127 +}
9128 +
9129 +
9130 +/* Build an skb with the data of the first S/G entry in the linear portion and
9131 + * the rest of the frame as skb fragments.
9132 + *
9133 + * The page fragment holding the S/G Table is recycled here.
9134 + */
9135 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
9136 + const struct qm_fd *fd, int *use_gro,
9137 + int *count_ptr)
9138 +{
9139 + const struct qm_sg_entry *sgt;
9140 + dma_addr_t addr = qm_fd_addr(fd);
9141 + ssize_t fd_off = dpa_fd_offset(fd);
9142 + dma_addr_t sg_addr;
9143 + void *vaddr, *sg_vaddr;
9144 + struct dpa_bp *dpa_bp;
9145 + struct page *page, *head_page;
9146 + int frag_offset, frag_len;
9147 + int page_offset;
9148 + int i;
9149 + const fm_prs_result_t *parse_results;
9150 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
9151 +
9152 + vaddr = phys_to_virt(addr);
9153 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
9154 +
9155 + dpa_bp = priv->dpa_bp;
9156 + /* Iterate through the SGT entries and add data buffers to the skb */
9157 + sgt = vaddr + fd_off;
9158 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
9159 + /* Extension bit is not supported */
9160 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9161 +
9162 + /* We use a single global Rx pool */
9163 + DPA_BUG_ON(dpa_bp !=
9164 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
9165 +
9166 + sg_addr = qm_sg_addr(&sgt[i]);
9167 + sg_vaddr = phys_to_virt(sg_addr);
9168 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
9169 + SMP_CACHE_BYTES));
9170 +
9171 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
9172 + DMA_BIDIRECTIONAL);
9173 + if (i == 0) {
9174 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
9175 + DPA_BUG_ON(skb->head != sg_vaddr);
9176 +#ifdef CONFIG_FSL_DPAA_1588
9177 + if (priv->tsu && priv->tsu->valid &&
9178 + priv->tsu->hwts_rx_en_ioctl)
9179 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
9180 +#endif
9181 +#ifdef CONFIG_FSL_DPAA_TS
9182 + if (priv->ts_rx_en)
9183 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
9184 +#endif /* CONFIG_FSL_DPAA_TS */
9185 +
9186 + /* In the case of a SG frame, FMan stores the Internal
9187 + * Context in the buffer containing the sgt.
9188 + * Inspect the parse results before anything else.
9189 + */
9190 + parse_results = (const fm_prs_result_t *)(vaddr +
9191 + DPA_RX_PRIV_DATA_SIZE);
9192 + _dpa_process_parse_results(parse_results, fd, skb,
9193 + use_gro);
9194 +
9195 + /* Make sure forwarded skbs will have enough space
9196 + * on Tx, if extra headers are added.
9197 + */
9198 + DPA_BUG_ON(fd_off != priv->rx_headroom);
9199 + skb_reserve(skb, fd_off);
9200 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
9201 + } else {
9202 + /* Not the first S/G entry; all data from buffer will
9203 + * be added in an skb fragment; fragment index is offset
9204 + * by one since first S/G entry was incorporated in the
9205 + * linear part of the skb.
9206 + *
9207 + * Caution: 'page' may be a tail page.
9208 + */
9209 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
9210 + page = virt_to_page(sg_vaddr);
9211 + head_page = virt_to_head_page(sg_vaddr);
9212 +
9213 + /* Free (only) the skbuff shell because its data buffer
9214 + * is already a frag in the main skb.
9215 + */
9216 + get_page(head_page);
9217 + dev_kfree_skb(skb_tmp);
9218 +
9219 + /* Compute offset in (possibly tail) page */
9220 + page_offset = ((unsigned long)sg_vaddr &
9221 + (PAGE_SIZE - 1)) +
9222 + (page_address(page) - page_address(head_page));
9223 + /* page_offset only refers to the beginning of sgt[i];
9224 + * but the buffer itself may have an internal offset.
9225 + */
9226 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
9227 + page_offset;
9228 + frag_len = qm_sg_entry_get_len(&sgt[i]);
9229 + /* skb_add_rx_frag() does no checking on the page; if
9230 + * we pass it a tail page, we'll end up with
9231 + * bad page accounting and eventually with segafults.
9232 + */
9233 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
9234 + frag_len, dpa_bp->size);
9235 + }
9236 + /* Update the pool count for the current {cpu x bpool} */
9237 + (*count_ptr)--;
9238 +
9239 + if (qm_sg_entry_get_final(&sgt[i]))
9240 + break;
9241 + }
9242 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
9243 +
9244 + /* recycle the SGT fragment */
9245 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9246 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
9247 + return skb;
9248 +}
9249 +
9250 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9251 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
9252 + struct sk_buff *skb)
9253 +{
9254 + if (unlikely(priv->loop_to < 0))
9255 + return 0; /* loop disabled by default */
9256 +
9257 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
9258 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
9259 +
9260 + return 1; /* Frame Tx on the selected interface */
9261 +}
9262 +#endif
9263 +
9264 +void __hot _dpa_rx(struct net_device *net_dev,
9265 + struct qman_portal *portal,
9266 + const struct dpa_priv_s *priv,
9267 + struct dpa_percpu_priv_s *percpu_priv,
9268 + const struct qm_fd *fd,
9269 + u32 fqid,
9270 + int *count_ptr)
9271 +{
9272 + struct dpa_bp *dpa_bp;
9273 + struct sk_buff *skb;
9274 + dma_addr_t addr = qm_fd_addr(fd);
9275 + u32 fd_status = fd->status;
9276 + unsigned int skb_len;
9277 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
9278 + int use_gro = net_dev->features & NETIF_F_GRO;
9279 +
9280 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
9281 + if (netif_msg_hw(priv) && net_ratelimit())
9282 + netdev_warn(net_dev, "FD status = 0x%08x\n",
9283 + fd_status & FM_FD_STAT_RX_ERRORS);
9284 +
9285 + percpu_stats->rx_errors++;
9286 + goto _release_frame;
9287 + }
9288 +
9289 + dpa_bp = priv->dpa_bp;
9290 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
9291 +
9292 + /* prefetch the first 64 bytes of the frame or the SGT start */
9293 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
9294 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
9295 +
9296 + /* The only FD types that we may receive are contig and S/G */
9297 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
9298 +
9299 + if (likely(fd->format == qm_fd_contig)) {
9300 +#ifdef CONFIG_FSL_DPAA_HOOKS
9301 + /* Execute the Rx processing hook, if it exists. */
9302 + if (dpaa_eth_hooks.rx_default &&
9303 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
9304 + fqid) == DPAA_ETH_STOLEN) {
9305 + /* won't count the rx bytes in */
9306 + return;
9307 + }
9308 +#endif
9309 + skb = contig_fd_to_skb(priv, fd, &use_gro);
9310 + } else {
9311 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
9312 + percpu_priv->rx_sg++;
9313 + }
9314 +
9315 + /* Account for either the contig buffer or the SGT buffer (depending on
9316 + * which case we were in) having been removed from the pool.
9317 + */
9318 + (*count_ptr)--;
9319 + skb->protocol = eth_type_trans(skb, net_dev);
9320 +
9321 + skb_len = skb->len;
9322 +
9323 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
9324 + if (dpa_skb_loop(priv, skb)) {
9325 + percpu_stats->rx_packets++;
9326 + percpu_stats->rx_bytes += skb_len;
9327 + return;
9328 + }
9329 +#endif
9330 +
9331 + if (use_gro) {
9332 + gro_result_t gro_result;
9333 + const struct qman_portal_config *pc =
9334 + qman_p_get_portal_config(portal);
9335 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
9336 +
9337 + np->p = portal;
9338 + gro_result = napi_gro_receive(&np->napi, skb);
9339 + /* If frame is dropped by the stack, rx_dropped counter is
9340 + * incremented automatically, so no need for us to update it
9341 + */
9342 + if (unlikely(gro_result == GRO_DROP))
9343 + goto packet_dropped;
9344 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
9345 + goto packet_dropped;
9346 +
9347 + percpu_stats->rx_packets++;
9348 + percpu_stats->rx_bytes += skb_len;
9349 +
9350 +packet_dropped:
9351 + return;
9352 +
9353 +_release_frame:
9354 + dpa_fd_release(net_dev, fd);
9355 +}
9356 +
9357 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
9358 + struct sk_buff *skb, struct qm_fd *fd,
9359 + int *count_ptr, int *offset)
9360 +{
9361 + struct sk_buff **skbh;
9362 + dma_addr_t addr;
9363 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9364 + struct net_device *net_dev = priv->net_dev;
9365 + int err;
9366 + enum dma_data_direction dma_dir;
9367 + unsigned char *buffer_start;
9368 + int dma_map_size;
9369 +
9370 +#ifndef CONFIG_FSL_DPAA_TS
9371 + /* Check recycling conditions; only if timestamp support is not
9372 + * enabled, otherwise we need the fd back on tx confirmation
9373 + */
9374 +
9375 + /* We can recycle the buffer if:
9376 + * - the pool is not full
9377 + * - the buffer meets the skb recycling conditions
9378 + * - the buffer meets our own (size, offset, align) conditions
9379 + */
9380 + if (likely((*count_ptr < dpa_bp->target_count) &&
9381 + dpa_skb_is_recyclable(skb) &&
9382 + dpa_buf_is_recyclable(skb, dpa_bp->size,
9383 + priv->tx_headroom, &buffer_start))) {
9384 + /* Buffer is recyclable; use the new start address
9385 + * and set fd parameters and DMA mapping direction
9386 + */
9387 + fd->bpid = dpa_bp->bpid;
9388 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
9389 + fd->offset = (uint16_t)(skb->data - buffer_start);
9390 + dma_dir = DMA_BIDIRECTIONAL;
9391 + dma_map_size = dpa_bp->size;
9392 +
9393 + /* Store the skb back-pointer before the start of the buffer.
9394 + * Otherwise it will be overwritten by the FMan.
9395 + */
9396 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
9397 + *offset = skb_headroom(skb) - fd->offset;
9398 + } else
9399 +#endif
9400 + {
9401 + /* Not recyclable.
9402 + * We are guaranteed to have at least tx_headroom bytes
9403 + * available, so just use that for offset.
9404 + */
9405 + fd->bpid = 0xff;
9406 + buffer_start = skb->data - priv->tx_headroom;
9407 + fd->offset = priv->tx_headroom;
9408 + dma_dir = DMA_TO_DEVICE;
9409 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
9410 +
9411 + /* The buffer will be Tx-confirmed, but the TxConf cb must
9412 + * necessarily look at our Tx private data to retrieve the
9413 + * skbuff. Store the back-pointer inside the buffer.
9414 + */
9415 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
9416 + }
9417 +
9418 + /* Enable L3/L4 hardware checksum computation.
9419 + *
9420 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9421 + * need to write into the skb.
9422 + */
9423 + err = dpa_enable_tx_csum(priv, skb, fd,
9424 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
9425 + if (unlikely(err < 0)) {
9426 + if (netif_msg_tx_err(priv) && net_ratelimit())
9427 + netdev_err(net_dev, "HW csum error: %d\n", err);
9428 + return err;
9429 + }
9430 +
9431 + /* Fill in the rest of the FD fields */
9432 + fd->format = qm_fd_contig;
9433 + fd->length20 = skb->len;
9434 + fd->cmd |= FM_FD_CMD_FCO;
9435 +
9436 + /* Map the entire buffer size that may be seen by FMan, but no more */
9437 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
9438 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9439 + if (netif_msg_tx_err(priv) && net_ratelimit())
9440 + netdev_err(net_dev, "dma_map_single() failed\n");
9441 + return -EINVAL;
9442 + }
9443 + qm_fd_addr_set64(fd, addr);
9444 +
9445 + return 0;
9446 +}
9447 +EXPORT_SYMBOL(skb_to_contig_fd);
9448 +
9449 +#ifndef CONFIG_PPC
9450 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
9451 + * 16 bytes and 4K memory address crossings.
9452 + */
9453 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
9454 +{
9455 + int nr_frags, i = 0;
9456 + skb_frag_t *frag;
9457 +
9458 + /* Check if the headroom is aligned */
9459 + if (((uintptr_t)skb->data - priv->tx_headroom) %
9460 + priv->buf_layout[TX].data_align != 0)
9461 + return true;
9462 +
9463 + /* Check if the headroom crosses a boundary */
9464 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
9465 + return true;
9466 +
9467 + /* Check if the non-paged data crosses a boundary */
9468 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
9469 + return true;
9470 +
9471 + /* Check if the entire linear skb crosses a boundary */
9472 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
9473 + return true;
9474 +
9475 + nr_frags = skb_shinfo(skb)->nr_frags;
9476 +
9477 + while (i < nr_frags) {
9478 + frag = &skb_shinfo(skb)->frags[i];
9479 +
9480 + /* Check if a paged fragment crosses a boundary from its
9481 + * offset to its end.
9482 + */
9483 + if (HAS_DMA_ISSUE(frag->page_offset, frag->size))
9484 + return true;
9485 +
9486 + i++;
9487 + }
9488 +
9489 + return false;
9490 +}
9491 +
9492 +/* Realign the skb by copying its contents at the start of a newly allocated
9493 + * page. Build a new skb around the new buffer and release the old one.
9494 + * A performance drop should be expected.
9495 + */
9496 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
9497 + struct dpa_priv_s *priv)
9498 +{
9499 + int trans_offset = skb_transport_offset(skb);
9500 + int net_offset = skb_network_offset(skb);
9501 + struct sk_buff *nskb = NULL;
9502 + int nsize, headroom;
9503 + struct page *npage;
9504 + void *npage_addr;
9505 +
9506 + /* Guarantee the minimum required headroom */
9507 + if (skb_headroom(skb) >= priv->tx_headroom)
9508 + headroom = skb_headroom(skb);
9509 + else
9510 + headroom = priv->tx_headroom;
9511 +
9512 + npage = alloc_page(GFP_ATOMIC);
9513 + if (unlikely(!npage)) {
9514 + WARN_ONCE(1, "Memory allocation failure\n");
9515 + return NULL;
9516 + }
9517 + npage_addr = page_address(npage);
9518 +
9519 + /* For the new skb we only need the old one's data (both non-paged and
9520 + * paged) and a headroom large enough to fit our private info. We can
9521 + * skip the old tailroom.
9522 + *
9523 + * Make sure the new linearized buffer will not exceed a page's size.
9524 + */
9525 + nsize = headroom + skb->len +
9526 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
9527 + if (unlikely(nsize > 4096))
9528 + goto err;
9529 +
9530 + nskb = build_skb(npage_addr, nsize);
9531 + if (unlikely(!nskb))
9532 + goto err;
9533 +
9534 + /* Reserve only the needed headroom in order to guarantee the data's
9535 + * alignment.
9536 + * Code borrowed and adapted from skb_copy().
9537 + */
9538 + skb_reserve(nskb, priv->tx_headroom);
9539 + skb_put(nskb, skb->len);
9540 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
9541 + WARN_ONCE(1, "skb parsing failure\n");
9542 + goto err;
9543 + }
9544 + copy_skb_header(nskb, skb);
9545 +
9546 +#ifdef CONFIG_FSL_DPAA_TS
9547 + /* Copy relevant timestamp info from the old skb to the new */
9548 + if (priv->ts_tx_en) {
9549 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
9550 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
9551 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
9552 + if (skb->sk)
9553 + skb_set_owner_w(nskb, skb->sk);
9554 + }
9555 +#endif
9556 + /* We move the headroom when we align it so we have to reset the
9557 + * network and transport header offsets relative to the new data
9558 + * pointer. The checksum offload relies on these offsets.
9559 + */
9560 + skb_set_network_header(nskb, net_offset);
9561 + skb_set_transport_header(nskb, trans_offset);
9562 +
9563 + /* We don't want the buffer to be recycled so we mark it accordingly */
9564 + nskb->mark = NONREC_MARK;
9565 +
9566 + dev_kfree_skb(skb);
9567 + return nskb;
9568 +
9569 +err:
9570 + if (nskb)
9571 + dev_kfree_skb(nskb);
9572 + put_page(npage);
9573 + return NULL;
9574 +}
9575 +#endif
9576 +
9577 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
9578 + struct sk_buff *skb, struct qm_fd *fd)
9579 +{
9580 + struct dpa_bp *dpa_bp = priv->dpa_bp;
9581 + dma_addr_t addr;
9582 + dma_addr_t sg_addr;
9583 + struct sk_buff **skbh;
9584 + struct net_device *net_dev = priv->net_dev;
9585 + int sg_len, sgt_size;
9586 + int err;
9587 +
9588 + struct qm_sg_entry *sgt;
9589 + void *sgt_buf;
9590 + skb_frag_t *frag;
9591 + int i = 0, j = 0;
9592 + int nr_frags;
9593 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
9594 +
9595 + nr_frags = skb_shinfo(skb)->nr_frags;
9596 + fd->format = qm_fd_sg;
9597 +
9598 + sgt_size = sizeof(struct qm_sg_entry) * (1 + nr_frags);
9599 +
9600 + /* Get a page frag to store the SGTable, or a full page if the errata
9601 + * is in place and we need to avoid crossing a 4k boundary.
9602 + */
9603 +#ifndef CONFIG_PPC
9604 + if (unlikely(dpaa_errata_a010022))
9605 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
9606 + else
9607 +#endif
9608 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
9609 + if (unlikely(!sgt_buf)) {
9610 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
9611 + return -ENOMEM;
9612 + }
9613 +
9614 + /* it seems that the memory allocator does not zero the allocated mem */
9615 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
9616 +
9617 + /* Enable L3/L4 hardware checksum computation.
9618 + *
9619 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
9620 + * need to write into the skb.
9621 + */
9622 + err = dpa_enable_tx_csum(priv, skb, fd,
9623 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
9624 + if (unlikely(err < 0)) {
9625 + if (netif_msg_tx_err(priv) && net_ratelimit())
9626 + netdev_err(net_dev, "HW csum error: %d\n", err);
9627 + goto csum_failed;
9628 + }
9629 +
9630 + /* Assign the data from skb->data to the first SG list entry */
9631 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
9632 + sg_len = skb_headlen(skb);
9633 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
9634 + qm_sg_entry_set_offset(&sgt[0], 0);
9635 + qm_sg_entry_set_len(&sgt[0], sg_len);
9636 + qm_sg_entry_set_ext(&sgt[0], 0);
9637 + qm_sg_entry_set_final(&sgt[0], 0);
9638 +
9639 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
9640 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9641 + dev_err(dpa_bp->dev, "DMA mapping failed");
9642 + err = -EINVAL;
9643 + goto sg0_map_failed;
9644 + }
9645 +
9646 + qm_sg_entry_set64(&sgt[0], addr);
9647 +
9648 + /* populate the rest of SGT entries */
9649 + for (i = 1; i <= nr_frags; i++) {
9650 + frag = &skb_shinfo(skb)->frags[i - 1];
9651 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
9652 + qm_sg_entry_set_offset(&sgt[i], 0);
9653 + qm_sg_entry_set_len(&sgt[i], frag->size);
9654 + qm_sg_entry_set_ext(&sgt[i], 0);
9655 +
9656 + if (i == nr_frags)
9657 + qm_sg_entry_set_final(&sgt[i], 1);
9658 + else
9659 + qm_sg_entry_set_final(&sgt[i], 0);
9660 +
9661 + DPA_BUG_ON(!skb_frag_page(frag));
9662 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
9663 + dma_dir);
9664 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9665 + dev_err(dpa_bp->dev, "DMA mapping failed");
9666 + err = -EINVAL;
9667 + goto sg_map_failed;
9668 + }
9669 +
9670 + /* keep the offset in the address */
9671 + qm_sg_entry_set64(&sgt[i], addr);
9672 + }
9673 +
9674 + fd->length20 = skb->len;
9675 + fd->offset = priv->tx_headroom;
9676 +
9677 + /* DMA map the SGT page
9678 + *
9679 + * It's safe to store the skb back-pointer inside the buffer since
9680 + * S/G frames are non-recyclable.
9681 + */
9682 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
9683 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
9684 + priv->tx_headroom + sgt_size,
9685 + dma_dir);
9686 +
9687 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9688 + dev_err(dpa_bp->dev, "DMA mapping failed");
9689 + err = -EINVAL;
9690 + goto sgt_map_failed;
9691 + }
9692 +
9693 + qm_fd_addr_set64(fd, addr);
9694 + fd->bpid = 0xff;
9695 + fd->cmd |= FM_FD_CMD_FCO;
9696 +
9697 + return 0;
9698 +
9699 +sgt_map_failed:
9700 +sg_map_failed:
9701 + for (j = 0; j < i; j++) {
9702 + sg_addr = qm_sg_addr(&sgt[j]);
9703 + dma_unmap_page(dpa_bp->dev, sg_addr,
9704 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
9705 + }
9706 +sg0_map_failed:
9707 +csum_failed:
9708 + put_page(virt_to_head_page(sgt_buf));
9709 +
9710 + return err;
9711 +}
9712 +EXPORT_SYMBOL(skb_to_sg_fd);
9713 +
9714 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
9715 +{
9716 + struct dpa_priv_s *priv;
9717 + const int queue_mapping = dpa_get_queue_mapping(skb);
9718 + struct qman_fq *egress_fq, *conf_fq;
9719 +
9720 +#ifdef CONFIG_FSL_DPAA_HOOKS
9721 + /* If there is a Tx hook, run it. */
9722 + if (dpaa_eth_hooks.tx &&
9723 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
9724 + /* won't update any Tx stats */
9725 + return NETDEV_TX_OK;
9726 +#endif
9727 +
9728 + priv = netdev_priv(net_dev);
9729 +
9730 +#ifdef CONFIG_FSL_DPAA_CEETM
9731 + if (priv->ceetm_en)
9732 + return ceetm_tx(skb, net_dev);
9733 +#endif
9734 +
9735 + egress_fq = priv->egress_fqs[queue_mapping];
9736 + conf_fq = priv->conf_fqs[queue_mapping];
9737 +
9738 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
9739 +}
9740 +
9741 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
9742 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
9743 +{
9744 + struct dpa_priv_s *priv;
9745 + struct qm_fd fd;
9746 + struct dpa_percpu_priv_s *percpu_priv;
9747 + struct rtnl_link_stats64 *percpu_stats;
9748 + int err = 0;
9749 + bool nonlinear;
9750 + int *countptr, offset = 0;
9751 +
9752 + priv = netdev_priv(net_dev);
9753 + /* Non-migratable context, safe to use raw_cpu_ptr */
9754 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
9755 + percpu_stats = &percpu_priv->stats;
9756 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
9757 +
9758 + clear_fd(&fd);
9759 +
9760 +#ifndef CONFIG_PPC
9761 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
9762 + skb = a010022_realign_skb(skb, priv);
9763 + if (!skb)
9764 + goto skb_to_fd_failed;
9765 + }
9766 +#endif
9767 +
9768 + nonlinear = skb_is_nonlinear(skb);
9769 +
9770 +#ifdef CONFIG_FSL_DPAA_1588
9771 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
9772 + fd.cmd |= FM_FD_CMD_UPD;
9773 +#endif
9774 +#ifdef CONFIG_FSL_DPAA_TS
9775 + if (unlikely(priv->ts_tx_en &&
9776 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
9777 + fd.cmd |= FM_FD_CMD_UPD;
9778 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
9779 +#endif /* CONFIG_FSL_DPAA_TS */
9780 +
9781 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
9782 + * we don't feed FMan with more fragments than it supports.
9783 + * Btw, we're using the first sgt entry to store the linear part of
9784 + * the skb, so we're one extra frag short.
9785 + */
9786 + if (nonlinear &&
9787 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
9788 + /* Just create a S/G fd based on the skb */
9789 + err = skb_to_sg_fd(priv, skb, &fd);
9790 + percpu_priv->tx_frag_skbuffs++;
9791 + } else {
9792 + /* Make sure we have enough headroom to accommodate private
9793 + * data, parse results, etc. Normally this shouldn't happen if
9794 + * we're here via the standard kernel stack.
9795 + */
9796 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
9797 + struct sk_buff *skb_new;
9798 +
9799 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
9800 + if (unlikely(!skb_new)) {
9801 + dev_kfree_skb(skb);
9802 + percpu_stats->tx_errors++;
9803 + return NETDEV_TX_OK;
9804 + }
9805 +
9806 + /* propagate the skb ownership information */
9807 + if (skb->sk)
9808 + skb_set_owner_w(skb_new, skb->sk);
9809 +
9810 + dev_kfree_skb(skb);
9811 + skb = skb_new;
9812 + }
9813 +
9814 + /* We're going to store the skb backpointer at the beginning
9815 + * of the data buffer, so we need a privately owned skb
9816 + */
9817 +
9818 + /* Code borrowed from skb_unshare(). */
9819 + if (skb_cloned(skb)) {
9820 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
9821 + kfree_skb(skb);
9822 + skb = nskb;
9823 +#ifndef CONFIG_PPC
9824 + if (unlikely(dpaa_errata_a010022) &&
9825 + a010022_check_skb(skb, priv)) {
9826 + skb = a010022_realign_skb(skb, priv);
9827 + if (!skb)
9828 + goto skb_to_fd_failed;
9829 + }
9830 +#endif
9831 + /* skb_copy() has now linearized the skbuff. */
9832 + } else if (unlikely(nonlinear)) {
9833 + /* We are here because the egress skb contains
9834 + * more fragments than we support. In this case,
9835 + * we have no choice but to linearize it ourselves.
9836 + */
9837 + err = __skb_linearize(skb);
9838 + }
9839 + if (unlikely(!skb || err < 0))
9840 + /* Common out-of-memory error path */
9841 + goto enomem;
9842 +
9843 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
9844 + }
9845 + if (unlikely(err < 0))
9846 + goto skb_to_fd_failed;
9847 +
9848 + if (fd.bpid != 0xff) {
9849 + skb_recycle(skb);
9850 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
9851 + * but we need the skb to look as if returned by build_skb().
9852 + * We need to manually adjust the tailptr as well.
9853 + */
9854 + skb->data = skb->head + offset;
9855 + skb_reset_tail_pointer(skb);
9856 +
9857 + (*countptr)++;
9858 + percpu_priv->tx_returned++;
9859 + }
9860 +
9861 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
9862 + goto xmit_failed;
9863 +
9864 + netif_trans_update(net_dev);
9865 + return NETDEV_TX_OK;
9866 +
9867 +xmit_failed:
9868 + if (fd.bpid != 0xff) {
9869 + (*countptr)--;
9870 + percpu_priv->tx_returned--;
9871 + dpa_fd_release(net_dev, &fd);
9872 + percpu_stats->tx_errors++;
9873 + return NETDEV_TX_OK;
9874 + }
9875 + _dpa_cleanup_tx_fd(priv, &fd);
9876 +skb_to_fd_failed:
9877 +enomem:
9878 + percpu_stats->tx_errors++;
9879 + dev_kfree_skb(skb);
9880 + return NETDEV_TX_OK;
9881 +}
9882 +EXPORT_SYMBOL(dpa_tx_extended);
9883 --- /dev/null
9884 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
9885 @@ -0,0 +1,278 @@
9886 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
9887 + *
9888 + * Redistribution and use in source and binary forms, with or without
9889 + * modification, are permitted provided that the following conditions are met:
9890 + * * Redistributions of source code must retain the above copyright
9891 + * notice, this list of conditions and the following disclaimer.
9892 + * * Redistributions in binary form must reproduce the above copyright
9893 + * notice, this list of conditions and the following disclaimer in the
9894 + * documentation and/or other materials provided with the distribution.
9895 + * * Neither the name of Freescale Semiconductor nor the
9896 + * names of its contributors may be used to endorse or promote products
9897 + * derived from this software without specific prior written permission.
9898 + *
9899 + *
9900 + * ALTERNATIVELY, this software may be distributed under the terms of the
9901 + * GNU General Public License ("GPL") as published by the Free Software
9902 + * Foundation, either version 2 of that License or (at your option) any
9903 + * later version.
9904 + *
9905 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9906 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9907 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9908 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
9909 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
9910 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9911 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
9912 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9913 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
9914 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9915 + */
9916 +
9917 +#include <linux/init.h>
9918 +#include <linux/module.h>
9919 +#include <linux/kthread.h>
9920 +#include <linux/io.h>
9921 +#include <linux/of_net.h>
9922 +#include "dpaa_eth.h"
9923 +#include "mac.h" /* struct mac_device */
9924 +#ifdef CONFIG_FSL_DPAA_1588
9925 +#include "dpaa_1588.h"
9926 +#endif
9927 +
9928 +static ssize_t dpaa_eth_show_addr(struct device *dev,
9929 + struct device_attribute *attr, char *buf)
9930 +{
9931 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9932 + struct mac_device *mac_dev = priv->mac_dev;
9933 +
9934 + if (mac_dev)
9935 + return sprintf(buf, "%llx",
9936 + (unsigned long long)mac_dev->res->start);
9937 + else
9938 + return sprintf(buf, "none");
9939 +}
9940 +
9941 +static ssize_t dpaa_eth_show_type(struct device *dev,
9942 + struct device_attribute *attr, char *buf)
9943 +{
9944 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9945 + ssize_t res = 0;
9946 +
9947 + if (priv)
9948 + res = sprintf(buf, "%s", priv->if_type);
9949 +
9950 + return res;
9951 +}
9952 +
9953 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
9954 + struct device_attribute *attr, char *buf)
9955 +{
9956 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
9957 + ssize_t bytes = 0;
9958 + int i = 0;
9959 + char *str;
9960 + struct dpa_fq *fq;
9961 + struct dpa_fq *tmp;
9962 + struct dpa_fq *prev = NULL;
9963 + u32 first_fqid = 0;
9964 + u32 last_fqid = 0;
9965 + char *prevstr = NULL;
9966 +
9967 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
9968 + switch (fq->fq_type) {
9969 + case FQ_TYPE_RX_DEFAULT:
9970 + str = "Rx default";
9971 + break;
9972 + case FQ_TYPE_RX_ERROR:
9973 + str = "Rx error";
9974 + break;
9975 + case FQ_TYPE_RX_PCD:
9976 + str = "Rx PCD";
9977 + break;
9978 + case FQ_TYPE_TX_CONFIRM:
9979 + str = "Tx default confirmation";
9980 + break;
9981 + case FQ_TYPE_TX_CONF_MQ:
9982 + str = "Tx confirmation (mq)";
9983 + break;
9984 + case FQ_TYPE_TX_ERROR:
9985 + str = "Tx error";
9986 + break;
9987 + case FQ_TYPE_TX:
9988 + str = "Tx";
9989 + break;
9990 + case FQ_TYPE_RX_PCD_HI_PRIO:
9991 + str ="Rx PCD High Priority";
9992 + break;
9993 + default:
9994 + str = "Unknown";
9995 + }
9996 +
9997 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
9998 + str != prevstr)) {
9999 + if (last_fqid == first_fqid)
10000 + bytes += sprintf(buf + bytes,
10001 + "%s: %d\n", prevstr, prev->fqid);
10002 + else
10003 + bytes += sprintf(buf + bytes,
10004 + "%s: %d - %d\n", prevstr,
10005 + first_fqid, last_fqid);
10006 + }
10007 +
10008 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
10009 + last_fqid = fq->fqid;
10010 + else
10011 + first_fqid = last_fqid = fq->fqid;
10012 +
10013 + prev = fq;
10014 + prevstr = str;
10015 + i++;
10016 + }
10017 +
10018 + if (prev) {
10019 + if (last_fqid == first_fqid)
10020 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
10021 + prev->fqid);
10022 + else
10023 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
10024 + first_fqid, last_fqid);
10025 + }
10026 +
10027 + return bytes;
10028 +}
10029 +
10030 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
10031 + struct device_attribute *attr, char *buf)
10032 +{
10033 + ssize_t bytes = 0;
10034 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10035 + struct dpa_bp *dpa_bp = priv->dpa_bp;
10036 + int i = 0;
10037 +
10038 + for (i = 0; i < priv->bp_count; i++)
10039 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
10040 + dpa_bp[i].bpid);
10041 +
10042 + return bytes;
10043 +}
10044 +
10045 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
10046 + struct device_attribute *attr, char *buf)
10047 +{
10048 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10049 + struct mac_device *mac_dev = priv->mac_dev;
10050 + int n = 0;
10051 +
10052 + if (mac_dev)
10053 + n = fm_mac_dump_regs(mac_dev, buf, n);
10054 + else
10055 + return sprintf(buf, "no mac registers\n");
10056 +
10057 + return n;
10058 +}
10059 +
10060 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
10061 + struct device_attribute *attr, char *buf)
10062 +{
10063 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10064 + struct mac_device *mac_dev = priv->mac_dev;
10065 + int n = 0;
10066 +
10067 + if (mac_dev)
10068 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
10069 + else
10070 + return sprintf(buf, "no mac rx stats\n");
10071 +
10072 + return n;
10073 +}
10074 +
10075 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
10076 + struct device_attribute *attr, char *buf)
10077 +{
10078 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10079 + struct mac_device *mac_dev = priv->mac_dev;
10080 + int n = 0;
10081 +
10082 + if (mac_dev)
10083 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
10084 + else
10085 + return sprintf(buf, "no mac tx stats\n");
10086 +
10087 + return n;
10088 +}
10089 +
10090 +#ifdef CONFIG_FSL_DPAA_1588
10091 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
10092 + struct device_attribute *attr, char *buf)
10093 +{
10094 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10095 +
10096 + if (priv->tsu && priv->tsu->valid)
10097 + return sprintf(buf, "1\n");
10098 + else
10099 + return sprintf(buf, "0\n");
10100 +}
10101 +
10102 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
10103 + struct device_attribute *attr,
10104 + const char *buf, size_t count)
10105 +{
10106 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
10107 + unsigned int num;
10108 + unsigned long flags;
10109 +
10110 + if (kstrtouint(buf, 0, &num) < 0)
10111 + return -EINVAL;
10112 +
10113 + local_irq_save(flags);
10114 +
10115 + if (num) {
10116 + if (priv->tsu)
10117 + priv->tsu->valid = TRUE;
10118 + } else {
10119 + if (priv->tsu)
10120 + priv->tsu->valid = FALSE;
10121 + }
10122 +
10123 + local_irq_restore(flags);
10124 +
10125 + return count;
10126 +}
10127 +#endif
10128 +
10129 +static struct device_attribute dpaa_eth_attrs[] = {
10130 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
10131 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
10132 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
10133 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
10134 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
10135 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
10136 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
10137 +#ifdef CONFIG_FSL_DPAA_1588
10138 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
10139 + dpaa_eth_set_ptp_1588),
10140 +#endif
10141 +};
10142 +
10143 +void dpaa_eth_sysfs_init(struct device *dev)
10144 +{
10145 + int i;
10146 +
10147 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10148 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
10149 + dev_err(dev, "Error creating sysfs file\n");
10150 + while (i > 0)
10151 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
10152 + return;
10153 + }
10154 +}
10155 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
10156 +
10157 +void dpaa_eth_sysfs_remove(struct device *dev)
10158 +{
10159 + int i;
10160 +
10161 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
10162 + device_remove_file(dev, &dpaa_eth_attrs[i]);
10163 +}
10164 --- /dev/null
10165 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
10166 @@ -0,0 +1,144 @@
10167 +/* Copyright 2013 Freescale Semiconductor Inc.
10168 + *
10169 + * Redistribution and use in source and binary forms, with or without
10170 + * modification, are permitted provided that the following conditions are met:
10171 + * * Redistributions of source code must retain the above copyright
10172 + * notice, this list of conditions and the following disclaimer.
10173 + * * Redistributions in binary form must reproduce the above copyright
10174 + * notice, this list of conditions and the following disclaimer in the
10175 + * documentation and/or other materials provided with the distribution.
10176 + * * Neither the name of Freescale Semiconductor nor the
10177 + * names of its contributors may be used to endorse or promote products
10178 + * derived from this software without specific prior written permission.
10179 + *
10180 + *
10181 + * ALTERNATIVELY, this software may be distributed under the terms of the
10182 + * GNU General Public License ("GPL") as published by the Free Software
10183 + * Foundation, either version 2 of that License or (at your option) any
10184 + * later version.
10185 + *
10186 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10187 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10188 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10189 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10190 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10191 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10192 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10193 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10194 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10195 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10196 + */
10197 +
10198 +#undef TRACE_SYSTEM
10199 +#define TRACE_SYSTEM dpaa_eth
10200 +
10201 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
10202 +#define _DPAA_ETH_TRACE_H
10203 +
10204 +#include <linux/skbuff.h>
10205 +#include <linux/netdevice.h>
10206 +#include "dpaa_eth.h"
10207 +#include <linux/tracepoint.h>
10208 +
10209 +#define fd_format_name(format) { qm_fd_##format, #format }
10210 +#define fd_format_list \
10211 + fd_format_name(contig), \
10212 + fd_format_name(sg)
10213 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
10214 + " status=0x%08x"
10215 +
10216 +/* This is used to declare a class of events.
10217 + * individual events of this type will be defined below.
10218 + */
10219 +
10220 +/* Store details about a frame descriptor and the FQ on which it was
10221 + * transmitted/received.
10222 + */
10223 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
10224 + /* Trace function prototype */
10225 + TP_PROTO(struct net_device *netdev,
10226 + struct qman_fq *fq,
10227 + const struct qm_fd *fd),
10228 +
10229 + /* Repeat argument list here */
10230 + TP_ARGS(netdev, fq, fd),
10231 +
10232 + /* A structure containing the relevant information we want to record.
10233 + * Declare name and type for each normal element, name, type and size
10234 + * for arrays. Use __string for variable length strings.
10235 + */
10236 + TP_STRUCT__entry(
10237 + __field(u32, fqid)
10238 + __field(u64, fd_addr)
10239 + __field(u8, fd_format)
10240 + __field(u16, fd_offset)
10241 + __field(u32, fd_length)
10242 + __field(u32, fd_status)
10243 + __string(name, netdev->name)
10244 + ),
10245 +
10246 + /* The function that assigns values to the above declared fields */
10247 + TP_fast_assign(
10248 + __entry->fqid = fq->fqid;
10249 + __entry->fd_addr = qm_fd_addr_get64(fd);
10250 + __entry->fd_format = fd->format;
10251 + __entry->fd_offset = dpa_fd_offset(fd);
10252 + __entry->fd_length = dpa_fd_length(fd);
10253 + __entry->fd_status = fd->status;
10254 + __assign_str(name, netdev->name);
10255 + ),
10256 +
10257 + /* This is what gets printed when the trace event is triggered */
10258 + /* TODO: print the status using __print_flags() */
10259 + TP_printk(TR_FMT,
10260 + __get_str(name), __entry->fqid, __entry->fd_addr,
10261 + __print_symbolic(__entry->fd_format, fd_format_list),
10262 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
10263 +);
10264 +
10265 +/* Now declare events of the above type. Format is:
10266 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
10267 + */
10268 +
10269 +/* Tx (egress) fd */
10270 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
10271 +
10272 + TP_PROTO(struct net_device *netdev,
10273 + struct qman_fq *fq,
10274 + const struct qm_fd *fd),
10275 +
10276 + TP_ARGS(netdev, fq, fd)
10277 +);
10278 +
10279 +/* Rx fd */
10280 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
10281 +
10282 + TP_PROTO(struct net_device *netdev,
10283 + struct qman_fq *fq,
10284 + const struct qm_fd *fd),
10285 +
10286 + TP_ARGS(netdev, fq, fd)
10287 +);
10288 +
10289 +/* Tx confirmation fd */
10290 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
10291 +
10292 + TP_PROTO(struct net_device *netdev,
10293 + struct qman_fq *fq,
10294 + const struct qm_fd *fd),
10295 +
10296 + TP_ARGS(netdev, fq, fd)
10297 +);
10298 +
10299 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
10300 + * The syntax is the same as for DECLARE_EVENT_CLASS().
10301 + */
10302 +
10303 +#endif /* _DPAA_ETH_TRACE_H */
10304 +
10305 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
10306 +#undef TRACE_INCLUDE_PATH
10307 +#define TRACE_INCLUDE_PATH .
10308 +#undef TRACE_INCLUDE_FILE
10309 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
10310 +#include <trace/define_trace.h>
10311 --- /dev/null
10312 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
10313 @@ -0,0 +1,544 @@
10314 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
10315 + *
10316 + * Redistribution and use in source and binary forms, with or without
10317 + * modification, are permitted provided that the following conditions are met:
10318 + * * Redistributions of source code must retain the above copyright
10319 + * notice, this list of conditions and the following disclaimer.
10320 + * * Redistributions in binary form must reproduce the above copyright
10321 + * notice, this list of conditions and the following disclaimer in the
10322 + * documentation and/or other materials provided with the distribution.
10323 + * * Neither the name of Freescale Semiconductor nor the
10324 + * names of its contributors may be used to endorse or promote products
10325 + * derived from this software without specific prior written permission.
10326 + *
10327 + *
10328 + * ALTERNATIVELY, this software may be distributed under the terms of the
10329 + * GNU General Public License ("GPL") as published by the Free Software
10330 + * Foundation, either version 2 of that License or (at your option) any
10331 + * later version.
10332 + *
10333 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10334 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10335 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10336 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10337 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10338 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10339 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10340 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10341 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10342 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10343 + */
10344 +
10345 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10346 +#define pr_fmt(fmt) \
10347 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10348 + KBUILD_BASENAME".c", __LINE__, __func__
10349 +#else
10350 +#define pr_fmt(fmt) \
10351 + KBUILD_MODNAME ": " fmt
10352 +#endif
10353 +
10354 +#include <linux/string.h>
10355 +
10356 +#include "dpaa_eth.h"
10357 +#include "mac.h" /* struct mac_device */
10358 +#include "dpaa_eth_common.h"
10359 +
10360 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
10361 + "interrupts",
10362 + "rx packets",
10363 + "tx packets",
10364 + "tx recycled",
10365 + "tx confirm",
10366 + "tx S/G",
10367 + "rx S/G",
10368 + "tx error",
10369 + "rx error",
10370 + "bp count"
10371 +};
10372 +
10373 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
10374 + /* dpa rx errors */
10375 + "rx dma error",
10376 + "rx frame physical error",
10377 + "rx frame size error",
10378 + "rx header error",
10379 + "rx csum error",
10380 +
10381 + /* demultiplexing errors */
10382 + "qman cg_tdrop",
10383 + "qman wred",
10384 + "qman error cond",
10385 + "qman early window",
10386 + "qman late window",
10387 + "qman fq tdrop",
10388 + "qman fq retired",
10389 + "qman orp disabled",
10390 +
10391 + /* congestion related stats */
10392 + "congestion time (ms)",
10393 + "entered congestion",
10394 + "congested (0/1)"
10395 +};
10396 +
10397 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
10398 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
10399 +
10400 +static int __cold dpa_get_settings(struct net_device *net_dev,
10401 + struct ethtool_cmd *et_cmd)
10402 +{
10403 + int _errno;
10404 + struct dpa_priv_s *priv;
10405 +
10406 + priv = netdev_priv(net_dev);
10407 +
10408 + if (priv->mac_dev == NULL) {
10409 + netdev_info(net_dev, "This is a MAC-less interface\n");
10410 + return -ENODEV;
10411 + }
10412 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10413 + netdev_dbg(net_dev, "phy device not initialized\n");
10414 + return 0;
10415 + }
10416 +
10417 + _errno = phy_ethtool_gset(priv->mac_dev->phy_dev, et_cmd);
10418 + if (unlikely(_errno < 0))
10419 + netdev_err(net_dev, "phy_ethtool_gset() = %d\n", _errno);
10420 +
10421 + return _errno;
10422 +}
10423 +
10424 +static int __cold dpa_set_settings(struct net_device *net_dev,
10425 + struct ethtool_cmd *et_cmd)
10426 +{
10427 + int _errno;
10428 + struct dpa_priv_s *priv;
10429 +
10430 + priv = netdev_priv(net_dev);
10431 +
10432 + if (priv->mac_dev == NULL) {
10433 + netdev_info(net_dev, "This is a MAC-less interface\n");
10434 + return -ENODEV;
10435 + }
10436 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10437 + netdev_err(net_dev, "phy device not initialized\n");
10438 + return -ENODEV;
10439 + }
10440 +
10441 + _errno = phy_ethtool_sset(priv->mac_dev->phy_dev, et_cmd);
10442 + if (unlikely(_errno < 0))
10443 + netdev_err(net_dev, "phy_ethtool_sset() = %d\n", _errno);
10444 +
10445 + return _errno;
10446 +}
10447 +
10448 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
10449 + struct ethtool_drvinfo *drvinfo)
10450 +{
10451 + int _errno;
10452 +
10453 + strncpy(drvinfo->driver, KBUILD_MODNAME,
10454 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
10455 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
10456 + "%X", 0);
10457 +
10458 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
10459 + /* Truncated output */
10460 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
10461 + } else if (unlikely(_errno < 0)) {
10462 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
10463 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
10464 + }
10465 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
10466 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
10467 +}
10468 +
10469 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
10470 +{
10471 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
10472 +}
10473 +
10474 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
10475 + uint32_t msg_enable)
10476 +{
10477 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
10478 +}
10479 +
10480 +static int __cold dpa_nway_reset(struct net_device *net_dev)
10481 +{
10482 + int _errno;
10483 + struct dpa_priv_s *priv;
10484 +
10485 + priv = netdev_priv(net_dev);
10486 +
10487 + if (priv->mac_dev == NULL) {
10488 + netdev_info(net_dev, "This is a MAC-less interface\n");
10489 + return -ENODEV;
10490 + }
10491 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10492 + netdev_err(net_dev, "phy device not initialized\n");
10493 + return -ENODEV;
10494 + }
10495 +
10496 + _errno = 0;
10497 + if (priv->mac_dev->phy_dev->autoneg) {
10498 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
10499 + if (unlikely(_errno < 0))
10500 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10501 + _errno);
10502 + }
10503 +
10504 + return _errno;
10505 +}
10506 +
10507 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
10508 + struct ethtool_pauseparam *epause)
10509 +{
10510 + struct dpa_priv_s *priv;
10511 + struct mac_device *mac_dev;
10512 + struct phy_device *phy_dev;
10513 +
10514 + priv = netdev_priv(net_dev);
10515 + mac_dev = priv->mac_dev;
10516 +
10517 + if (mac_dev == NULL) {
10518 + netdev_info(net_dev, "This is a MAC-less interface\n");
10519 + return;
10520 + }
10521 +
10522 + phy_dev = mac_dev->phy_dev;
10523 + if (unlikely(phy_dev == NULL)) {
10524 + netdev_err(net_dev, "phy device not initialized\n");
10525 + return;
10526 + }
10527 +
10528 + epause->autoneg = mac_dev->autoneg_pause;
10529 + epause->rx_pause = mac_dev->rx_pause_active;
10530 + epause->tx_pause = mac_dev->tx_pause_active;
10531 +}
10532 +
10533 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
10534 + struct ethtool_pauseparam *epause)
10535 +{
10536 + struct dpa_priv_s *priv;
10537 + struct mac_device *mac_dev;
10538 + struct phy_device *phy_dev;
10539 + int _errno;
10540 + u32 newadv, oldadv;
10541 + bool rx_pause, tx_pause;
10542 +
10543 + priv = netdev_priv(net_dev);
10544 + mac_dev = priv->mac_dev;
10545 +
10546 + if (mac_dev == NULL) {
10547 + netdev_info(net_dev, "This is a MAC-less interface\n");
10548 + return -ENODEV;
10549 + }
10550 +
10551 + phy_dev = mac_dev->phy_dev;
10552 + if (unlikely(phy_dev == NULL)) {
10553 + netdev_err(net_dev, "phy device not initialized\n");
10554 + return -ENODEV;
10555 + }
10556 +
10557 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
10558 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
10559 + (epause->rx_pause != epause->tx_pause)))
10560 + return -EINVAL;
10561 +
10562 + /* The MAC should know how to handle PAUSE frame autonegotiation before
10563 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
10564 + * settings.
10565 + */
10566 + mac_dev->autoneg_pause = !!epause->autoneg;
10567 + mac_dev->rx_pause_req = !!epause->rx_pause;
10568 + mac_dev->tx_pause_req = !!epause->tx_pause;
10569 +
10570 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
10571 + * rx/tx pause settings.
10572 + */
10573 + newadv = 0;
10574 + if (epause->rx_pause)
10575 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
10576 + if (epause->tx_pause)
10577 + newadv |= ADVERTISED_Asym_Pause;
10578 +
10579 + oldadv = phy_dev->advertising &
10580 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
10581 +
10582 + /* If there are differences between the old and the new advertised
10583 + * values, restart PHY autonegotiation and advertise the new values.
10584 + */
10585 + if (oldadv != newadv) {
10586 + phy_dev->advertising &= ~(ADVERTISED_Pause
10587 + | ADVERTISED_Asym_Pause);
10588 + phy_dev->advertising |= newadv;
10589 + if (phy_dev->autoneg) {
10590 + _errno = phy_start_aneg(phy_dev);
10591 + if (unlikely(_errno < 0))
10592 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
10593 + _errno);
10594 + }
10595 + }
10596 +
10597 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
10598 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
10599 + if (unlikely(_errno < 0))
10600 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
10601 +
10602 + return _errno;
10603 +}
10604 +
10605 +#ifdef CONFIG_PM
10606 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10607 +{
10608 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10609 +
10610 + wol->supported = 0;
10611 + wol->wolopts = 0;
10612 +
10613 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
10614 + return;
10615 +
10616 + if (priv->wol & DPAA_WOL_MAGIC) {
10617 + wol->supported = WAKE_MAGIC;
10618 + wol->wolopts = WAKE_MAGIC;
10619 + }
10620 +}
10621 +
10622 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
10623 +{
10624 + struct dpa_priv_s *priv = netdev_priv(net_dev);
10625 +
10626 + if (priv->mac_dev == NULL) {
10627 + netdev_info(net_dev, "This is a MAC-less interface\n");
10628 + return -ENODEV;
10629 + }
10630 +
10631 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10632 + netdev_dbg(net_dev, "phy device not initialized\n");
10633 + return -ENODEV;
10634 + }
10635 +
10636 + if (!device_can_wakeup(net_dev->dev.parent) ||
10637 + (wol->wolopts & ~WAKE_MAGIC))
10638 + return -EOPNOTSUPP;
10639 +
10640 + priv->wol = 0;
10641 +
10642 + if (wol->wolopts & WAKE_MAGIC) {
10643 + priv->wol = DPAA_WOL_MAGIC;
10644 + device_set_wakeup_enable(net_dev->dev.parent, 1);
10645 + } else {
10646 + device_set_wakeup_enable(net_dev->dev.parent, 0);
10647 + }
10648 +
10649 + return 0;
10650 +}
10651 +#endif
10652 +
10653 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10654 +{
10655 + struct dpa_priv_s *priv;
10656 +
10657 + priv = netdev_priv(net_dev);
10658 + if (priv->mac_dev == NULL) {
10659 + netdev_info(net_dev, "This is a MAC-less interface\n");
10660 + return -ENODEV;
10661 + }
10662 +
10663 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10664 + netdev_err(net_dev, "phy device not initialized\n");
10665 + return -ENODEV;
10666 + }
10667 +
10668 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
10669 +}
10670 +
10671 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
10672 +{
10673 + struct dpa_priv_s *priv;
10674 +
10675 + priv = netdev_priv(net_dev);
10676 + if (priv->mac_dev == NULL) {
10677 + netdev_info(net_dev, "This is a MAC-less interface\n");
10678 + return -ENODEV;
10679 + }
10680 +
10681 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
10682 + netdev_err(net_dev, "phy device not initialized\n");
10683 + return -ENODEV;
10684 + }
10685 +
10686 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
10687 +}
10688 +
10689 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
10690 +{
10691 + unsigned int total_stats, num_stats;
10692 +
10693 + num_stats = num_online_cpus() + 1;
10694 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
10695 +
10696 + switch (type) {
10697 + case ETH_SS_STATS:
10698 + return total_stats;
10699 + default:
10700 + return -EOPNOTSUPP;
10701 + }
10702 +}
10703 +
10704 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
10705 + int crr_cpu, u64 bp_count, u64 *data)
10706 +{
10707 + int num_stat_values = num_cpus + 1;
10708 + int crr_stat = 0;
10709 +
10710 + /* update current CPU's stats and also add them to the total values */
10711 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
10712 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
10713 +
10714 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
10715 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
10716 +
10717 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
10718 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
10719 +
10720 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
10721 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
10722 +
10723 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
10724 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
10725 +
10726 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
10727 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
10728 +
10729 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
10730 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
10731 +
10732 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
10733 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
10734 +
10735 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
10736 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
10737 +
10738 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
10739 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
10740 +}
10741 +
10742 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
10743 + struct ethtool_stats *stats, u64 *data)
10744 +{
10745 + u64 bp_count, cg_time, cg_num, cg_status;
10746 + struct dpa_percpu_priv_s *percpu_priv;
10747 + struct qm_mcr_querycgr query_cgr;
10748 + struct dpa_rx_errors rx_errors;
10749 + struct dpa_ern_cnt ern_cnt;
10750 + struct dpa_priv_s *priv;
10751 + unsigned int num_cpus, offset;
10752 + struct dpa_bp *dpa_bp;
10753 + int total_stats, i;
10754 +
10755 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
10756 + priv = netdev_priv(net_dev);
10757 + dpa_bp = priv->dpa_bp;
10758 + num_cpus = num_online_cpus();
10759 + bp_count = 0;
10760 +
10761 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
10762 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
10763 + memset(data, 0, total_stats * sizeof(u64));
10764 +
10765 + for_each_online_cpu(i) {
10766 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
10767 +
10768 + if (dpa_bp->percpu_count)
10769 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
10770 +
10771 + rx_errors.dme += percpu_priv->rx_errors.dme;
10772 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
10773 + rx_errors.fse += percpu_priv->rx_errors.fse;
10774 + rx_errors.phe += percpu_priv->rx_errors.phe;
10775 + rx_errors.cse += percpu_priv->rx_errors.cse;
10776 +
10777 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
10778 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
10779 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
10780 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
10781 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
10782 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
10783 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
10784 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
10785 +
10786 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
10787 + }
10788 +
10789 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
10790 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
10791 +
10792 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
10793 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
10794 +
10795 + /* gather congestion related counters */
10796 + cg_num = 0;
10797 + cg_status = 0;
10798 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
10799 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
10800 + cg_num = priv->cgr_data.cgr_congested_count;
10801 + cg_status = query_cgr.cgr.cs;
10802 +
10803 + /* reset congestion stats (like QMan API does */
10804 + priv->cgr_data.congested_jiffies = 0;
10805 + priv->cgr_data.cgr_congested_count = 0;
10806 + }
10807 +
10808 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
10809 + data[offset++] = cg_time;
10810 + data[offset++] = cg_num;
10811 + data[offset++] = cg_status;
10812 +}
10813 +
10814 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
10815 +{
10816 + unsigned int i, j, num_cpus, size;
10817 + char stat_string_cpu[ETH_GSTRING_LEN];
10818 + u8 *strings;
10819 +
10820 + strings = data;
10821 + num_cpus = num_online_cpus();
10822 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
10823 +
10824 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
10825 + for (j = 0; j < num_cpus; j++) {
10826 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
10827 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10828 + strings += ETH_GSTRING_LEN;
10829 + }
10830 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
10831 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
10832 + strings += ETH_GSTRING_LEN;
10833 + }
10834 + memcpy(strings, dpa_stats_global, size);
10835 +}
10836 +
10837 +const struct ethtool_ops dpa_ethtool_ops = {
10838 + .get_settings = dpa_get_settings,
10839 + .set_settings = dpa_set_settings,
10840 + .get_drvinfo = dpa_get_drvinfo,
10841 + .get_msglevel = dpa_get_msglevel,
10842 + .set_msglevel = dpa_set_msglevel,
10843 + .nway_reset = dpa_nway_reset,
10844 + .get_pauseparam = dpa_get_pauseparam,
10845 + .set_pauseparam = dpa_set_pauseparam,
10846 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
10847 + .get_link = ethtool_op_get_link,
10848 + .get_eee = dpa_get_eee,
10849 + .set_eee = dpa_set_eee,
10850 + .get_sset_count = dpa_get_sset_count,
10851 + .get_ethtool_stats = dpa_get_ethtool_stats,
10852 + .get_strings = dpa_get_strings,
10853 +#ifdef CONFIG_PM
10854 + .get_wol = dpa_get_wol,
10855 + .set_wol = dpa_set_wol,
10856 +#endif
10857 +};
10858 --- /dev/null
10859 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ptp.c
10860 @@ -0,0 +1,291 @@
10861 +/*
10862 + * DPAA Ethernet Driver -- PTP 1588 clock using the dTSEC
10863 + *
10864 + * Author: Yangbo Lu <yangbo.lu@freescale.com>
10865 + *
10866 + * Copyright 2014 Freescale Semiconductor, Inc.
10867 + *
10868 + * This program is free software; you can redistribute it and/or modify it
10869 + * under the terms of the GNU General Public License as published by the
10870 + * Free Software Foundation; either version 2 of the License, or (at your
10871 + * option) any later version.
10872 +*/
10873 +
10874 +#include <linux/device.h>
10875 +#include <linux/hrtimer.h>
10876 +#include <linux/init.h>
10877 +#include <linux/interrupt.h>
10878 +#include <linux/kernel.h>
10879 +#include <linux/module.h>
10880 +#include <linux/of.h>
10881 +#include <linux/of_platform.h>
10882 +#include <linux/timex.h>
10883 +#include <linux/io.h>
10884 +
10885 +#include <linux/ptp_clock_kernel.h>
10886 +
10887 +#include "dpaa_eth.h"
10888 +#include "mac.h"
10889 +
10890 +static struct mac_device *mac_dev;
10891 +static u32 freqCompensation;
10892 +
10893 +/* Bit definitions for the TMR_CTRL register */
10894 +#define ALM1P (1<<31) /* Alarm1 output polarity */
10895 +#define ALM2P (1<<30) /* Alarm2 output polarity */
10896 +#define FS (1<<28) /* FIPER start indication */
10897 +#define PP1L (1<<27) /* Fiper1 pulse loopback mode enabled. */
10898 +#define PP2L (1<<26) /* Fiper2 pulse loopback mode enabled. */
10899 +#define TCLK_PERIOD_SHIFT (16) /* 1588 timer reference clock period. */
10900 +#define TCLK_PERIOD_MASK (0x3ff)
10901 +#define RTPE (1<<15) /* Record Tx Timestamp to PAL Enable. */
10902 +#define FRD (1<<14) /* FIPER Realignment Disable */
10903 +#define ESFDP (1<<11) /* External Tx/Rx SFD Polarity. */
10904 +#define ESFDE (1<<10) /* External Tx/Rx SFD Enable. */
10905 +#define ETEP2 (1<<9) /* External trigger 2 edge polarity */
10906 +#define ETEP1 (1<<8) /* External trigger 1 edge polarity */
10907 +#define COPH (1<<7) /* Generated clock output phase. */
10908 +#define CIPH (1<<6) /* External oscillator input clock phase */
10909 +#define TMSR (1<<5) /* Timer soft reset. */
10910 +#define BYP (1<<3) /* Bypass drift compensated clock */
10911 +#define TE (1<<2) /* 1588 timer enable. */
10912 +#define CKSEL_SHIFT (0) /* 1588 Timer reference clock source */
10913 +#define CKSEL_MASK (0x3)
10914 +
10915 +/* Bit definitions for the TMR_TEVENT register */
10916 +#define ETS2 (1<<25) /* External trigger 2 timestamp sampled */
10917 +#define ETS1 (1<<24) /* External trigger 1 timestamp sampled */
10918 +#define ALM2 (1<<17) /* Current time = alarm time register 2 */
10919 +#define ALM1 (1<<16) /* Current time = alarm time register 1 */
10920 +#define PP1 (1<<7) /* periodic pulse generated on FIPER1 */
10921 +#define PP2 (1<<6) /* periodic pulse generated on FIPER2 */
10922 +#define PP3 (1<<5) /* periodic pulse generated on FIPER3 */
10923 +
10924 +/* Bit definitions for the TMR_TEMASK register */
10925 +#define ETS2EN (1<<25) /* External trigger 2 timestamp enable */
10926 +#define ETS1EN (1<<24) /* External trigger 1 timestamp enable */
10927 +#define ALM2EN (1<<17) /* Timer ALM2 event enable */
10928 +#define ALM1EN (1<<16) /* Timer ALM1 event enable */
10929 +#define PP1EN (1<<7) /* Periodic pulse event 1 enable */
10930 +#define PP2EN (1<<6) /* Periodic pulse event 2 enable */
10931 +
10932 +/* Bit definitions for the TMR_PEVENT register */
10933 +#define TXP2 (1<<9) /* PTP transmitted timestamp im TXTS2 */
10934 +#define TXP1 (1<<8) /* PTP transmitted timestamp in TXTS1 */
10935 +#define RXP (1<<0) /* PTP frame has been received */
10936 +
10937 +/* Bit definitions for the TMR_PEMASK register */
10938 +#define TXP2EN (1<<9) /* Transmit PTP packet event 2 enable */
10939 +#define TXP1EN (1<<8) /* Transmit PTP packet event 1 enable */
10940 +#define RXPEN (1<<0) /* Receive PTP packet event enable */
10941 +
10942 +/* Bit definitions for the TMR_STAT register */
10943 +#define STAT_VEC_SHIFT (0) /* Timer general purpose status vector */
10944 +#define STAT_VEC_MASK (0x3f)
10945 +
10946 +/* Bit definitions for the TMR_PRSC register */
10947 +#define PRSC_OCK_SHIFT (0) /* Output clock division/prescale factor. */
10948 +#define PRSC_OCK_MASK (0xffff)
10949 +
10950 +
10951 +#define N_EXT_TS 2
10952 +
10953 +static void set_alarm(void)
10954 +{
10955 + u64 ns;
10956 +
10957 + if (mac_dev->fm_rtc_get_cnt)
10958 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
10959 + ns += 1500000000ULL;
10960 + ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
10961 + ns -= DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10962 + if (mac_dev->fm_rtc_set_alarm)
10963 + mac_dev->fm_rtc_set_alarm(mac_dev->fm_dev, 0, ns);
10964 +}
10965 +
10966 +static void set_fipers(void)
10967 +{
10968 + u64 fiper;
10969 +
10970 + if (mac_dev->fm_rtc_disable)
10971 + mac_dev->fm_rtc_disable(mac_dev->fm_dev);
10972 +
10973 + set_alarm();
10974 + fiper = 1000000000ULL - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
10975 + if (mac_dev->fm_rtc_set_fiper)
10976 + mac_dev->fm_rtc_set_fiper(mac_dev->fm_dev, 0, fiper);
10977 +
10978 + if (mac_dev->fm_rtc_enable)
10979 + mac_dev->fm_rtc_enable(mac_dev->fm_dev);
10980 +}
10981 +
10982 +/* PTP clock operations */
10983 +
10984 +static int ptp_dpa_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
10985 +{
10986 + u64 adj;
10987 + u32 diff, tmr_add;
10988 + int neg_adj = 0;
10989 +
10990 + if (ppb < 0) {
10991 + neg_adj = 1;
10992 + ppb = -ppb;
10993 + }
10994 +
10995 + tmr_add = freqCompensation;
10996 + adj = tmr_add;
10997 + adj *= ppb;
10998 + diff = div_u64(adj, 1000000000ULL);
10999 +
11000 + tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
11001 +
11002 + if (mac_dev->fm_rtc_set_drift)
11003 + mac_dev->fm_rtc_set_drift(mac_dev->fm_dev, tmr_add);
11004 +
11005 + return 0;
11006 +}
11007 +
11008 +static int ptp_dpa_adjtime(struct ptp_clock_info *ptp, s64 delta)
11009 +{
11010 + s64 now;
11011 +
11012 + if (mac_dev->fm_rtc_get_cnt)
11013 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &now);
11014 +
11015 + now += delta;
11016 +
11017 + if (mac_dev->fm_rtc_set_cnt)
11018 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, now);
11019 + set_fipers();
11020 +
11021 + return 0;
11022 +}
11023 +
11024 +static int ptp_dpa_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
11025 +{
11026 + u64 ns;
11027 + u32 remainder;
11028 +
11029 + if (mac_dev->fm_rtc_get_cnt)
11030 + mac_dev->fm_rtc_get_cnt(mac_dev->fm_dev, &ns);
11031 +
11032 + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
11033 + ts->tv_nsec = remainder;
11034 + return 0;
11035 +}
11036 +
11037 +static int ptp_dpa_settime(struct ptp_clock_info *ptp,
11038 + const struct timespec64 *ts)
11039 +{
11040 + u64 ns;
11041 +
11042 + ns = ts->tv_sec * 1000000000ULL;
11043 + ns += ts->tv_nsec;
11044 +
11045 + if (mac_dev->fm_rtc_set_cnt)
11046 + mac_dev->fm_rtc_set_cnt(mac_dev->fm_dev, ns);
11047 + set_fipers();
11048 + return 0;
11049 +}
11050 +
11051 +static int ptp_dpa_enable(struct ptp_clock_info *ptp,
11052 + struct ptp_clock_request *rq, int on)
11053 +{
11054 + u32 bit;
11055 +
11056 + switch (rq->type) {
11057 + case PTP_CLK_REQ_EXTTS:
11058 + switch (rq->extts.index) {
11059 + case 0:
11060 + bit = ETS1EN;
11061 + break;
11062 + case 1:
11063 + bit = ETS2EN;
11064 + break;
11065 + default:
11066 + return -EINVAL;
11067 + }
11068 + if (on) {
11069 + if (mac_dev->fm_rtc_enable_interrupt)
11070 + mac_dev->fm_rtc_enable_interrupt(
11071 + mac_dev->fm_dev, bit);
11072 + } else {
11073 + if (mac_dev->fm_rtc_disable_interrupt)
11074 + mac_dev->fm_rtc_disable_interrupt(
11075 + mac_dev->fm_dev, bit);
11076 + }
11077 + return 0;
11078 +
11079 + case PTP_CLK_REQ_PPS:
11080 + if (on) {
11081 + if (mac_dev->fm_rtc_enable_interrupt)
11082 + mac_dev->fm_rtc_enable_interrupt(
11083 + mac_dev->fm_dev, PP1EN);
11084 + } else {
11085 + if (mac_dev->fm_rtc_disable_interrupt)
11086 + mac_dev->fm_rtc_disable_interrupt(
11087 + mac_dev->fm_dev, PP1EN);
11088 + }
11089 + return 0;
11090 +
11091 + default:
11092 + break;
11093 + }
11094 +
11095 + return -EOPNOTSUPP;
11096 +}
11097 +
11098 +static struct ptp_clock_info ptp_dpa_caps = {
11099 + .owner = THIS_MODULE,
11100 + .name = "dpaa clock",
11101 + .max_adj = 512000,
11102 + .n_alarm = 0,
11103 + .n_ext_ts = N_EXT_TS,
11104 + .n_per_out = 0,
11105 + .pps = 1,
11106 + .adjfreq = ptp_dpa_adjfreq,
11107 + .adjtime = ptp_dpa_adjtime,
11108 + .gettime64 = ptp_dpa_gettime,
11109 + .settime64 = ptp_dpa_settime,
11110 + .enable = ptp_dpa_enable,
11111 +};
11112 +
11113 +static int __init __cold dpa_ptp_load(void)
11114 +{
11115 + struct device *ptp_dev;
11116 + struct timespec64 now;
11117 + struct ptp_clock *clock = ptp_priv.clock;
11118 + int dpa_phc_index;
11119 + int err;
11120 +
11121 + if (!(ptp_priv.of_dev && ptp_priv.mac_dev))
11122 + return -ENODEV;
11123 +
11124 + ptp_dev = &ptp_priv.of_dev->dev;
11125 + mac_dev = ptp_priv.mac_dev;
11126 +
11127 + if (mac_dev->fm_rtc_get_drift)
11128 + mac_dev->fm_rtc_get_drift(mac_dev->fm_dev, &freqCompensation);
11129 +
11130 + getnstimeofday64(&now);
11131 + ptp_dpa_settime(&ptp_dpa_caps, &now);
11132 +
11133 + clock = ptp_clock_register(&ptp_dpa_caps, ptp_dev);
11134 + if (IS_ERR(clock)) {
11135 + err = PTR_ERR(clock);
11136 + return err;
11137 + }
11138 + dpa_phc_index = ptp_clock_index(clock);
11139 + return 0;
11140 +}
11141 +module_init(dpa_ptp_load);
11142 +
11143 +static void __exit __cold dpa_ptp_unload(void)
11144 +{
11145 + struct ptp_clock *clock = ptp_priv.clock;
11146 +
11147 + if (mac_dev->fm_rtc_disable_interrupt)
11148 + mac_dev->fm_rtc_disable_interrupt(mac_dev->fm_dev, 0xffffffff);
11149 + ptp_clock_unregister(clock);
11150 +}
11151 +module_exit(dpa_ptp_unload);
11152 --- /dev/null
11153 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
11154 @@ -0,0 +1,931 @@
11155 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
11156 + *
11157 + * Redistribution and use in source and binary forms, with or without
11158 + * modification, are permitted provided that the following conditions are met:
11159 + * * Redistributions of source code must retain the above copyright
11160 + * notice, this list of conditions and the following disclaimer.
11161 + * * Redistributions in binary form must reproduce the above copyright
11162 + * notice, this list of conditions and the following disclaimer in the
11163 + * documentation and/or other materials provided with the distribution.
11164 + * * Neither the name of Freescale Semiconductor nor the
11165 + * names of its contributors may be used to endorse or promote products
11166 + * derived from this software without specific prior written permission.
11167 + *
11168 + *
11169 + * ALTERNATIVELY, this software may be distributed under the terms of the
11170 + * GNU General Public License ("GPL") as published by the Free Software
11171 + * Foundation, either version 2 of that License or (at your option) any
11172 + * later version.
11173 + *
11174 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11175 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11176 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11177 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11178 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11179 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11180 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11181 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11182 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11183 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11184 + */
11185 +
11186 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
11187 +#define pr_fmt(fmt) \
11188 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
11189 + KBUILD_BASENAME".c", __LINE__, __func__
11190 +#else
11191 +#define pr_fmt(fmt) \
11192 + KBUILD_MODNAME ": " fmt
11193 +#endif
11194 +
11195 +#include <linux/init.h>
11196 +#include <linux/module.h>
11197 +#include <linux/io.h>
11198 +#include <linux/of_platform.h>
11199 +#include <linux/of_mdio.h>
11200 +#include <linux/phy.h>
11201 +#include <linux/netdevice.h>
11202 +
11203 +#include "dpaa_eth.h"
11204 +#include "mac.h"
11205 +#include "lnxwrp_fsl_fman.h"
11206 +
11207 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
11208 +
11209 +#include "fsl_fman_dtsec.h"
11210 +#include "fsl_fman_tgec.h"
11211 +#include "fsl_fman_memac.h"
11212 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
11213 +
11214 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
11215 +
11216 +MODULE_LICENSE("Dual BSD/GPL");
11217 +
11218 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
11219 +
11220 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
11221 +
11222 +struct mac_priv_s {
11223 + struct fm_mac_dev *fm_mac;
11224 +};
11225 +
11226 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
11227 +const size_t mac_sizeof_priv[] = {
11228 + [DTSEC] = sizeof(struct mac_priv_s),
11229 + [XGMAC] = sizeof(struct mac_priv_s),
11230 + [MEMAC] = sizeof(struct mac_priv_s)
11231 +};
11232 +
11233 +static const enet_mode_t _100[] = {
11234 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
11235 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
11236 +};
11237 +
11238 +static const enet_mode_t _1000[] = {
11239 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
11240 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
11241 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
11242 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
11243 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
11244 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
11245 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
11246 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
11247 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
11248 +};
11249 +
11250 +static enet_mode_t __cold __attribute__((nonnull))
11251 +macdev2enetinterface(const struct mac_device *mac_dev)
11252 +{
11253 + switch (mac_dev->max_speed) {
11254 + case SPEED_100:
11255 + return _100[mac_dev->phy_if];
11256 + case SPEED_1000:
11257 + return _1000[mac_dev->phy_if];
11258 + case SPEED_2500:
11259 + return e_ENET_MODE_SGMII_2500;
11260 + case SPEED_10000:
11261 + return e_ENET_MODE_XGMII_10000;
11262 + default:
11263 + return e_ENET_MODE_MII_100;
11264 + }
11265 +}
11266 +
11267 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
11268 +{
11269 + struct mac_device *mac_dev;
11270 +
11271 + mac_dev = (struct mac_device *)_mac_dev;
11272 +
11273 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
11274 + /* don't flag RX FIFO after the first */
11275 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11276 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
11277 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
11278 + exception);
11279 + }
11280 +
11281 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
11282 + exception);
11283 +}
11284 +
11285 +static int __cold init(struct mac_device *mac_dev)
11286 +{
11287 + int _errno;
11288 + struct mac_priv_s *priv;
11289 + t_FmMacParams param;
11290 + uint32_t version;
11291 +
11292 + priv = macdev_priv(mac_dev);
11293 +
11294 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11295 + mac_dev->dev, mac_dev->res->start, 0x2000);
11296 + param.enetMode = macdev2enetinterface(mac_dev);
11297 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
11298 + sizeof(mac_dev->addr)));
11299 + param.macId = mac_dev->cell_index;
11300 + param.h_Fm = (handle_t)mac_dev->fm;
11301 + param.mdioIrq = NO_IRQ;
11302 + param.f_Exception = mac_exception;
11303 + param.f_Event = mac_exception;
11304 + param.h_App = mac_dev;
11305 +
11306 + priv->fm_mac = fm_mac_config(&param);
11307 + if (unlikely(priv->fm_mac == NULL)) {
11308 + _errno = -EINVAL;
11309 + goto _return;
11310 + }
11311 +
11312 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11313 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11314 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11315 +
11316 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
11317 + fm_get_max_frm());
11318 + if (unlikely(_errno < 0))
11319 + goto _return_fm_mac_free;
11320 +
11321 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11322 + /* 10G always works with pad and CRC */
11323 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
11324 + if (unlikely(_errno < 0))
11325 + goto _return_fm_mac_free;
11326 +
11327 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
11328 + mac_dev->half_duplex);
11329 + if (unlikely(_errno < 0))
11330 + goto _return_fm_mac_free;
11331 + } else {
11332 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11333 + if (unlikely(_errno < 0))
11334 + goto _return_fm_mac_free;
11335 + }
11336 +
11337 + _errno = fm_mac_init(priv->fm_mac);
11338 + if (unlikely(_errno < 0))
11339 + goto _return_fm_mac_free;
11340 +
11341 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
11342 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
11343 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
11344 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11345 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
11346 + if (unlikely(_errno < 0))
11347 + goto _return_fm_mac_free;
11348 + }
11349 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
11350 +
11351 + /* For 10G MAC, disable Tx ECC exception */
11352 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
11353 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
11354 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
11355 + if (unlikely(_errno < 0))
11356 + goto _return_fm_mac_free;
11357 + }
11358 +
11359 + _errno = fm_mac_get_version(priv->fm_mac, &version);
11360 + if (unlikely(_errno < 0))
11361 + goto _return_fm_mac_free;
11362 +
11363 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
11364 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11365 + "dTSEC" : "XGEC"), version);
11366 +
11367 + goto _return;
11368 +
11369 +
11370 +_return_fm_mac_free:
11371 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
11372 +
11373 +_return:
11374 + return _errno;
11375 +}
11376 +
11377 +static int __cold memac_init(struct mac_device *mac_dev)
11378 +{
11379 + int _errno;
11380 + struct mac_priv_s *priv;
11381 + t_FmMacParams param;
11382 +
11383 + priv = macdev_priv(mac_dev);
11384 +
11385 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
11386 + mac_dev->dev, mac_dev->res->start, 0x2000);
11387 + param.enetMode = macdev2enetinterface(mac_dev);
11388 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
11389 + param.macId = mac_dev->cell_index;
11390 + param.h_Fm = (handle_t)mac_dev->fm;
11391 + param.mdioIrq = NO_IRQ;
11392 + param.f_Exception = mac_exception;
11393 + param.f_Event = mac_exception;
11394 + param.h_App = mac_dev;
11395 +
11396 + priv->fm_mac = fm_mac_config(&param);
11397 + if (unlikely(priv->fm_mac == NULL)) {
11398 + _errno = -EINVAL;
11399 + goto _return;
11400 + }
11401 +
11402 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
11403 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
11404 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
11405 +
11406 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
11407 + if (unlikely(_errno < 0))
11408 + goto _return_fm_mac_free;
11409 +
11410 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
11411 + if (unlikely(_errno < 0))
11412 + goto _return_fm_mac_free;
11413 +
11414 + _errno = fm_mac_init(priv->fm_mac);
11415 + if (unlikely(_errno < 0))
11416 + goto _return_fm_mac_free;
11417 +
11418 + dev_info(mac_dev->dev, "FMan MEMAC\n");
11419 +
11420 + goto _return;
11421 +
11422 +_return_fm_mac_free:
11423 + fm_mac_free(priv->fm_mac);
11424 +
11425 +_return:
11426 + return _errno;
11427 +}
11428 +
11429 +static int __cold start(struct mac_device *mac_dev)
11430 +{
11431 + int _errno;
11432 + struct phy_device *phy_dev = mac_dev->phy_dev;
11433 +
11434 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
11435 +
11436 + if (!_errno && phy_dev)
11437 + phy_start(phy_dev);
11438 +
11439 + return _errno;
11440 +}
11441 +
11442 +static int __cold stop(struct mac_device *mac_dev)
11443 +{
11444 + if (mac_dev->phy_dev)
11445 + phy_stop(mac_dev->phy_dev);
11446 +
11447 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
11448 +}
11449 +
11450 +static int __cold set_multi(struct net_device *net_dev,
11451 + struct mac_device *mac_dev)
11452 +{
11453 + struct mac_priv_s *mac_priv;
11454 + struct mac_address *old_addr, *tmp;
11455 + struct netdev_hw_addr *ha;
11456 + int _errno;
11457 +
11458 + mac_priv = macdev_priv(mac_dev);
11459 +
11460 + /* Clear previous address list */
11461 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
11462 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
11463 + (t_EnetAddr *)old_addr->addr);
11464 + if (_errno < 0)
11465 + return _errno;
11466 +
11467 + list_del(&old_addr->list);
11468 + kfree(old_addr);
11469 + }
11470 +
11471 + /* Add all the addresses from the new list */
11472 + netdev_for_each_mc_addr(ha, net_dev) {
11473 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
11474 + (t_EnetAddr *)ha->addr);
11475 + if (_errno < 0)
11476 + return _errno;
11477 +
11478 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
11479 + if (!tmp) {
11480 + dev_err(mac_dev->dev, "Out of memory\n");
11481 + return -ENOMEM;
11482 + }
11483 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
11484 + list_add(&tmp->list, &mac_dev->mc_addr_list);
11485 + }
11486 + return 0;
11487 +}
11488 +
11489 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
11490 + * active PAUSE settings. Otherwise, the new active settings should be reflected
11491 + * in FMan.
11492 + */
11493 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
11494 +{
11495 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11496 + int _errno = 0;
11497 +
11498 + if (unlikely(rx != mac_dev->rx_pause_active)) {
11499 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
11500 + if (likely(_errno == 0))
11501 + mac_dev->rx_pause_active = rx;
11502 + }
11503 +
11504 + if (unlikely(tx != mac_dev->tx_pause_active)) {
11505 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
11506 + if (likely(_errno == 0))
11507 + mac_dev->tx_pause_active = tx;
11508 + }
11509 +
11510 + return _errno;
11511 +}
11512 +EXPORT_SYMBOL(set_mac_active_pause);
11513 +
11514 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
11515 + * autonegotiation or values set by eththool.
11516 + */
11517 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
11518 +{
11519 + struct phy_device *phy_dev = mac_dev->phy_dev;
11520 + u16 lcl_adv, rmt_adv;
11521 + u8 flowctrl;
11522 +
11523 + *rx_pause = *tx_pause = false;
11524 +
11525 + if (!phy_dev->duplex)
11526 + return;
11527 +
11528 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
11529 + * are those set by ethtool.
11530 + */
11531 + if (!mac_dev->autoneg_pause) {
11532 + *rx_pause = mac_dev->rx_pause_req;
11533 + *tx_pause = mac_dev->tx_pause_req;
11534 + return;
11535 + }
11536 +
11537 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
11538 + * settings depend on the result of the link negotiation.
11539 + */
11540 +
11541 + /* get local capabilities */
11542 + lcl_adv = 0;
11543 + if (phy_dev->advertising & ADVERTISED_Pause)
11544 + lcl_adv |= ADVERTISE_PAUSE_CAP;
11545 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
11546 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
11547 +
11548 + /* get link partner capabilities */
11549 + rmt_adv = 0;
11550 + if (phy_dev->pause)
11551 + rmt_adv |= LPA_PAUSE_CAP;
11552 + if (phy_dev->asym_pause)
11553 + rmt_adv |= LPA_PAUSE_ASYM;
11554 +
11555 + /* Calculate TX/RX settings based on local and peer advertised
11556 + * symmetric/asymmetric PAUSE capabilities.
11557 + */
11558 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
11559 + if (flowctrl & FLOW_CTRL_RX)
11560 + *rx_pause = true;
11561 + if (flowctrl & FLOW_CTRL_TX)
11562 + *tx_pause = true;
11563 +}
11564 +EXPORT_SYMBOL(get_pause_cfg);
11565 +
11566 +static void adjust_link_void(struct net_device *net_dev)
11567 +{
11568 +}
11569 +
11570 +static void adjust_link(struct net_device *net_dev)
11571 +{
11572 + struct dpa_priv_s *priv = netdev_priv(net_dev);
11573 + struct mac_device *mac_dev = priv->mac_dev;
11574 + struct phy_device *phy_dev = mac_dev->phy_dev;
11575 + struct fm_mac_dev *fm_mac_dev;
11576 + bool rx_pause, tx_pause;
11577 + int _errno;
11578 +
11579 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
11580 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
11581 + phy_dev->duplex);
11582 +
11583 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
11584 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
11585 + if (unlikely(_errno < 0))
11586 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
11587 +}
11588 +
11589 +/* Initializes driver's PHY state, and attaches to the PHY.
11590 + * Returns 0 on success.
11591 + */
11592 +static int dtsec_init_phy(struct net_device *net_dev,
11593 + struct mac_device *mac_dev)
11594 +{
11595 + struct phy_device *phy_dev;
11596 +
11597 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11598 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11599 + 0, mac_dev->phy_if);
11600 + else
11601 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11602 + &adjust_link, 0, mac_dev->phy_if);
11603 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11604 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11605 + mac_dev->phy_node ?
11606 + mac_dev->phy_node->full_name :
11607 + mac_dev->fixed_bus_id);
11608 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11609 + }
11610 +
11611 + /* Remove any features not supported by the controller */
11612 + phy_dev->supported &= mac_dev->if_support;
11613 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11614 + * as most of the PHY drivers do not enable them by default.
11615 + */
11616 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11617 + phy_dev->advertising = phy_dev->supported;
11618 +
11619 + mac_dev->phy_dev = phy_dev;
11620 +
11621 + return 0;
11622 +}
11623 +
11624 +static int xgmac_init_phy(struct net_device *net_dev,
11625 + struct mac_device *mac_dev)
11626 +{
11627 + struct phy_device *phy_dev;
11628 +
11629 + if (of_phy_is_fixed_link(mac_dev->phy_node))
11630 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
11631 + 0, mac_dev->phy_if);
11632 + else
11633 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11634 + &adjust_link_void, 0, mac_dev->phy_if);
11635 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11636 + netdev_err(net_dev, "Could not attach to PHY %s\n",
11637 + mac_dev->phy_node ?
11638 + mac_dev->phy_node->full_name :
11639 + mac_dev->fixed_bus_id);
11640 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11641 + }
11642 +
11643 + phy_dev->supported &= mac_dev->if_support;
11644 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11645 + * as most of the PHY drivers do not enable them by default.
11646 + */
11647 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11648 + phy_dev->advertising = phy_dev->supported;
11649 +
11650 + mac_dev->phy_dev = phy_dev;
11651 +
11652 + return 0;
11653 +}
11654 +
11655 +static int memac_init_phy(struct net_device *net_dev,
11656 + struct mac_device *mac_dev)
11657 +{
11658 + struct phy_device *phy_dev;
11659 + void (*adjust_link_handler)(struct net_device *);
11660 +
11661 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
11662 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) {
11663 + /* Pass a void link state handler to the PHY state machine
11664 + * for XGMII (10G) and SGMII 2.5G, as the hardware does not
11665 + * permit dynamic link speed adjustments. */
11666 + adjust_link_handler = adjust_link_void;
11667 + } else if (macdev2enetinterface(mac_dev) & e_ENET_IF_RGMII) {
11668 + /* Regular RGMII ports connected to a PHY, as well as
11669 + * ports that are marked as "fixed-link" in the DTS,
11670 + * will have the adjust_link callback. This calls
11671 + * fman_memac_adjust_link in order to configure the
11672 + * IF_MODE register, which is needed in both cases.
11673 + */
11674 + adjust_link_handler = adjust_link;
11675 + } else if (of_phy_is_fixed_link(mac_dev->phy_node)) {
11676 + /* Pass a void link state handler for fixed-link
11677 + * interfaces that are not RGMII. Only RGMII has been
11678 + * tested and confirmed to work with fixed-link. Other
11679 + * MII interfaces may need further work.
11680 + * TODO: Change this as needed.
11681 + */
11682 + adjust_link_handler = adjust_link_void;
11683 + } else {
11684 + /* MII, RMII, SMII, GMII, SGMII, BASEX ports,
11685 + * that are NOT fixed-link.
11686 + * TODO: May not be needed for interfaces that
11687 + * pass through the SerDes block (*SGMII, XFI).
11688 + */
11689 + adjust_link_handler = adjust_link;
11690 + }
11691 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
11692 + adjust_link_handler, 0,
11693 + mac_dev->phy_if);
11694 +
11695 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
11696 + netdev_err(net_dev, "Could not connect to PHY %s\n",
11697 + mac_dev->phy_node ?
11698 + mac_dev->phy_node->full_name :
11699 + mac_dev->fixed_bus_id);
11700 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
11701 + }
11702 +
11703 + /* Remove any features not supported by the controller */
11704 + phy_dev->supported &= mac_dev->if_support;
11705 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
11706 + * as most of the PHY drivers do not enable them by default.
11707 + */
11708 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
11709 + phy_dev->advertising = phy_dev->supported;
11710 +
11711 + mac_dev->phy_dev = phy_dev;
11712 +
11713 + return 0;
11714 +}
11715 +
11716 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
11717 +{
11718 + int _errno, __errno;
11719 +
11720 + _errno = fm_mac_disable(fm_mac_dev);
11721 + __errno = fm_mac_free(fm_mac_dev);
11722 +
11723 + if (unlikely(__errno < 0))
11724 + _errno = __errno;
11725 +
11726 + return _errno;
11727 +}
11728 +
11729 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
11730 +{
11731 + const struct mac_priv_s *priv;
11732 + priv = macdev_priv(mac_dev);
11733 + return priv->fm_mac;
11734 +}
11735 +
11736 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11737 +{
11738 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
11739 + int i = 0, n = nn;
11740 +
11741 + FM_DMP_SUBTITLE(buf, n, "\n");
11742 +
11743 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
11744 +
11745 + FM_DMP_V32(buf, n, p_mm, tsec_id);
11746 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
11747 + FM_DMP_V32(buf, n, p_mm, ievent);
11748 + FM_DMP_V32(buf, n, p_mm, imask);
11749 + FM_DMP_V32(buf, n, p_mm, ecntrl);
11750 + FM_DMP_V32(buf, n, p_mm, ptv);
11751 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
11752 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
11753 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
11754 + FM_DMP_V32(buf, n, p_mm, tctrl);
11755 + FM_DMP_V32(buf, n, p_mm, rctrl);
11756 + FM_DMP_V32(buf, n, p_mm, maccfg1);
11757 + FM_DMP_V32(buf, n, p_mm, maccfg2);
11758 + FM_DMP_V32(buf, n, p_mm, ipgifg);
11759 + FM_DMP_V32(buf, n, p_mm, hafdup);
11760 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11761 +
11762 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
11763 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
11764 +
11765 + for (i = 0; i < 7; ++i) {
11766 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
11767 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
11768 + }
11769 +
11770 + FM_DMP_V32(buf, n, p_mm, car1);
11771 + FM_DMP_V32(buf, n, p_mm, car2);
11772 +
11773 + return n;
11774 +}
11775 +
11776 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11777 +{
11778 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
11779 + int n = nn;
11780 +
11781 + FM_DMP_SUBTITLE(buf, n, "\n");
11782 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
11783 +
11784 + FM_DMP_V32(buf, n, p_mm, tgec_id);
11785 + FM_DMP_V32(buf, n, p_mm, command_config);
11786 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
11787 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
11788 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11789 + FM_DMP_V32(buf, n, p_mm, pause_quant);
11790 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
11791 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
11792 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
11793 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
11794 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11795 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
11796 + FM_DMP_V32(buf, n, p_mm, mdio_command);
11797 + FM_DMP_V32(buf, n, p_mm, mdio_data);
11798 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
11799 + FM_DMP_V32(buf, n, p_mm, status);
11800 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
11801 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
11802 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
11803 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
11804 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
11805 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
11806 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
11807 + FM_DMP_V32(buf, n, p_mm, imask);
11808 + FM_DMP_V32(buf, n, p_mm, ievent);
11809 +
11810 + return n;
11811 +}
11812 +
11813 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11814 +{
11815 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11816 + int i = 0, n = nn;
11817 +
11818 + FM_DMP_SUBTITLE(buf, n, "\n");
11819 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
11820 +
11821 + FM_DMP_V32(buf, n, p_mm, command_config);
11822 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
11823 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
11824 + FM_DMP_V32(buf, n, p_mm, maxfrm);
11825 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
11826 + FM_DMP_V32(buf, n, p_mm, ievent);
11827 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
11828 + FM_DMP_V32(buf, n, p_mm, imask);
11829 +
11830 + for (i = 0; i < 4; ++i)
11831 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
11832 +
11833 + for (i = 0; i < 4; ++i)
11834 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
11835 +
11836 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
11837 +
11838 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
11839 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
11840 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
11841 + }
11842 +
11843 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
11844 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
11845 + FM_DMP_V32(buf, n, p_mm, statn_config);
11846 + FM_DMP_V32(buf, n, p_mm, if_mode);
11847 + FM_DMP_V32(buf, n, p_mm, if_status);
11848 + FM_DMP_V32(buf, n, p_mm, hg_config);
11849 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
11850 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
11851 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
11852 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
11853 + FM_DMP_V32(buf, n, p_mm, rhm);
11854 + FM_DMP_V32(buf, n, p_mm, thm);
11855 +
11856 + return n;
11857 +}
11858 +
11859 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
11860 +{
11861 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11862 + int n = nn;
11863 +
11864 + FM_DMP_SUBTITLE(buf, n, "\n");
11865 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
11866 +
11867 + /* Rx Statistics Counter */
11868 + FM_DMP_V32(buf, n, p_mm, reoct_l);
11869 + FM_DMP_V32(buf, n, p_mm, reoct_u);
11870 + FM_DMP_V32(buf, n, p_mm, roct_l);
11871 + FM_DMP_V32(buf, n, p_mm, roct_u);
11872 + FM_DMP_V32(buf, n, p_mm, raln_l);
11873 + FM_DMP_V32(buf, n, p_mm, raln_u);
11874 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
11875 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
11876 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
11877 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
11878 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
11879 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
11880 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
11881 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
11882 + FM_DMP_V32(buf, n, p_mm, rerr_l);
11883 + FM_DMP_V32(buf, n, p_mm, rerr_u);
11884 + FM_DMP_V32(buf, n, p_mm, ruca_l);
11885 + FM_DMP_V32(buf, n, p_mm, ruca_u);
11886 + FM_DMP_V32(buf, n, p_mm, rmca_l);
11887 + FM_DMP_V32(buf, n, p_mm, rmca_u);
11888 + FM_DMP_V32(buf, n, p_mm, rbca_l);
11889 + FM_DMP_V32(buf, n, p_mm, rbca_u);
11890 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
11891 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
11892 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
11893 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
11894 + FM_DMP_V32(buf, n, p_mm, rund_l);
11895 + FM_DMP_V32(buf, n, p_mm, rund_u);
11896 + FM_DMP_V32(buf, n, p_mm, r64_l);
11897 + FM_DMP_V32(buf, n, p_mm, r64_u);
11898 + FM_DMP_V32(buf, n, p_mm, r127_l);
11899 + FM_DMP_V32(buf, n, p_mm, r127_u);
11900 + FM_DMP_V32(buf, n, p_mm, r255_l);
11901 + FM_DMP_V32(buf, n, p_mm, r255_u);
11902 + FM_DMP_V32(buf, n, p_mm, r511_l);
11903 + FM_DMP_V32(buf, n, p_mm, r511_u);
11904 + FM_DMP_V32(buf, n, p_mm, r1023_l);
11905 + FM_DMP_V32(buf, n, p_mm, r1023_u);
11906 + FM_DMP_V32(buf, n, p_mm, r1518_l);
11907 + FM_DMP_V32(buf, n, p_mm, r1518_u);
11908 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
11909 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
11910 + FM_DMP_V32(buf, n, p_mm, rovr_l);
11911 + FM_DMP_V32(buf, n, p_mm, rovr_u);
11912 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
11913 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
11914 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
11915 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
11916 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
11917 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
11918 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
11919 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
11920 +
11921 + return n;
11922 +}
11923 +
11924 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
11925 +{
11926 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
11927 + int n = nn;
11928 +
11929 + FM_DMP_SUBTITLE(buf, n, "\n");
11930 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
11931 +
11932 +
11933 + /* Tx Statistics Counter */
11934 + FM_DMP_V32(buf, n, p_mm, teoct_l);
11935 + FM_DMP_V32(buf, n, p_mm, teoct_u);
11936 + FM_DMP_V32(buf, n, p_mm, toct_l);
11937 + FM_DMP_V32(buf, n, p_mm, toct_u);
11938 + FM_DMP_V32(buf, n, p_mm, txpf_l);
11939 + FM_DMP_V32(buf, n, p_mm, txpf_u);
11940 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
11941 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
11942 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
11943 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
11944 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
11945 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
11946 + FM_DMP_V32(buf, n, p_mm, terr_l);
11947 + FM_DMP_V32(buf, n, p_mm, terr_u);
11948 + FM_DMP_V32(buf, n, p_mm, tuca_l);
11949 + FM_DMP_V32(buf, n, p_mm, tuca_u);
11950 + FM_DMP_V32(buf, n, p_mm, tmca_l);
11951 + FM_DMP_V32(buf, n, p_mm, tmca_u);
11952 + FM_DMP_V32(buf, n, p_mm, tbca_l);
11953 + FM_DMP_V32(buf, n, p_mm, tbca_u);
11954 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
11955 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
11956 + FM_DMP_V32(buf, n, p_mm, tund_l);
11957 + FM_DMP_V32(buf, n, p_mm, tund_u);
11958 + FM_DMP_V32(buf, n, p_mm, t64_l);
11959 + FM_DMP_V32(buf, n, p_mm, t64_u);
11960 + FM_DMP_V32(buf, n, p_mm, t127_l);
11961 + FM_DMP_V32(buf, n, p_mm, t127_u);
11962 + FM_DMP_V32(buf, n, p_mm, t255_l);
11963 + FM_DMP_V32(buf, n, p_mm, t255_u);
11964 + FM_DMP_V32(buf, n, p_mm, t511_l);
11965 + FM_DMP_V32(buf, n, p_mm, t511_u);
11966 + FM_DMP_V32(buf, n, p_mm, t1023_l);
11967 + FM_DMP_V32(buf, n, p_mm, t1023_u);
11968 + FM_DMP_V32(buf, n, p_mm, t1518_l);
11969 + FM_DMP_V32(buf, n, p_mm, t1518_u);
11970 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
11971 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
11972 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
11973 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
11974 +
11975 + return n;
11976 +}
11977 +
11978 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
11979 +{
11980 + int n = nn;
11981 +
11982 + n = h_mac->dump_mac_regs(h_mac, buf, n);
11983 +
11984 + return n;
11985 +}
11986 +EXPORT_SYMBOL(fm_mac_dump_regs);
11987 +
11988 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
11989 +{
11990 + int n = nn;
11991 +
11992 + if(h_mac->dump_mac_rx_stats)
11993 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
11994 +
11995 + return n;
11996 +}
11997 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
11998 +
11999 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
12000 +{
12001 + int n = nn;
12002 +
12003 + if(h_mac->dump_mac_tx_stats)
12004 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
12005 +
12006 + return n;
12007 +}
12008 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
12009 +
12010 +static void __cold setup_dtsec(struct mac_device *mac_dev)
12011 +{
12012 + mac_dev->init_phy = dtsec_init_phy;
12013 + mac_dev->init = init;
12014 + mac_dev->start = start;
12015 + mac_dev->stop = stop;
12016 + mac_dev->set_promisc = fm_mac_set_promiscuous;
12017 + mac_dev->change_addr = fm_mac_modify_mac_addr;
12018 + mac_dev->set_multi = set_multi;
12019 + mac_dev->uninit = uninit;
12020 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
12021 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
12022 + mac_dev->get_mac_handle = get_mac_handle;
12023 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
12024 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
12025 + mac_dev->fm_rtc_enable = fm_rtc_enable;
12026 + mac_dev->fm_rtc_disable = fm_rtc_disable;
12027 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
12028 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
12029 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
12030 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
12031 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
12032 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
12033 + mac_dev->set_wol = fm_mac_set_wol;
12034 + mac_dev->dump_mac_regs = dtsec_dump_regs;
12035 +}
12036 +
12037 +static void __cold setup_xgmac(struct mac_device *mac_dev)
12038 +{
12039 + mac_dev->init_phy = xgmac_init_phy;
12040 + mac_dev->init = init;
12041 + mac_dev->start = start;
12042 + mac_dev->stop = stop;
12043 + mac_dev->set_promisc = fm_mac_set_promiscuous;
12044 + mac_dev->change_addr = fm_mac_modify_mac_addr;
12045 + mac_dev->set_multi = set_multi;
12046 + mac_dev->uninit = uninit;
12047 + mac_dev->get_mac_handle = get_mac_handle;
12048 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
12049 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
12050 + mac_dev->set_wol = fm_mac_set_wol;
12051 + mac_dev->dump_mac_regs = xgmac_dump_regs;
12052 +}
12053 +
12054 +static void __cold setup_memac(struct mac_device *mac_dev)
12055 +{
12056 + mac_dev->init_phy = memac_init_phy;
12057 + mac_dev->init = memac_init;
12058 + mac_dev->start = start;
12059 + mac_dev->stop = stop;
12060 + mac_dev->set_promisc = fm_mac_set_promiscuous;
12061 + mac_dev->change_addr = fm_mac_modify_mac_addr;
12062 + mac_dev->set_multi = set_multi;
12063 + mac_dev->uninit = uninit;
12064 + mac_dev->get_mac_handle = get_mac_handle;
12065 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
12066 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
12067 + mac_dev->fm_rtc_enable = fm_rtc_enable;
12068 + mac_dev->fm_rtc_disable = fm_rtc_disable;
12069 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
12070 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
12071 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
12072 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
12073 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
12074 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
12075 + mac_dev->set_wol = fm_mac_set_wol;
12076 + mac_dev->dump_mac_regs = memac_dump_regs;
12077 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
12078 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
12079 +}
12080 +
12081 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
12082 + [DTSEC] = setup_dtsec,
12083 + [XGMAC] = setup_xgmac,
12084 + [MEMAC] = setup_memac
12085 +};
12086 --- /dev/null
12087 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
12088 @@ -0,0 +1,489 @@
12089 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
12090 + *
12091 + * Redistribution and use in source and binary forms, with or without
12092 + * modification, are permitted provided that the following conditions are met:
12093 + * * Redistributions of source code must retain the above copyright
12094 + * notice, this list of conditions and the following disclaimer.
12095 + * * Redistributions in binary form must reproduce the above copyright
12096 + * notice, this list of conditions and the following disclaimer in the
12097 + * documentation and/or other materials provided with the distribution.
12098 + * * Neither the name of Freescale Semiconductor nor the
12099 + * names of its contributors may be used to endorse or promote products
12100 + * derived from this software without specific prior written permission.
12101 + *
12102 + *
12103 + * ALTERNATIVELY, this software may be distributed under the terms of the
12104 + * GNU General Public License ("GPL") as published by the Free Software
12105 + * Foundation, either version 2 of that License or (at your option) any
12106 + * later version.
12107 + *
12108 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12109 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12110 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12111 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12112 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12113 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12114 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12115 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12116 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12117 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12118 + */
12119 +
12120 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12121 +#define pr_fmt(fmt) \
12122 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12123 + KBUILD_BASENAME".c", __LINE__, __func__
12124 +#else
12125 +#define pr_fmt(fmt) \
12126 + KBUILD_MODNAME ": " fmt
12127 +#endif
12128 +
12129 +#include <linux/init.h>
12130 +#include <linux/module.h>
12131 +#include <linux/of_address.h>
12132 +#include <linux/of_platform.h>
12133 +#include <linux/of_net.h>
12134 +#include <linux/of_mdio.h>
12135 +#include <linux/phy_fixed.h>
12136 +#include <linux/device.h>
12137 +#include <linux/phy.h>
12138 +#include <linux/io.h>
12139 +
12140 +#include "lnxwrp_fm_ext.h"
12141 +
12142 +#include "mac.h"
12143 +
12144 +#define DTSEC_SUPPORTED \
12145 + (SUPPORTED_10baseT_Half \
12146 + | SUPPORTED_10baseT_Full \
12147 + | SUPPORTED_100baseT_Half \
12148 + | SUPPORTED_100baseT_Full \
12149 + | SUPPORTED_Autoneg \
12150 + | SUPPORTED_Pause \
12151 + | SUPPORTED_Asym_Pause \
12152 + | SUPPORTED_MII)
12153 +
12154 +static const char phy_str[][11] = {
12155 + [PHY_INTERFACE_MODE_MII] = "mii",
12156 + [PHY_INTERFACE_MODE_GMII] = "gmii",
12157 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
12158 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
12159 + [PHY_INTERFACE_MODE_TBI] = "tbi",
12160 + [PHY_INTERFACE_MODE_RMII] = "rmii",
12161 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
12162 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
12163 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
12164 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
12165 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
12166 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
12167 + [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500",
12168 +};
12169 +
12170 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
12171 +{
12172 + int i;
12173 +
12174 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
12175 + if (strcmp(str, phy_str[i]) == 0)
12176 + return (phy_interface_t)i;
12177 +
12178 + return PHY_INTERFACE_MODE_MII;
12179 +}
12180 +
12181 +static const uint16_t phy2speed[] = {
12182 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
12183 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
12184 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
12185 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
12186 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
12187 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
12188 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
12189 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
12190 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
12191 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
12192 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
12193 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
12194 + [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500,
12195 +};
12196 +
12197 +static struct mac_device * __cold
12198 +alloc_macdev(struct device *dev, size_t sizeof_priv,
12199 + void (*setup)(struct mac_device *mac_dev))
12200 +{
12201 + struct mac_device *mac_dev;
12202 +
12203 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
12204 + if (unlikely(mac_dev == NULL))
12205 + mac_dev = ERR_PTR(-ENOMEM);
12206 + else {
12207 + mac_dev->dev = dev;
12208 + dev_set_drvdata(dev, mac_dev);
12209 + setup(mac_dev);
12210 + }
12211 +
12212 + return mac_dev;
12213 +}
12214 +
12215 +static int __cold free_macdev(struct mac_device *mac_dev)
12216 +{
12217 + dev_set_drvdata(mac_dev->dev, NULL);
12218 +
12219 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
12220 +}
12221 +
12222 +static const struct of_device_id mac_match[] = {
12223 + [DTSEC] = {
12224 + .compatible = "fsl,fman-dtsec"
12225 + },
12226 + [XGMAC] = {
12227 + .compatible = "fsl,fman-xgec"
12228 + },
12229 + [MEMAC] = {
12230 + .compatible = "fsl,fman-memac"
12231 + },
12232 + {}
12233 +};
12234 +MODULE_DEVICE_TABLE(of, mac_match);
12235 +
12236 +static int __cold mac_probe(struct platform_device *_of_dev)
12237 +{
12238 + int _errno, i;
12239 + struct device *dev;
12240 + struct device_node *mac_node, *dev_node;
12241 + struct mac_device *mac_dev;
12242 + struct platform_device *of_dev;
12243 + struct resource res;
12244 + const uint8_t *mac_addr;
12245 + const char *char_prop;
12246 + int nph;
12247 + u32 cell_index;
12248 + const struct of_device_id *match;
12249 +
12250 + dev = &_of_dev->dev;
12251 + mac_node = dev->of_node;
12252 +
12253 + match = of_match_device(mac_match, dev);
12254 + if (!match)
12255 + return -EINVAL;
12256 +
12257 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
12258 + i++)
12259 + ;
12260 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
12261 +
12262 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
12263 + if (IS_ERR(mac_dev)) {
12264 + _errno = PTR_ERR(mac_dev);
12265 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
12266 + goto _return;
12267 + }
12268 +
12269 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
12270 +
12271 + /* Get the FM node */
12272 + dev_node = of_get_parent(mac_node);
12273 + if (unlikely(dev_node == NULL)) {
12274 + dev_err(dev, "of_get_parent(%s) failed\n",
12275 + mac_node->full_name);
12276 + _errno = -EINVAL;
12277 + goto _return_dev_set_drvdata;
12278 + }
12279 +
12280 + of_dev = of_find_device_by_node(dev_node);
12281 + if (unlikely(of_dev == NULL)) {
12282 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12283 + dev_node->full_name);
12284 + _errno = -EINVAL;
12285 + goto _return_of_node_put;
12286 + }
12287 +
12288 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
12289 + if (unlikely(mac_dev->fm_dev == NULL)) {
12290 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
12291 + _errno = -ENODEV;
12292 + goto _return_of_node_put;
12293 + }
12294 +
12295 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
12296 + of_node_put(dev_node);
12297 +
12298 + /* Get the address of the memory mapped registers */
12299 + _errno = of_address_to_resource(mac_node, 0, &res);
12300 + if (unlikely(_errno < 0)) {
12301 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
12302 + mac_node->full_name, _errno);
12303 + goto _return_dev_set_drvdata;
12304 + }
12305 +
12306 + mac_dev->res = __devm_request_region(
12307 + dev,
12308 + fm_get_mem_region(mac_dev->fm_dev),
12309 + res.start, res.end + 1 - res.start, "mac");
12310 + if (unlikely(mac_dev->res == NULL)) {
12311 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
12312 + _errno = -EBUSY;
12313 + goto _return_dev_set_drvdata;
12314 + }
12315 +
12316 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
12317 + mac_dev->res->end + 1
12318 + - mac_dev->res->start);
12319 + if (unlikely(mac_dev->vaddr == NULL)) {
12320 + dev_err(dev, "devm_ioremap() failed\n");
12321 + _errno = -EIO;
12322 + goto _return_dev_set_drvdata;
12323 + }
12324 +
12325 +#define TBIPA_OFFSET 0x1c
12326 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
12327 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
12328 + if (mac_dev->tbi_node) {
12329 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
12330 + const __be32 *tbi_reg;
12331 + void __iomem *addr;
12332 +
12333 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
12334 + if (tbi_reg)
12335 + tbiaddr = be32_to_cpup(tbi_reg);
12336 + addr = mac_dev->vaddr + TBIPA_OFFSET;
12337 + /* TODO: out_be32 does not exist on ARM */
12338 + out_be32(addr, tbiaddr);
12339 + }
12340 +
12341 + if (!of_device_is_available(mac_node)) {
12342 + devm_iounmap(dev, mac_dev->vaddr);
12343 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
12344 + res.start, res.end + 1 - res.start);
12345 + fm_unbind(mac_dev->fm_dev);
12346 + devm_kfree(dev, mac_dev);
12347 + dev_set_drvdata(dev, NULL);
12348 + return -ENODEV;
12349 + }
12350 +
12351 + /* Get the cell-index */
12352 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
12353 + if (unlikely(_errno)) {
12354 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
12355 + mac_node->full_name);
12356 + goto _return_dev_set_drvdata;
12357 + }
12358 + mac_dev->cell_index = (uint8_t)cell_index;
12359 + if (mac_dev->cell_index >= 8)
12360 + mac_dev->cell_index -= 8;
12361 +
12362 + /* Get the MAC address */
12363 + mac_addr = of_get_mac_address(mac_node);
12364 + if (unlikely(mac_addr == NULL)) {
12365 + dev_err(dev, "of_get_mac_address(%s) failed\n",
12366 + mac_node->full_name);
12367 + _errno = -EINVAL;
12368 + goto _return_dev_set_drvdata;
12369 + }
12370 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
12371 +
12372 + /* Verify the number of port handles */
12373 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
12374 + if (unlikely(nph < 0)) {
12375 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
12376 + mac_node->full_name);
12377 + _errno = nph;
12378 + goto _return_dev_set_drvdata;
12379 + }
12380 +
12381 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
12382 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
12383 + mac_node->full_name);
12384 + _errno = -EINVAL;
12385 + goto _return_dev_set_drvdata;
12386 + }
12387 +
12388 + for_each_port_device(i, mac_dev->port_dev) {
12389 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
12390 + if (unlikely(dev_node == NULL)) {
12391 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
12392 + mac_node->full_name);
12393 + _errno = -EINVAL;
12394 + goto _return_of_node_put;
12395 + }
12396 +
12397 + of_dev = of_find_device_by_node(dev_node);
12398 + if (unlikely(of_dev == NULL)) {
12399 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
12400 + dev_node->full_name);
12401 + _errno = -EINVAL;
12402 + goto _return_of_node_put;
12403 + }
12404 +
12405 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
12406 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
12407 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
12408 + dev_node->full_name);
12409 + _errno = -EINVAL;
12410 + goto _return_of_node_put;
12411 + }
12412 + of_node_put(dev_node);
12413 + }
12414 +
12415 + /* Get the PHY connection type */
12416 + _errno = of_property_read_string(mac_node, "phy-connection-type",
12417 + &char_prop);
12418 + if (unlikely(_errno)) {
12419 + dev_warn(dev,
12420 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
12421 + mac_node->full_name);
12422 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
12423 + } else
12424 + mac_dev->phy_if = str2phy(char_prop);
12425 +
12426 + mac_dev->link = false;
12427 + mac_dev->half_duplex = false;
12428 + mac_dev->speed = phy2speed[mac_dev->phy_if];
12429 + mac_dev->max_speed = mac_dev->speed;
12430 + mac_dev->if_support = DTSEC_SUPPORTED;
12431 + /* We don't support half-duplex in SGMII mode */
12432 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
12433 + strstr(char_prop, "sgmii-2500"))
12434 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
12435 + SUPPORTED_100baseT_Half);
12436 +
12437 + /* Gigabit support (no half-duplex) */
12438 + if (mac_dev->max_speed == SPEED_1000 ||
12439 + mac_dev->max_speed == SPEED_2500)
12440 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
12441 +
12442 + /* The 10G interface only supports one mode */
12443 + if (strstr(char_prop, "xgmii"))
12444 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
12445 +
12446 + /* Get the rest of the PHY information */
12447 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
12448 + if (!mac_dev->phy_node) {
12449 + struct phy_device *phy;
12450 +
12451 + if (!of_phy_is_fixed_link(mac_node)) {
12452 + dev_err(dev, "Wrong PHY information of mac node %s\n",
12453 + mac_node->full_name);
12454 + goto _return_dev_set_drvdata;
12455 + }
12456 +
12457 + _errno = of_phy_register_fixed_link(mac_node);
12458 + if (_errno)
12459 + goto _return_dev_set_drvdata;
12460 +
12461 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
12462 + sizeof(*mac_dev->fixed_link),
12463 + GFP_KERNEL);
12464 + if (!mac_dev->fixed_link)
12465 + goto _return_dev_set_drvdata;
12466 +
12467 + mac_dev->phy_node = of_node_get(mac_node);
12468 + phy = of_phy_find_device(mac_dev->phy_node);
12469 + if (!phy)
12470 + goto _return_dev_set_drvdata;
12471 +
12472 + mac_dev->fixed_link->link = phy->link;
12473 + mac_dev->fixed_link->speed = phy->speed;
12474 + mac_dev->fixed_link->duplex = phy->duplex;
12475 + mac_dev->fixed_link->pause = phy->pause;
12476 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
12477 + }
12478 +
12479 + _errno = mac_dev->init(mac_dev);
12480 + if (unlikely(_errno < 0)) {
12481 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
12482 + goto _return_dev_set_drvdata;
12483 + }
12484 +
12485 + /* pause frame autonegotiation enabled*/
12486 + mac_dev->autoneg_pause = true;
12487 +
12488 + /* by intializing the values to false, force FMD to enable PAUSE frames
12489 + * on RX and TX
12490 + */
12491 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
12492 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
12493 + _errno = set_mac_active_pause(mac_dev, true, true);
12494 + if (unlikely(_errno < 0))
12495 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
12496 +
12497 + dev_info(dev,
12498 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
12499 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
12500 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
12501 +
12502 + goto _return;
12503 +
12504 +_return_of_node_put:
12505 + of_node_put(dev_node);
12506 +_return_dev_set_drvdata:
12507 + dev_set_drvdata(dev, NULL);
12508 +_return:
12509 + return _errno;
12510 +}
12511 +
12512 +static int __cold mac_remove(struct platform_device *of_dev)
12513 +{
12514 + int i, _errno;
12515 + struct device *dev;
12516 + struct mac_device *mac_dev;
12517 +
12518 + dev = &of_dev->dev;
12519 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
12520 +
12521 + for_each_port_device(i, mac_dev->port_dev)
12522 + fm_port_unbind(mac_dev->port_dev[i]);
12523 +
12524 + fm_unbind(mac_dev->fm_dev);
12525 +
12526 + _errno = free_macdev(mac_dev);
12527 +
12528 + return _errno;
12529 +}
12530 +
12531 +static struct platform_driver mac_driver = {
12532 + .driver = {
12533 + .name = KBUILD_MODNAME,
12534 + .of_match_table = mac_match,
12535 + .owner = THIS_MODULE,
12536 + },
12537 + .probe = mac_probe,
12538 + .remove = mac_remove
12539 +};
12540 +
12541 +static int __init __cold mac_load(void)
12542 +{
12543 + int _errno;
12544 +
12545 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12546 + KBUILD_BASENAME".c", __func__);
12547 +
12548 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
12549 +
12550 + _errno = platform_driver_register(&mac_driver);
12551 + if (unlikely(_errno < 0)) {
12552 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
12553 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
12554 + goto _return;
12555 + }
12556 +
12557 + goto _return;
12558 +
12559 +_return:
12560 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12561 + KBUILD_BASENAME".c", __func__);
12562 +
12563 + return _errno;
12564 +}
12565 +module_init(mac_load);
12566 +
12567 +static void __exit __cold mac_unload(void)
12568 +{
12569 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
12570 + KBUILD_BASENAME".c", __func__);
12571 +
12572 + platform_driver_unregister(&mac_driver);
12573 +
12574 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
12575 + KBUILD_BASENAME".c", __func__);
12576 +}
12577 +module_exit(mac_unload);
12578 --- /dev/null
12579 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
12580 @@ -0,0 +1,135 @@
12581 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
12582 + *
12583 + * Redistribution and use in source and binary forms, with or without
12584 + * modification, are permitted provided that the following conditions are met:
12585 + * * Redistributions of source code must retain the above copyright
12586 + * notice, this list of conditions and the following disclaimer.
12587 + * * Redistributions in binary form must reproduce the above copyright
12588 + * notice, this list of conditions and the following disclaimer in the
12589 + * documentation and/or other materials provided with the distribution.
12590 + * * Neither the name of Freescale Semiconductor nor the
12591 + * names of its contributors may be used to endorse or promote products
12592 + * derived from this software without specific prior written permission.
12593 + *
12594 + *
12595 + * ALTERNATIVELY, this software may be distributed under the terms of the
12596 + * GNU General Public License ("GPL") as published by the Free Software
12597 + * Foundation, either version 2 of that License or (at your option) any
12598 + * later version.
12599 + *
12600 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12601 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12602 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12603 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12604 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12605 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12606 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12607 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12608 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12609 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12610 + */
12611 +
12612 +#ifndef __MAC_H
12613 +#define __MAC_H
12614 +
12615 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
12616 +#include <linux/if_ether.h> /* ETH_ALEN */
12617 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
12618 +#include <linux/list.h>
12619 +
12620 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
12621 +
12622 +enum {DTSEC, XGMAC, MEMAC};
12623 +
12624 +struct mac_device {
12625 + struct device *dev;
12626 + void *priv;
12627 + uint8_t cell_index;
12628 + struct resource *res;
12629 + void __iomem *vaddr;
12630 + uint8_t addr[ETH_ALEN];
12631 + bool promisc;
12632 +
12633 + struct fm *fm_dev;
12634 + struct fm_port *port_dev[2];
12635 +
12636 + phy_interface_t phy_if;
12637 + u32 if_support;
12638 + bool link;
12639 + bool half_duplex;
12640 + uint16_t speed;
12641 + uint16_t max_speed;
12642 + struct device_node *phy_node;
12643 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
12644 + struct device_node *tbi_node;
12645 + struct phy_device *phy_dev;
12646 + void *fm;
12647 + /* List of multicast addresses */
12648 + struct list_head mc_addr_list;
12649 + struct fixed_phy_status *fixed_link;
12650 +
12651 + bool autoneg_pause;
12652 + bool rx_pause_req;
12653 + bool tx_pause_req;
12654 + bool rx_pause_active;
12655 + bool tx_pause_active;
12656 +
12657 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
12658 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
12659 + int (*init)(struct mac_device *mac_dev);
12660 + int (*start)(struct mac_device *mac_dev);
12661 + int (*stop)(struct mac_device *mac_dev);
12662 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
12663 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
12664 + int (*set_multi)(struct net_device *net_dev,
12665 + struct mac_device *mac_dev);
12666 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
12667 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
12668 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
12669 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12670 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
12671 + int (*fm_rtc_enable)(struct fm *fm_dev);
12672 + int (*fm_rtc_disable)(struct fm *fm_dev);
12673 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
12674 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
12675 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
12676 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
12677 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
12678 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
12679 + uint64_t fiper);
12680 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
12681 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
12682 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
12683 +#endif
12684 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
12685 + bool en);
12686 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
12687 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
12688 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
12689 +};
12690 +
12691 +struct mac_address {
12692 + uint8_t addr[ETH_ALEN];
12693 + struct list_head list;
12694 +};
12695 +
12696 +#define get_fm_handle(net_dev) \
12697 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
12698 +
12699 +#define for_each_port_device(i, port_dev) \
12700 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
12701 +
12702 +static inline __attribute((nonnull)) void *macdev_priv(
12703 + const struct mac_device *mac_dev)
12704 +{
12705 + return (void *)mac_dev + sizeof(*mac_dev);
12706 +}
12707 +
12708 +extern const char *mac_driver_description;
12709 +extern const size_t mac_sizeof_priv[];
12710 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
12711 +
12712 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
12713 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
12714 +
12715 +#endif /* __MAC_H */
12716 --- /dev/null
12717 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
12718 @@ -0,0 +1,848 @@
12719 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
12720 + *
12721 + * Redistribution and use in source and binary forms, with or without
12722 + * modification, are permitted provided that the following conditions are met:
12723 + * * Redistributions of source code must retain the above copyright
12724 + * notice, this list of conditions and the following disclaimer.
12725 + * * Redistributions in binary form must reproduce the above copyright
12726 + * notice, this list of conditions and the following disclaimer in the
12727 + * documentation and/or other materials provided with the distribution.
12728 + * * Neither the name of Freescale Semiconductor nor the
12729 + * names of its contributors may be used to endorse or promote products
12730 + * derived from this software without specific prior written permission.
12731 + *
12732 + *
12733 + * ALTERNATIVELY, this software may be distributed under the terms of the
12734 + * GNU General Public License ("GPL") as published by the Free Software
12735 + * Foundation, either version 2 of that License or (at your option) any
12736 + * later version.
12737 + *
12738 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12739 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12740 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12741 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12742 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12743 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12744 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12745 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12746 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12747 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12748 + */
12749 +
12750 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
12751 + * Validates device-tree configuration and sets up the offline ports.
12752 + */
12753 +
12754 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12755 +#define pr_fmt(fmt) \
12756 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12757 + KBUILD_BASENAME".c", __LINE__, __func__
12758 +#else
12759 +#define pr_fmt(fmt) \
12760 + KBUILD_MODNAME ": " fmt
12761 +#endif
12762 +
12763 +
12764 +#include <linux/init.h>
12765 +#include <linux/module.h>
12766 +#include <linux/of_platform.h>
12767 +#include <linux/fsl_qman.h>
12768 +
12769 +#include "offline_port.h"
12770 +#include "dpaa_eth.h"
12771 +#include "dpaa_eth_common.h"
12772 +
12773 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
12774 +/* Manip extra space and data alignment for fragmentation */
12775 +#define FRAG_MANIP_SPACE 128
12776 +#define FRAG_DATA_ALIGN 64
12777 +
12778 +
12779 +MODULE_LICENSE("Dual BSD/GPL");
12780 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
12781 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
12782 +
12783 +
12784 +static const struct of_device_id oh_port_match_table[] = {
12785 + {
12786 + .compatible = "fsl,dpa-oh"
12787 + },
12788 + {
12789 + .compatible = "fsl,dpa-oh-shared"
12790 + },
12791 + {}
12792 +};
12793 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
12794 +
12795 +#ifdef CONFIG_PM
12796 +
12797 +static int oh_suspend(struct device *dev)
12798 +{
12799 + struct dpa_oh_config_s *oh_config;
12800 +
12801 + oh_config = dev_get_drvdata(dev);
12802 + return fm_port_suspend(oh_config->oh_port);
12803 +}
12804 +
12805 +static int oh_resume(struct device *dev)
12806 +{
12807 + struct dpa_oh_config_s *oh_config;
12808 +
12809 + oh_config = dev_get_drvdata(dev);
12810 + return fm_port_resume(oh_config->oh_port);
12811 +}
12812 +
12813 +static const struct dev_pm_ops oh_pm_ops = {
12814 + .suspend = oh_suspend,
12815 + .resume = oh_resume,
12816 +};
12817 +
12818 +#define OH_PM_OPS (&oh_pm_ops)
12819 +
12820 +#else /* CONFIG_PM */
12821 +
12822 +#define OH_PM_OPS NULL
12823 +
12824 +#endif /* CONFIG_PM */
12825 +
12826 +/* Creates Frame Queues */
12827 +static uint32_t oh_fq_create(struct qman_fq *fq,
12828 + uint32_t fq_id, uint16_t channel,
12829 + uint16_t wq_id)
12830 +{
12831 + struct qm_mcc_initfq fq_opts;
12832 + uint32_t create_flags, init_flags;
12833 + uint32_t ret = 0;
12834 +
12835 + if (fq == NULL)
12836 + return 1;
12837 +
12838 + /* Set flags for FQ create */
12839 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
12840 +
12841 + /* Create frame queue */
12842 + ret = qman_create_fq(fq_id, create_flags, fq);
12843 + if (ret != 0)
12844 + return 1;
12845 +
12846 + /* Set flags for FQ init */
12847 + init_flags = QMAN_INITFQ_FLAG_SCHED;
12848 +
12849 + /* Set FQ init options. Specify destination WQ ID and channel */
12850 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
12851 + fq_opts.fqd.dest.wq = wq_id;
12852 + fq_opts.fqd.dest.channel = channel;
12853 +
12854 + /* Initialize frame queue */
12855 + ret = qman_init_fq(fq, init_flags, &fq_opts);
12856 + if (ret != 0) {
12857 + qman_destroy_fq(fq, 0);
12858 + return 1;
12859 + }
12860 +
12861 + return 0;
12862 +}
12863 +
12864 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
12865 +{
12866 + if (channel) {
12867 + /* display fqs with a valid (!= 0) destination channel */
12868 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
12869 + }
12870 +}
12871 +
12872 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
12873 + int fqs_count, uint16_t channel_id)
12874 +{
12875 + int i;
12876 + for (i = 0; i < fqs_count; i++)
12877 + dump_fq(dev, (fqs + i)->fqid, channel_id);
12878 +}
12879 +
12880 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
12881 +{
12882 + struct list_head *fq_list;
12883 + struct fq_duple *fqd;
12884 + int i;
12885 +
12886 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
12887 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
12888 +
12889 + /* TX queues (old initialization) */
12890 + dev_info(dev, "Initialized queues:");
12891 + for (i = 0; i < conf->egress_cnt; i++)
12892 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
12893 + conf->channel);
12894 +
12895 + /* initialized ingress queues */
12896 + list_for_each(fq_list, &conf->fqs_ingress_list) {
12897 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12898 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12899 + }
12900 +
12901 + /* initialized egress queues */
12902 + list_for_each(fq_list, &conf->fqs_egress_list) {
12903 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
12904 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
12905 + }
12906 +}
12907 +
12908 +/* Destroys Frame Queues */
12909 +static void oh_fq_destroy(struct qman_fq *fq)
12910 +{
12911 + int _errno = 0;
12912 +
12913 + _errno = qman_retire_fq(fq, NULL);
12914 + if (unlikely(_errno < 0))
12915 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
12916 + KBUILD_BASENAME".c", __LINE__, __func__,
12917 + qman_fq_fqid(fq), _errno);
12918 +
12919 + _errno = qman_oos_fq(fq);
12920 + if (unlikely(_errno < 0)) {
12921 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
12922 + KBUILD_BASENAME".c", __LINE__, __func__,
12923 + qman_fq_fqid(fq), _errno);
12924 + }
12925 +
12926 + qman_destroy_fq(fq, 0);
12927 +}
12928 +
12929 +/* Allocation code for the OH port's PCD frame queues */
12930 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
12931 + uint32_t num,
12932 + uint8_t alignment,
12933 + uint32_t *base_fqid)
12934 +{
12935 + dev_crit(dev, "callback not implemented!\n");
12936 + BUG();
12937 +
12938 + return 0;
12939 +}
12940 +
12941 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
12942 +{
12943 + dev_crit(dev, "callback not implemented!\n");
12944 + BUG();
12945 +
12946 + return 0;
12947 +}
12948 +
12949 +static void oh_set_buffer_layout(struct fm_port *port,
12950 + struct dpa_buffer_layout_s *layout)
12951 +{
12952 + struct fm_port_params params;
12953 +
12954 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
12955 + layout->parse_results = true;
12956 + layout->hash_results = true;
12957 + layout->time_stamp = false;
12958 +
12959 + fm_port_get_buff_layout_ext_params(port, &params);
12960 + layout->manip_extra_space = params.manip_extra_space;
12961 + layout->data_align = params.data_align;
12962 +}
12963 +
12964 +static int
12965 +oh_port_probe(struct platform_device *_of_dev)
12966 +{
12967 + struct device *dpa_oh_dev;
12968 + struct device_node *dpa_oh_node;
12969 + int lenp, _errno = 0, fq_idx, duple_idx;
12970 + int n_size, i, j, ret, duples_count;
12971 + struct platform_device *oh_of_dev;
12972 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
12973 + struct device *oh_dev;
12974 + struct dpa_oh_config_s *oh_config = NULL;
12975 + const __be32 *oh_all_queues;
12976 + const __be32 *channel_ids;
12977 + const __be32 *oh_tx_queues;
12978 + uint32_t queues_count;
12979 + uint32_t crt_fqid_base;
12980 + uint32_t crt_fq_count;
12981 + bool frag_enabled = false;
12982 + struct fm_port_params oh_port_tx_params;
12983 + struct fm_port_pcd_param oh_port_pcd_params;
12984 + struct dpa_buffer_layout_s buf_layout;
12985 +
12986 + /* True if the current partition owns the OH port. */
12987 + bool init_oh_port;
12988 +
12989 + const struct of_device_id *match;
12990 + int crt_ext_pools_count;
12991 + u32 ext_pool_size;
12992 + u32 port_id;
12993 + u32 channel_id;
12994 +
12995 + int channel_ids_count;
12996 + int channel_idx;
12997 + struct fq_duple *fqd;
12998 + struct list_head *fq_list, *fq_list_tmp;
12999 +
13000 + const __be32 *bpool_cfg;
13001 + uint32_t bpid;
13002 +
13003 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
13004 + dpa_oh_dev = &_of_dev->dev;
13005 + dpa_oh_node = dpa_oh_dev->of_node;
13006 + BUG_ON(dpa_oh_node == NULL);
13007 +
13008 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
13009 + if (!match)
13010 + return -EINVAL;
13011 +
13012 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
13013 +
13014 + /* Find the referenced OH node */
13015 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
13016 + if (oh_node == NULL) {
13017 + dev_err(dpa_oh_dev,
13018 + "Can't find OH node referenced from node %s\n",
13019 + dpa_oh_node->full_name);
13020 + return -EINVAL;
13021 + }
13022 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
13023 + match->compatible);
13024 +
13025 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
13026 + if (_errno) {
13027 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
13028 + dpa_oh_node->full_name);
13029 + goto return_kfree;
13030 + }
13031 +
13032 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
13033 + &channel_id);
13034 + if (_errno) {
13035 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
13036 + dpa_oh_node->full_name);
13037 + goto return_kfree;
13038 + }
13039 +
13040 + oh_of_dev = of_find_device_by_node(oh_node);
13041 + BUG_ON(oh_of_dev == NULL);
13042 + oh_dev = &oh_of_dev->dev;
13043 +
13044 + /* The OH port must be initialized exactly once.
13045 + * The following scenarios are of interest:
13046 + * - the node is Linux-private (will always initialize it);
13047 + * - the node is shared between two Linux partitions
13048 + * (only one of them will initialize it);
13049 + * - the node is shared between a Linux and a LWE partition
13050 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
13051 + */
13052 +
13053 + /* Check if the current partition owns the OH port
13054 + * and ought to initialize it. It may be the case that we leave this
13055 + * to another (also Linux) partition.
13056 + */
13057 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
13058 +
13059 + /* If we aren't the "owner" of the OH node, we're done here. */
13060 + if (!init_oh_port) {
13061 + dev_dbg(dpa_oh_dev,
13062 + "Not owning the shared OH port %s, will not initialize it.\n",
13063 + oh_node->full_name);
13064 + of_node_put(oh_node);
13065 + return 0;
13066 + }
13067 +
13068 + /* Allocate OH dev private data */
13069 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
13070 + if (oh_config == NULL) {
13071 + dev_err(dpa_oh_dev,
13072 + "Can't allocate private data for OH node %s referenced from node %s!\n",
13073 + oh_node->full_name, dpa_oh_node->full_name);
13074 + _errno = -ENOMEM;
13075 + goto return_kfree;
13076 + }
13077 +
13078 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
13079 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
13080 +
13081 + /* FQs that enter OH port */
13082 + lenp = 0;
13083 + oh_all_queues = of_get_property(dpa_oh_node,
13084 + "fsl,qman-frame-queues-ingress", &lenp);
13085 + if (lenp % (2 * sizeof(*oh_all_queues))) {
13086 + dev_warn(dpa_oh_dev,
13087 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
13088 + oh_node->full_name, dpa_oh_node->full_name);
13089 + /* just ignore the last unpaired value */
13090 + }
13091 +
13092 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
13093 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
13094 + duples_count);
13095 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
13096 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
13097 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
13098 +
13099 + fqd = devm_kzalloc(dpa_oh_dev,
13100 + sizeof(struct fq_duple), GFP_KERNEL);
13101 + if (!fqd) {
13102 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
13103 + oh_node->full_name,
13104 + dpa_oh_node->full_name);
13105 + _errno = -ENOMEM;
13106 + goto return_kfree;
13107 + }
13108 +
13109 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13110 + crt_fq_count * sizeof(struct qman_fq),
13111 + GFP_KERNEL);
13112 + if (!fqd->fqs) {
13113 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
13114 + oh_node->full_name,
13115 + dpa_oh_node->full_name);
13116 + _errno = -ENOMEM;
13117 + goto return_kfree;
13118 + }
13119 +
13120 + for (j = 0; j < crt_fq_count; j++)
13121 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13122 + fqd->fqs_count = crt_fq_count;
13123 + fqd->channel_id = (uint16_t)channel_id;
13124 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
13125 + }
13126 +
13127 + /* create the ingress queues */
13128 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
13129 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13130 +
13131 + for (j = 0; j < fqd->fqs_count; j++) {
13132 + ret = oh_fq_create(fqd->fqs + j,
13133 + (fqd->fqs + j)->fqid,
13134 + fqd->channel_id, 3);
13135 + if (ret != 0) {
13136 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
13137 + (fqd->fqs + j)->fqid,
13138 + oh_node->full_name,
13139 + dpa_oh_node->full_name);
13140 + _errno = -EINVAL;
13141 + goto return_kfree;
13142 + }
13143 + }
13144 + }
13145 +
13146 + /* FQs that exit OH port */
13147 + lenp = 0;
13148 + oh_all_queues = of_get_property(dpa_oh_node,
13149 + "fsl,qman-frame-queues-egress", &lenp);
13150 + if (lenp % (2 * sizeof(*oh_all_queues))) {
13151 + dev_warn(dpa_oh_dev,
13152 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
13153 + oh_node->full_name, dpa_oh_node->full_name);
13154 + /* just ignore the last unpaired value */
13155 + }
13156 +
13157 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
13158 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
13159 + duples_count);
13160 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
13161 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
13162 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
13163 +
13164 + fqd = devm_kzalloc(dpa_oh_dev,
13165 + sizeof(struct fq_duple), GFP_KERNEL);
13166 + if (!fqd) {
13167 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13168 + oh_node->full_name,
13169 + dpa_oh_node->full_name);
13170 + _errno = -ENOMEM;
13171 + goto return_kfree;
13172 + }
13173 +
13174 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
13175 + crt_fq_count * sizeof(struct qman_fq),
13176 + GFP_KERNEL);
13177 + if (!fqd->fqs) {
13178 + dev_err(dpa_oh_dev,
13179 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
13180 + oh_node->full_name,
13181 + dpa_oh_node->full_name);
13182 + _errno = -ENOMEM;
13183 + goto return_kfree;
13184 + }
13185 +
13186 + for (j = 0; j < crt_fq_count; j++)
13187 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
13188 + fqd->fqs_count = crt_fq_count;
13189 + /* channel ID is specified in another attribute */
13190 + fqd->channel_id = 0;
13191 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
13192 +
13193 + /* allocate the queue */
13194 +
13195 + }
13196 +
13197 + /* channel_ids for FQs that exit OH port */
13198 + lenp = 0;
13199 + channel_ids = of_get_property(dpa_oh_node,
13200 + "fsl,qman-channel-ids-egress", &lenp);
13201 +
13202 + channel_ids_count = lenp / (sizeof(*channel_ids));
13203 + if (channel_ids_count != duples_count) {
13204 + dev_warn(dpa_oh_dev,
13205 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
13206 + oh_node->full_name, dpa_oh_node->full_name);
13207 + /* just ignore the queues that do not have a Channel ID */
13208 + }
13209 +
13210 + channel_idx = 0;
13211 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13212 + if (channel_idx + 1 > channel_ids_count)
13213 + break;
13214 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13215 + fqd->channel_id =
13216 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
13217 + }
13218 +
13219 + /* create egress queues */
13220 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
13221 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13222 +
13223 + if (fqd->channel_id == 0) {
13224 + /* missing channel id in dts */
13225 + continue;
13226 + }
13227 +
13228 + for (j = 0; j < fqd->fqs_count; j++) {
13229 + ret = oh_fq_create(fqd->fqs + j,
13230 + (fqd->fqs + j)->fqid,
13231 + fqd->channel_id, 3);
13232 + if (ret != 0) {
13233 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
13234 + (fqd->fqs + j)->fqid,
13235 + oh_node->full_name,
13236 + dpa_oh_node->full_name);
13237 + _errno = -EINVAL;
13238 + goto return_kfree;
13239 + }
13240 + }
13241 + }
13242 +
13243 + /* Read FQ ids/nums for the DPA OH node */
13244 + oh_all_queues = of_get_property(dpa_oh_node,
13245 + "fsl,qman-frame-queues-oh", &lenp);
13246 + if (oh_all_queues == NULL) {
13247 + dev_err(dpa_oh_dev,
13248 + "No frame queues have been defined for OH node %s referenced from node %s\n",
13249 + oh_node->full_name, dpa_oh_node->full_name);
13250 + _errno = -EINVAL;
13251 + goto return_kfree;
13252 + }
13253 +
13254 + /* Check that the OH error and default FQs are there */
13255 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
13256 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
13257 + if (queues_count != 2) {
13258 + dev_err(dpa_oh_dev,
13259 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
13260 + oh_node->full_name, dpa_oh_node->full_name);
13261 + _errno = -EINVAL;
13262 + goto return_kfree;
13263 + }
13264 +
13265 + /* Read the FQIDs defined for this OH port */
13266 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
13267 + fq_idx = 0;
13268 +
13269 + /* Error FQID - must be present */
13270 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13271 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13272 + if (crt_fq_count != 1) {
13273 + dev_err(dpa_oh_dev,
13274 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
13275 + oh_node->full_name, dpa_oh_node->full_name,
13276 + crt_fq_count);
13277 + _errno = -EINVAL;
13278 + goto return_kfree;
13279 + }
13280 + oh_config->error_fqid = crt_fqid_base;
13281 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
13282 + oh_config->error_fqid, oh_node->full_name);
13283 +
13284 + /* Default FQID - must be present */
13285 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
13286 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
13287 + if (crt_fq_count != 1) {
13288 + dev_err(dpa_oh_dev,
13289 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
13290 + oh_node->full_name, dpa_oh_node->full_name,
13291 + crt_fq_count);
13292 + _errno = -EINVAL;
13293 + goto return_kfree;
13294 + }
13295 + oh_config->default_fqid = crt_fqid_base;
13296 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
13297 + oh_config->default_fqid, oh_node->full_name);
13298 +
13299 + /* TX FQID - presence is optional */
13300 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
13301 + &lenp);
13302 + if (oh_tx_queues == NULL) {
13303 + dev_dbg(dpa_oh_dev,
13304 + "No tx queues have been defined for OH node %s referenced from node %s\n",
13305 + oh_node->full_name, dpa_oh_node->full_name);
13306 + goto config_port;
13307 + }
13308 +
13309 + /* Check that queues-tx has only a base and a count defined */
13310 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
13311 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
13312 + if (queues_count != 1) {
13313 + dev_err(dpa_oh_dev,
13314 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
13315 + oh_node->full_name, dpa_oh_node->full_name);
13316 + _errno = -EINVAL;
13317 + goto return_kfree;
13318 + }
13319 +
13320 + fq_idx = 0;
13321 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
13322 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
13323 + oh_config->egress_cnt = crt_fq_count;
13324 +
13325 + /* Allocate TX queues */
13326 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
13327 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
13328 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
13329 + if (oh_config->egress_fqs == NULL) {
13330 + dev_err(dpa_oh_dev,
13331 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
13332 + oh_node->full_name, dpa_oh_node->full_name);
13333 + _errno = -ENOMEM;
13334 + goto return_kfree;
13335 + }
13336 +
13337 + /* Create TX queues */
13338 + for (i = 0; i < crt_fq_count; i++) {
13339 + ret = oh_fq_create(oh_config->egress_fqs + i,
13340 + crt_fqid_base + i, (uint16_t)channel_id, 3);
13341 + if (ret != 0) {
13342 + dev_err(dpa_oh_dev,
13343 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
13344 + crt_fqid_base + i, oh_node->full_name,
13345 + dpa_oh_node->full_name);
13346 + _errno = -EINVAL;
13347 + goto return_kfree;
13348 + }
13349 + }
13350 +
13351 +config_port:
13352 + /* Get a handle to the fm_port so we can set
13353 + * its configuration params
13354 + */
13355 + oh_config->oh_port = fm_port_bind(oh_dev);
13356 + if (oh_config->oh_port == NULL) {
13357 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
13358 + oh_node->full_name);
13359 + _errno = -EINVAL;
13360 + goto return_kfree;
13361 + }
13362 +
13363 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
13364 +
13365 + /* read the pool handlers */
13366 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
13367 + "fsl,bman-buffer-pools", NULL);
13368 + if (crt_ext_pools_count <= 0) {
13369 + dev_info(dpa_oh_dev,
13370 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
13371 + oh_node->full_name);
13372 + goto init_port;
13373 + }
13374 +
13375 + /* used for reading ext_pool_size*/
13376 + root_node = of_find_node_by_path("/");
13377 + if (root_node == NULL) {
13378 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
13379 + _errno = -EINVAL;
13380 + goto return_kfree;
13381 + }
13382 +
13383 + n_size = of_n_size_cells(root_node);
13384 + of_node_put(root_node);
13385 +
13386 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
13387 + crt_ext_pools_count);
13388 +
13389 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
13390 +
13391 + for (i = 0; i < crt_ext_pools_count; i++) {
13392 + bpool_node = of_parse_phandle(dpa_oh_node,
13393 + "fsl,bman-buffer-pools", i);
13394 + if (bpool_node == NULL) {
13395 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
13396 + _errno = -EINVAL;
13397 + goto return_kfree;
13398 + }
13399 +
13400 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
13401 + if (_errno) {
13402 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
13403 + _errno = -EINVAL;
13404 + goto return_kfree;
13405 + }
13406 +
13407 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
13408 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
13409 +
13410 + bpool_cfg = of_get_property(bpool_node,
13411 + "fsl,bpool-ethernet-cfg", &lenp);
13412 + if (bpool_cfg == NULL) {
13413 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
13414 + _errno = -EINVAL;
13415 + goto return_kfree;
13416 + }
13417 +
13418 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
13419 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
13420 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
13421 + ext_pool_size);
13422 + of_node_put(bpool_node);
13423 +
13424 + }
13425 +
13426 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
13427 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
13428 + goto init_port;
13429 +
13430 + frag_enabled = true;
13431 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
13432 + port_id);
13433 +
13434 +init_port:
13435 + of_node_put(oh_node);
13436 + /* Set Tx params */
13437 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
13438 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
13439 + frag_enabled);
13440 + /* Set PCD params */
13441 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
13442 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
13443 + oh_port_pcd_params.dev = dpa_oh_dev;
13444 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
13445 +
13446 + dev_set_drvdata(dpa_oh_dev, oh_config);
13447 +
13448 + /* Enable the OH port */
13449 + _errno = fm_port_enable(oh_config->oh_port);
13450 + if (_errno)
13451 + goto return_kfree;
13452 +
13453 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
13454 +
13455 + /* print of all referenced & created queues */
13456 + dump_oh_config(dpa_oh_dev, oh_config);
13457 +
13458 + return 0;
13459 +
13460 +return_kfree:
13461 + if (bpool_node)
13462 + of_node_put(bpool_node);
13463 + if (oh_node)
13464 + of_node_put(oh_node);
13465 + if (oh_config && oh_config->egress_fqs)
13466 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
13467 +
13468 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
13469 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13470 + list_del(fq_list);
13471 + devm_kfree(dpa_oh_dev, fqd->fqs);
13472 + devm_kfree(dpa_oh_dev, fqd);
13473 + }
13474 +
13475 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
13476 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
13477 + list_del(fq_list);
13478 + devm_kfree(dpa_oh_dev, fqd->fqs);
13479 + devm_kfree(dpa_oh_dev, fqd);
13480 + }
13481 +
13482 + devm_kfree(dpa_oh_dev, oh_config);
13483 + return _errno;
13484 +}
13485 +
13486 +static int __cold oh_port_remove(struct platform_device *_of_dev)
13487 +{
13488 + int _errno = 0, i;
13489 + struct dpa_oh_config_s *oh_config;
13490 +
13491 + pr_info("Removing OH port...\n");
13492 +
13493 + oh_config = dev_get_drvdata(&_of_dev->dev);
13494 + if (oh_config == NULL) {
13495 + pr_err(KBUILD_MODNAME
13496 + ": %s:%hu:%s(): No OH config in device private data!\n",
13497 + KBUILD_BASENAME".c", __LINE__, __func__);
13498 + _errno = -ENODEV;
13499 + goto return_error;
13500 + }
13501 +
13502 + if (oh_config->egress_fqs)
13503 + for (i = 0; i < oh_config->egress_cnt; i++)
13504 + oh_fq_destroy(oh_config->egress_fqs + i);
13505 +
13506 + if (oh_config->oh_port == NULL) {
13507 + pr_err(KBUILD_MODNAME
13508 + ": %s:%hu:%s(): No fm port in device private data!\n",
13509 + KBUILD_BASENAME".c", __LINE__, __func__);
13510 + _errno = -EINVAL;
13511 + goto free_egress_fqs;
13512 + }
13513 +
13514 + _errno = fm_port_disable(oh_config->oh_port);
13515 +
13516 +free_egress_fqs:
13517 + if (oh_config->egress_fqs)
13518 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
13519 + devm_kfree(&_of_dev->dev, oh_config);
13520 + dev_set_drvdata(&_of_dev->dev, NULL);
13521 +
13522 +return_error:
13523 + return _errno;
13524 +}
13525 +
13526 +static struct platform_driver oh_port_driver = {
13527 + .driver = {
13528 + .name = KBUILD_MODNAME,
13529 + .of_match_table = oh_port_match_table,
13530 + .owner = THIS_MODULE,
13531 + .pm = OH_PM_OPS,
13532 + },
13533 + .probe = oh_port_probe,
13534 + .remove = oh_port_remove
13535 +};
13536 +
13537 +static int __init __cold oh_port_load(void)
13538 +{
13539 + int _errno;
13540 +
13541 + pr_info(OH_MOD_DESCRIPTION "\n");
13542 +
13543 + _errno = platform_driver_register(&oh_port_driver);
13544 + if (_errno < 0) {
13545 + pr_err(KBUILD_MODNAME
13546 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
13547 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
13548 + }
13549 +
13550 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13551 + KBUILD_BASENAME".c", __func__);
13552 + return _errno;
13553 +}
13554 +module_init(oh_port_load);
13555 +
13556 +static void __exit __cold oh_port_unload(void)
13557 +{
13558 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
13559 + KBUILD_BASENAME".c", __func__);
13560 +
13561 + platform_driver_unregister(&oh_port_driver);
13562 +
13563 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
13564 + KBUILD_BASENAME".c", __func__);
13565 +}
13566 +module_exit(oh_port_unload);
13567 --- /dev/null
13568 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
13569 @@ -0,0 +1,59 @@
13570 +/* Copyright 2011 Freescale Semiconductor Inc.
13571 + *
13572 + * Redistribution and use in source and binary forms, with or without
13573 + * modification, are permitted provided that the following conditions are met:
13574 + * * Redistributions of source code must retain the above copyright
13575 + * notice, this list of conditions and the following disclaimer.
13576 + * * Redistributions in binary form must reproduce the above copyright
13577 + * notice, this list of conditions and the following disclaimer in the
13578 + * documentation and/or other materials provided with the distribution.
13579 + * * Neither the name of Freescale Semiconductor nor the
13580 + * names of its contributors may be used to endorse or promote products
13581 + * derived from this software without specific prior written permission.
13582 + *
13583 + *
13584 + * ALTERNATIVELY, this software may be distributed under the terms of the
13585 + * GNU General Public License ("GPL") as published by the Free Software
13586 + * Foundation, either version 2 of that License or (at your option) any
13587 + * later version.
13588 + *
13589 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13590 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13591 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13592 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13593 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13594 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13595 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13596 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13597 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13598 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13599 + */
13600 +
13601 +#ifndef __OFFLINE_PORT_H
13602 +#define __OFFLINE_PORT_H
13603 +
13604 +struct fm_port;
13605 +struct qman_fq;
13606 +
13607 +/* fqs are defined in duples (base_fq, fq_count) */
13608 +struct fq_duple {
13609 + struct qman_fq *fqs;
13610 + int fqs_count;
13611 + uint16_t channel_id;
13612 + struct list_head fq_list;
13613 +};
13614 +
13615 +/* OH port configuration */
13616 +struct dpa_oh_config_s {
13617 + uint32_t error_fqid;
13618 + uint32_t default_fqid;
13619 + struct fm_port *oh_port;
13620 + uint32_t egress_cnt;
13621 + struct qman_fq *egress_fqs;
13622 + uint16_t channel;
13623 +
13624 + struct list_head fqs_ingress_list;
13625 + struct list_head fqs_egress_list;
13626 +};
13627 +
13628 +#endif /* __OFFLINE_PORT_H */
13629 --- /dev/null
13630 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
13631 @@ -0,0 +1,153 @@
13632 +menu "Frame Manager support"
13633 +
13634 +menuconfig FSL_SDK_FMAN
13635 + bool "Freescale Frame Manager (datapath) support - SDK driver"
13636 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
13637 + default y
13638 + ---help---
13639 + If unsure, say Y.
13640 +
13641 +if FSL_SDK_FMAN
13642 +
13643 +config FSL_SDK_FMAN_TEST
13644 + bool "FMan test module"
13645 + default n
13646 + select FSL_DPAA_HOOKS
13647 + ---help---
13648 + This option compiles test code for FMan.
13649 +
13650 +menu "FMAN Processor support"
13651 +choice
13652 + depends on FSL_SDK_FMAN
13653 + prompt "Processor Type"
13654 +
13655 +config FMAN_ARM
13656 + bool "LS1043"
13657 + depends on ARM64 || ARM
13658 + ---help---
13659 + Choose "LS1043" for the ARM platforms:
13660 + LS1043
13661 +
13662 +config FMAN_P3040_P4080_P5020
13663 + bool "P3040 P4080 5020"
13664 +
13665 +config FMAN_P1023
13666 + bool "P1023"
13667 +
13668 +config FMAN_V3H
13669 + bool "FmanV3H"
13670 + ---help---
13671 + Choose "FmanV3H" for Fman rev3H:
13672 + B4860, T4240, T4160, etc
13673 +
13674 +config FMAN_V3L
13675 + bool "FmanV3L"
13676 + ---help---
13677 + Choose "FmanV3L" for Fman rev3L:
13678 + T1040, T1042, T1020, T1022, T1023, T1024, etc
13679 +
13680 +endchoice
13681 +endmenu
13682 +
13683 +config FMAN_MIB_CNT_OVF_IRQ_EN
13684 + bool "Enable the dTSEC MIB counters overflow interrupt"
13685 + default n
13686 + ---help---
13687 + Enable the dTSEC MIB counters overflow interrupt to get
13688 + accurate MIB counters values. Enabled it compensates
13689 + for the counters overflow but reduces performance and
13690 + triggers error messages in HV setups.
13691 +
13692 +config FSL_FM_MAX_FRAME_SIZE
13693 + int "Maximum L2 frame size"
13694 + depends on FSL_SDK_FMAN
13695 + range 64 9600
13696 + default "1522"
13697 + help
13698 + Configure this in relation to the maximum possible MTU of your
13699 + network configuration. In particular, one would need to
13700 + increase this value in order to use jumbo frames.
13701 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
13702 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
13703 + excess of the desired L3 MTU.
13704 +
13705 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
13706 + than the actual MTU) may lead to buffer exhaustion, especially
13707 + in the case of badly fragmented datagrams on the Rx path.
13708 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
13709 + MTU will lead to frames being dropped.
13710 +
13711 + This can be overridden by specifying "fsl_fm_max_frm" in
13712 + the kernel bootargs:
13713 + * in Hypervisor-based scenarios, by adding a "chosen" node
13714 + with the "bootargs" property specifying
13715 + "fsl_fm_max_frm=<YourValue>";
13716 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13717 + modifying the "bootargs" env variable.
13718 +
13719 +config FSL_FM_RX_EXTRA_HEADROOM
13720 + int "Add extra headroom at beginning of data buffers"
13721 + depends on FSL_SDK_FMAN
13722 + range 16 384
13723 + default "64"
13724 + help
13725 + Configure this to tell the Frame Manager to reserve some extra
13726 + space at the beginning of a data buffer on the receive path,
13727 + before Internal Context fields are copied. This is in addition
13728 + to the private data area already reserved for driver internal
13729 + use. The provided value must be a multiple of 16.
13730 +
13731 + This setting can be overridden by specifying
13732 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
13733 + * in Hypervisor-based scenarios, by adding a "chosen" node
13734 + with the "bootargs" property specifying
13735 + "fsl_fm_rx_extra_headroom=<YourValue>";
13736 + * in non-Hypervisor-based scenarios, via u-boot's env, by
13737 + modifying the "bootargs" env variable.
13738 +
13739 +config FMAN_PFC
13740 + bool "FMan PFC support (EXPERIMENTAL)"
13741 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
13742 + default n
13743 + help
13744 + This option enables PFC support on FMan v3 ports.
13745 + Data Center Bridging defines Classes of Service that are
13746 + flow-controlled using PFC pause frames.
13747 +
13748 +if FMAN_PFC
13749 +config FMAN_PFC_COS_COUNT
13750 + int "Number of PFC Classes of Service"
13751 + depends on FMAN_PFC && FSL_SDK_FMAN
13752 + range 1 4
13753 + default "3"
13754 + help
13755 + The number of Classes of Service controlled by PFC.
13756 +
13757 +config FMAN_PFC_QUANTA_0
13758 + int "The pause quanta for PFC CoS 0"
13759 + depends on FMAN_PFC && FSL_SDK_FMAN
13760 + range 0 65535
13761 + default "65535"
13762 +
13763 +config FMAN_PFC_QUANTA_1
13764 + int "The pause quanta for PFC CoS 1"
13765 + depends on FMAN_PFC && FSL_SDK_FMAN
13766 + range 0 65535
13767 + default "65535"
13768 +
13769 +config FMAN_PFC_QUANTA_2
13770 + int "The pause quanta for PFC CoS 2"
13771 + depends on FMAN_PFC && FSL_SDK_FMAN
13772 + range 0 65535
13773 + default "65535"
13774 +
13775 +config FMAN_PFC_QUANTA_3
13776 + int "The pause quanta for PFC CoS 3"
13777 + depends on FMAN_PFC && FSL_SDK_FMAN
13778 + range 0 65535
13779 + default "65535"
13780 +endif
13781 +
13782 +endif # FSL_SDK_FMAN
13783 +
13784 +endmenu
13785 --- /dev/null
13786 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
13787 @@ -0,0 +1,11 @@
13788 +#
13789 +# Makefile for the Freescale Ethernet controllers
13790 +#
13791 +ccflags-y += -DVERSION=\"\"
13792 +#
13793 +#Include netcomm SW specific definitions
13794 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13795 +#
13796 +obj-y += etc/
13797 +obj-y += Peripherals/FM/
13798 +obj-y += src/
13799 --- /dev/null
13800 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
13801 @@ -0,0 +1,15 @@
13802 +#
13803 +# Makefile for the Freescale Ethernet controllers
13804 +#
13805 +ccflags-y += -DVERSION=\"\"
13806 +#
13807 +#Include netcomm SW specific definitions
13808 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
13809 +
13810 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
13811 +
13812 +ccflags-y += -I$(NCSW_FM_INC)
13813 +
13814 +obj-y += fsl-ncsw-Hc.o
13815 +
13816 +fsl-ncsw-Hc-objs := hc.o
13817 --- /dev/null
13818 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
13819 @@ -0,0 +1,1232 @@
13820 +/*
13821 + * Copyright 2008-2012 Freescale Semiconductor Inc.
13822 + *
13823 + * Redistribution and use in source and binary forms, with or without
13824 + * modification, are permitted provided that the following conditions are met:
13825 + * * Redistributions of source code must retain the above copyright
13826 + * notice, this list of conditions and the following disclaimer.
13827 + * * Redistributions in binary form must reproduce the above copyright
13828 + * notice, this list of conditions and the following disclaimer in the
13829 + * documentation and/or other materials provided with the distribution.
13830 + * * Neither the name of Freescale Semiconductor nor the
13831 + * names of its contributors may be used to endorse or promote products
13832 + * derived from this software without specific prior written permission.
13833 + *
13834 + *
13835 + * ALTERNATIVELY, this software may be distributed under the terms of the
13836 + * GNU General Public License ("GPL") as published by the Free Software
13837 + * Foundation, either version 2 of that License or (at your option) any
13838 + * later version.
13839 + *
13840 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13841 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13842 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13843 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13844 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13845 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13846 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13847 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13848 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13849 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13850 + */
13851 +
13852 +
13853 +#include "std_ext.h"
13854 +#include "error_ext.h"
13855 +#include "sprint_ext.h"
13856 +#include "string_ext.h"
13857 +
13858 +#include "fm_common.h"
13859 +#include "fm_hc.h"
13860 +
13861 +
13862 +/**************************************************************************//**
13863 + @Description defaults
13864 +*//***************************************************************************/
13865 +#define DEFAULT_dataMemId 0
13866 +
13867 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
13868 +#define HC_HCOR_OPCODE_KG_SCM 0x1
13869 +#define HC_HCOR_OPCODE_SYNC 0x2
13870 +#define HC_HCOR_OPCODE_CC 0x3
13871 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
13872 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
13873 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
13874 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
13875 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
13876 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
13877 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
13878 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
13879 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
13880 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
13881 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
13882 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
13883 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
13884 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
13885 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
13886 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
13887 +
13888 +#define HC_HCOR_GBL 0x20000000
13889 +
13890 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
13891 +
13892 +#if (DPAA_VERSION == 10)
13893 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
13894 +#else
13895 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
13896 +#endif /* (DPAA_VERSION == 10) */
13897 +
13898 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
13899 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
13900 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
13901 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
13902 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
13903 +
13904 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
13905 +
13906 +#define BUILD_FD(len) \
13907 +do { \
13908 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
13909 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
13910 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
13911 + DPAA_FD_SET_LENGTH(&fmFd, len); \
13912 +} while (0)
13913 +
13914 +
13915 +#if defined(__MWERKS__) && !defined(__GNUC__)
13916 +#pragma pack(push,1)
13917 +#endif /* defined(__MWERKS__) && ... */
13918 +
13919 +typedef struct t_FmPcdKgPortRegs {
13920 + volatile uint32_t spReg;
13921 + volatile uint32_t cppReg;
13922 +} t_FmPcdKgPortRegs;
13923 +
13924 +typedef struct t_HcFrame {
13925 + volatile uint32_t opcode;
13926 + volatile uint32_t actionReg;
13927 + volatile uint32_t extraReg;
13928 + volatile uint32_t commandSequence;
13929 + union {
13930 + struct fman_kg_scheme_regs schemeRegs;
13931 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
13932 + t_FmPcdPlcrProfileRegs profileRegs;
13933 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
13934 + t_FmPcdKgPortRegs portRegsForRead;
13935 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
13936 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
13937 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
13938 + } hcSpecificData;
13939 +} t_HcFrame;
13940 +
13941 +#if defined(__MWERKS__) && !defined(__GNUC__)
13942 +#pragma pack(pop)
13943 +#endif /* defined(__MWERKS__) && ... */
13944 +
13945 +
13946 +typedef struct t_FmHc {
13947 + t_Handle h_FmPcd;
13948 + t_Handle h_HcPortDev;
13949 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
13950 + t_Handle h_QmArg; /**< A handle to the QM module */
13951 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
13952 +
13953 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
13954 + taking buffer */
13955 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
13956 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
13957 + and not confirmed yet */
13958 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
13959 +} t_FmHc;
13960 +
13961 +
13962 +static t_Error FillBufPool(t_FmHc *p_FmHc)
13963 +{
13964 + uint32_t i;
13965 +
13966 + ASSERT_COND(p_FmHc);
13967 +
13968 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13969 + {
13970 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
13971 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
13972 + p_FmHc->dataMemId,
13973 + 16);
13974 +#else
13975 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
13976 + p_FmHc->dataMemId,
13977 + 16);
13978 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
13979 + if (!p_FmHc->p_Frm[i])
13980 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
13981 + }
13982 +
13983 + /* Initialize FIFO of seqNum to use during GetBuf */
13984 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
13985 + {
13986 + p_FmHc->seqNum[i] = i;
13987 + }
13988 + p_FmHc->nextSeqNumLocation = 0;
13989 +
13990 + return E_OK;
13991 +}
13992 +
13993 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
13994 +{
13995 + uint32_t intFlags;
13996 +
13997 + ASSERT_COND(p_FmHc);
13998 +
13999 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14000 +
14001 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
14002 + {
14003 + /* No more buffers */
14004 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14005 + return NULL;
14006 + }
14007 +
14008 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
14009 + p_FmHc->nextSeqNumLocation++;
14010 +
14011 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14012 + return p_FmHc->p_Frm[*p_SeqNum];
14013 +}
14014 +
14015 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
14016 +{
14017 + uint32_t intFlags;
14018 +
14019 + UNUSED(p_Buf);
14020 +
14021 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14022 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
14023 + p_FmHc->nextSeqNumLocation--;
14024 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
14025 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14026 +}
14027 +
14028 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
14029 +{
14030 + t_Error err = E_OK;
14031 + uint32_t intFlags;
14032 + uint32_t timeout=100;
14033 +
14034 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14035 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
14036 + p_FmHc->enqueued[seqNum] = TRUE;
14037 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14038 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
14039 + seqNum,
14040 + DPAA_FD_GET_ADDR(p_FmFd),
14041 + DPAA_FD_GET_OFFSET(p_FmFd)));
14042 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
14043 + if (err)
14044 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
14045 +
14046 + while (p_FmHc->enqueued[seqNum] && --timeout)
14047 + XX_UDelay(100);
14048 +
14049 + if (!timeout)
14050 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
14051 +
14052 + return err;
14053 +}
14054 +
14055 +
14056 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
14057 +{
14058 + t_FmHc *p_FmHc;
14059 + t_FmPortParams fmPortParam;
14060 + t_Error err;
14061 +
14062 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
14063 + if (!p_FmHc)
14064 + {
14065 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
14066 + return NULL;
14067 + }
14068 + memset(p_FmHc,0,sizeof(t_FmHc));
14069 +
14070 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
14071 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
14072 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
14073 + p_FmHc->dataMemId = DEFAULT_dataMemId;
14074 +
14075 + err = FillBufPool(p_FmHc);
14076 + if (err != E_OK)
14077 + {
14078 + REPORT_ERROR(MAJOR, err, NO_MSG);
14079 + FmHcFree(p_FmHc);
14080 + return NULL;
14081 + }
14082 +
14083 + if (!FmIsMaster(p_FmHcParams->h_Fm))
14084 + return (t_Handle)p_FmHc;
14085 +
14086 + memset(&fmPortParam, 0, sizeof(fmPortParam));
14087 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
14088 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
14089 + fmPortParam.portId = p_FmHcParams->params.portId;
14090 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
14091 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
14092 +
14093 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
14094 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
14095 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
14096 +
14097 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
14098 + if (!p_FmHc->h_HcPortDev)
14099 + {
14100 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
14101 + XX_Free(p_FmHc);
14102 + return NULL;
14103 + }
14104 +
14105 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
14106 + (uint16_t)sizeof(t_HcFrame));
14107 +
14108 + if (err != E_OK)
14109 + {
14110 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14111 + FmHcFree(p_FmHc);
14112 + return NULL;
14113 + }
14114 +
14115 + /* final init */
14116 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
14117 + if (err != E_OK)
14118 + {
14119 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
14120 + FmHcFree(p_FmHc);
14121 + return NULL;
14122 + }
14123 +
14124 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
14125 + if (err != E_OK)
14126 + {
14127 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
14128 + FmHcFree(p_FmHc);
14129 + return NULL;
14130 + }
14131 +
14132 + return (t_Handle)p_FmHc;
14133 +}
14134 +
14135 +void FmHcFree(t_Handle h_FmHc)
14136 +{
14137 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14138 + int i;
14139 +
14140 + if (!p_FmHc)
14141 + return;
14142 +
14143 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14144 + if (p_FmHc->p_Frm[i])
14145 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14146 + else
14147 + break;
14148 +
14149 + if (p_FmHc->h_HcPortDev)
14150 + FM_PORT_Free(p_FmHc->h_HcPortDev);
14151 +
14152 + XX_Free(p_FmHc);
14153 +}
14154 +
14155 +/*****************************************************************************/
14156 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
14157 + uint8_t memId)
14158 +{
14159 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14160 + int i;
14161 +
14162 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14163 +
14164 + p_FmHc->dataMemId = memId;
14165 +
14166 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
14167 + if (p_FmHc->p_Frm[i])
14168 + XX_FreeSmart(p_FmHc->p_Frm[i]);
14169 +
14170 + return FillBufPool(p_FmHc);
14171 +}
14172 +
14173 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
14174 +{
14175 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14176 + t_HcFrame *p_HcFrame;
14177 + uint32_t intFlags;
14178 +
14179 + ASSERT_COND(p_FmHc);
14180 +
14181 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
14182 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
14183 +
14184 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
14185 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
14186 +
14187 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
14188 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
14189 + else
14190 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
14191 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
14192 +}
14193 +
14194 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
14195 + t_Handle h_Scheme,
14196 + struct fman_kg_scheme_regs *p_SchemeRegs,
14197 + bool updateCounter)
14198 +{
14199 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14200 + t_Error err = E_OK;
14201 + t_HcFrame *p_HcFrame;
14202 + t_DpaaFD fmFd;
14203 + uint8_t physicalSchemeId;
14204 + uint32_t seqNum;
14205 +
14206 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14207 + if (!p_HcFrame)
14208 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14209 +
14210 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14211 +
14212 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14213 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14214 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
14215 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14216 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
14217 + if (!updateCounter)
14218 + {
14219 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
14220 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
14221 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
14222 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
14223 + }
14224 + p_HcFrame->commandSequence = seqNum;
14225 +
14226 + BUILD_FD(sizeof(t_HcFrame));
14227 +
14228 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14229 +
14230 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14231 +
14232 + if (err != E_OK)
14233 + RETURN_ERROR(MINOR, err, NO_MSG);
14234 +
14235 + return E_OK;
14236 +}
14237 +
14238 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
14239 +{
14240 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14241 + t_Error err = E_OK;
14242 + t_HcFrame *p_HcFrame;
14243 + t_DpaaFD fmFd;
14244 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14245 + uint32_t seqNum;
14246 +
14247 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14248 + if (!p_HcFrame)
14249 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14250 +
14251 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14252 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14253 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14254 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14255 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
14256 + p_HcFrame->commandSequence = seqNum;
14257 +
14258 + BUILD_FD(sizeof(t_HcFrame));
14259 +
14260 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14261 +
14262 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14263 +
14264 + if (err != E_OK)
14265 + RETURN_ERROR(MINOR, err, NO_MSG);
14266 +
14267 + return E_OK;
14268 +}
14269 +
14270 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
14271 +{
14272 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14273 + t_Error err = E_OK;
14274 + t_HcFrame *p_HcFrame;
14275 + t_DpaaFD fmFd;
14276 + uint8_t relativeSchemeId;
14277 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14278 + uint32_t tmpReg32 = 0;
14279 + uint32_t seqNum;
14280 +
14281 + /* Scheme is locked by calling routine */
14282 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14283 + * "kgse_mode" or "kgse_om" without locking scheme !
14284 + */
14285 +
14286 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14287 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14288 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14289 +
14290 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
14291 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
14292 + {
14293 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14294 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
14295 + {
14296 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
14297 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
14298 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
14299 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
14300 + if (err)
14301 + RETURN_ERROR(MAJOR, err, NO_MSG);
14302 + }
14303 + else /* From here we deal with KG-Schemes only */
14304 + {
14305 + /* Pre change general code */
14306 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14307 + if (!p_HcFrame)
14308 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14309 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14310 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14311 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14312 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14313 + p_HcFrame->commandSequence = seqNum;
14314 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14315 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14316 + {
14317 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14318 + RETURN_ERROR(MINOR, err, NO_MSG);
14319 + }
14320 +
14321 + /* specific change */
14322 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
14323 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
14324 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
14325 + {
14326 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14327 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
14328 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14329 + }
14330 +
14331 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
14332 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
14333 + {
14334 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14335 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
14336 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
14337 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
14338 + }
14339 +
14340 + if (requiredAction & UPDATE_KG_OPT_MODE)
14341 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
14342 +
14343 + if (requiredAction & UPDATE_KG_NIA)
14344 + {
14345 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
14346 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
14347 + tmpReg32 |= value;
14348 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
14349 + }
14350 +
14351 + /* Post change general code */
14352 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14353 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
14354 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14355 +
14356 + BUILD_FD(sizeof(t_HcFrame));
14357 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14358 +
14359 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14360 +
14361 + if (err != E_OK)
14362 + RETURN_ERROR(MINOR, err, NO_MSG);
14363 + }
14364 + }
14365 +
14366 + return E_OK;
14367 +}
14368 +
14369 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
14370 +{
14371 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14372 + t_Error err;
14373 + t_HcFrame *p_HcFrame;
14374 + t_DpaaFD fmFd;
14375 + uint32_t retVal;
14376 + uint8_t relativeSchemeId;
14377 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14378 + uint32_t seqNum;
14379 +
14380 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14381 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14382 + {
14383 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14384 + return 0;
14385 + }
14386 +
14387 + /* first read scheme and check that it is valid */
14388 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14389 + if (!p_HcFrame)
14390 + {
14391 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14392 + return 0;
14393 + }
14394 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14395 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14396 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
14397 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14398 + p_HcFrame->commandSequence = seqNum;
14399 +
14400 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14401 +
14402 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14403 + if (err != E_OK)
14404 + {
14405 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14406 + REPORT_ERROR(MINOR, err, NO_MSG);
14407 + return 0;
14408 + }
14409 +
14410 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
14411 + {
14412 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14413 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
14414 + return 0;
14415 + }
14416 +
14417 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
14418 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14419 +
14420 + return retVal;
14421 +}
14422 +
14423 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
14424 +{
14425 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14426 + t_Error err = E_OK;
14427 + t_HcFrame *p_HcFrame;
14428 + t_DpaaFD fmFd;
14429 + uint8_t relativeSchemeId, physicalSchemeId;
14430 + uint32_t seqNum;
14431 +
14432 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
14433 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
14434 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
14435 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
14436 +
14437 + /* first read scheme and check that it is valid */
14438 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14439 + if (!p_HcFrame)
14440 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14441 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14442 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14443 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
14444 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
14445 + /* write counter */
14446 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14447 + p_HcFrame->commandSequence = seqNum;
14448 +
14449 + BUILD_FD(sizeof(t_HcFrame));
14450 +
14451 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14452 +
14453 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14454 + return err;
14455 +}
14456 +
14457 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
14458 +{
14459 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14460 + t_HcFrame *p_HcFrame;
14461 + t_DpaaFD fmFd;
14462 + uint8_t i, idx;
14463 + uint32_t seqNum;
14464 + t_Error err = E_OK;
14465 +
14466 + ASSERT_COND(p_FmHc);
14467 +
14468 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14469 + if (!p_HcFrame)
14470 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14471 +
14472 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
14473 + {
14474 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14475 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14476 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
14477 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14478 +
14479 + idx = (uint8_t)(i - p_Set->baseEntry);
14480 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
14481 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
14482 + p_HcFrame->commandSequence = seqNum;
14483 +
14484 + BUILD_FD(sizeof(t_HcFrame));
14485 +
14486 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14487 + {
14488 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14489 + RETURN_ERROR(MINOR, err, NO_MSG);
14490 + }
14491 + }
14492 +
14493 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14494 + return err;
14495 +}
14496 +
14497 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
14498 +{
14499 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14500 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
14501 +
14502 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
14503 + if (!p_ClsPlanSet)
14504 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
14505 +
14506 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
14507 +
14508 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
14509 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
14510 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
14511 +
14512 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
14513 + {
14514 + XX_Free(p_ClsPlanSet);
14515 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
14516 + }
14517 +
14518 + XX_Free(p_ClsPlanSet);
14519 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
14520 +
14521 + return E_OK;
14522 +}
14523 +
14524 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
14525 +{
14526 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14527 + t_HcFrame *p_HcFrame;
14528 + t_DpaaFD fmFd;
14529 + t_Error err;
14530 + uint32_t seqNum;
14531 +
14532 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14533 +
14534 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14535 + if (!p_HcFrame)
14536 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14537 +
14538 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14539 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
14540 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
14541 + p_HcFrame->commandSequence = seqNum;
14542 + BUILD_FD(sizeof(t_HcFrame));
14543 +
14544 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14545 +
14546 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14547 + return err;
14548 +}
14549 +
14550 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
14551 +{
14552 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14553 + t_HcFrame *p_HcFrame;
14554 + t_DpaaFD fmFd;
14555 + t_Error err;
14556 + uint32_t seqNum;
14557 +
14558 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14559 +
14560 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14561 + if (!p_HcFrame)
14562 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14563 +
14564 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14565 +
14566 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
14567 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
14568 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
14569 + if (fill == TRUE)
14570 + {
14571 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
14572 + }
14573 + p_HcFrame->commandSequence = seqNum;
14574 +
14575 + BUILD_FD(sizeof(t_HcFrame));
14576 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14577 + {
14578 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14579 + RETURN_ERROR(MINOR, err, NO_MSG);
14580 + }
14581 +
14582 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
14583 +
14584 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14585 + return E_OK;
14586 +}
14587 +
14588 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
14589 +{
14590 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14591 + t_HcFrame *p_HcFrame;
14592 + t_DpaaFD fmFd;
14593 + t_Error err;
14594 + uint32_t seqNum;
14595 +
14596 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14597 +
14598 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14599 + if (!p_HcFrame)
14600 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14601 +
14602 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14603 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
14604 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
14605 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
14606 + p_HcFrame->commandSequence = seqNum;
14607 +
14608 + BUILD_FD(sizeof(t_HcFrame));
14609 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14610 + {
14611 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14612 + RETURN_ERROR(MINOR, err, NO_MSG);
14613 + }
14614 +
14615 + *p_Result = (uint8_t)
14616 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
14617 +
14618 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14619 + return E_OK;
14620 +}
14621 +
14622 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
14623 +{
14624 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14625 + t_HcFrame *p_HcFrame;
14626 + t_DpaaFD fmFd;
14627 + t_Error err;
14628 + uint32_t tmpReg32 = 0;
14629 + uint32_t requiredActionTmp, requiredActionFlag;
14630 + uint32_t seqNum;
14631 +
14632 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14633 +
14634 + /* Profile is locked by calling routine */
14635 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
14636 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
14637 + */
14638 +
14639 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
14640 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
14641 +
14642 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
14643 + {
14644 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
14645 + {
14646 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14647 + if (!p_HcFrame)
14648 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14649 + /* first read scheme and check that it is valid */
14650 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14651 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14652 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14653 + p_HcFrame->extraReg = 0x00008000;
14654 + p_HcFrame->commandSequence = seqNum;
14655 +
14656 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14657 +
14658 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14659 + {
14660 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14661 + RETURN_ERROR(MINOR, err, NO_MSG);
14662 + }
14663 +
14664 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
14665 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14666 + {
14667 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14668 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
14669 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14670 + }
14671 +
14672 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14673 +
14674 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14675 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14676 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
14677 + p_HcFrame->extraReg = 0x00008000;
14678 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14679 +
14680 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14681 +
14682 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14683 + {
14684 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14685 + RETURN_ERROR(MINOR, err, NO_MSG);
14686 + }
14687 +
14688 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
14689 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14690 + {
14691 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14692 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14693 + }
14694 +
14695 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14696 +
14697 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14698 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14699 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
14700 + p_HcFrame->extraReg = 0x00008000;
14701 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14702 +
14703 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14704 +
14705 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14706 + {
14707 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14708 + RETURN_ERROR(MINOR, err, NO_MSG);
14709 + }
14710 +
14711 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
14712 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
14713 + {
14714 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14715 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
14716 + }
14717 +
14718 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
14719 +
14720 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14721 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14722 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
14723 + p_HcFrame->extraReg = 0x00008000;
14724 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
14725 +
14726 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14727 +
14728 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14729 + {
14730 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14731 + RETURN_ERROR(MINOR, err, NO_MSG);
14732 + }
14733 +
14734 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14735 + }
14736 + }
14737 +
14738 + return E_OK;
14739 +}
14740 +
14741 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
14742 +{
14743 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14744 + t_Error err = E_OK;
14745 + uint16_t profileIndx;
14746 + t_HcFrame *p_HcFrame;
14747 + t_DpaaFD fmFd;
14748 + uint32_t seqNum;
14749 +
14750 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14751 + if (!p_HcFrame)
14752 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14753 +
14754 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14755 +
14756 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14757 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14758 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
14759 + p_HcFrame->extraReg = 0x00008000;
14760 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
14761 + p_HcFrame->commandSequence = seqNum;
14762 +
14763 + BUILD_FD(sizeof(t_HcFrame));
14764 +
14765 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14766 +
14767 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14768 +
14769 + if (err != E_OK)
14770 + RETURN_ERROR(MINOR, err, NO_MSG);
14771 +
14772 + return E_OK;
14773 +}
14774 +
14775 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
14776 +{
14777 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14778 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14779 + t_Error err = E_OK;
14780 + t_HcFrame *p_HcFrame;
14781 + t_DpaaFD fmFd;
14782 + uint32_t seqNum;
14783 +
14784 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14785 + if (!p_HcFrame)
14786 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14787 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14788 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14789 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14790 + p_HcFrame->actionReg |= 0x00008000;
14791 + p_HcFrame->extraReg = 0x00008000;
14792 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
14793 + p_HcFrame->commandSequence = seqNum;
14794 +
14795 + BUILD_FD(sizeof(t_HcFrame));
14796 +
14797 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14798 +
14799 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14800 +
14801 + if (err != E_OK)
14802 + RETURN_ERROR(MINOR, err, NO_MSG);
14803 +
14804 + return E_OK;
14805 +}
14806 +
14807 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
14808 +{
14809 +
14810 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14811 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14812 + t_Error err = E_OK;
14813 + t_HcFrame *p_HcFrame;
14814 + t_DpaaFD fmFd;
14815 + uint32_t seqNum;
14816 +
14817 + /* first read scheme and check that it is valid */
14818 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14819 + if (!p_HcFrame)
14820 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14821 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14822 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14823 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
14824 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
14825 + p_HcFrame->extraReg = 0x00008000;
14826 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
14827 + p_HcFrame->commandSequence = seqNum;
14828 +
14829 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
14830 +
14831 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14832 +
14833 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14834 +
14835 + if (err != E_OK)
14836 + RETURN_ERROR(MINOR, err, NO_MSG);
14837 +
14838 + return E_OK;
14839 +}
14840 +
14841 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
14842 +{
14843 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14844 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
14845 + t_Error err;
14846 + t_HcFrame *p_HcFrame;
14847 + t_DpaaFD fmFd;
14848 + uint32_t retVal = 0;
14849 + uint32_t seqNum;
14850 +
14851 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
14852 +
14853 + /* first read scheme and check that it is valid */
14854 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14855 + if (!p_HcFrame)
14856 + {
14857 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14858 + return 0;
14859 + }
14860 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14861 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
14862 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
14863 + p_HcFrame->extraReg = 0x00008000;
14864 + p_HcFrame->commandSequence = seqNum;
14865 +
14866 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
14867 +
14868 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14869 + if (err != E_OK)
14870 + {
14871 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14872 + REPORT_ERROR(MINOR, err, NO_MSG);
14873 + return 0;
14874 + }
14875 +
14876 + switch (counter)
14877 + {
14878 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
14879 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
14880 + break;
14881 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
14882 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
14883 + break;
14884 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
14885 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
14886 + break;
14887 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
14888 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
14889 + break;
14890 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
14891 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
14892 + break;
14893 + default:
14894 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
14895 + }
14896 +
14897 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14898 + return retVal;
14899 +}
14900 +
14901 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
14902 +{
14903 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14904 + t_HcFrame *p_HcFrame;
14905 + t_DpaaFD fmFd;
14906 + t_Error err = E_OK;
14907 + uint32_t seqNum;
14908 +
14909 + ASSERT_COND(p_FmHc);
14910 +
14911 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14912 + if (!p_HcFrame)
14913 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14914 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14915 + /* first read SP register */
14916 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14917 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
14918 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14919 + p_HcFrame->commandSequence = seqNum;
14920 +
14921 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
14922 +
14923 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
14924 + {
14925 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14926 + RETURN_ERROR(MINOR, err, NO_MSG);
14927 + }
14928 +
14929 + /* spReg is the first reg, so we can use it both for read and for write */
14930 + if (add)
14931 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
14932 + else
14933 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
14934 +
14935 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
14936 +
14937 + BUILD_FD(sizeof(t_HcFrame));
14938 +
14939 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14940 +
14941 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14942 +
14943 + if (err != E_OK)
14944 + RETURN_ERROR(MINOR, err, NO_MSG);
14945 +
14946 + return E_OK;
14947 +}
14948 +
14949 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
14950 +{
14951 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14952 + t_HcFrame *p_HcFrame;
14953 + t_DpaaFD fmFd;
14954 + t_Error err = E_OK;
14955 + uint32_t seqNum;
14956 +
14957 + ASSERT_COND(p_FmHc);
14958 +
14959 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14960 + if (!p_HcFrame)
14961 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14962 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14963 + /* first read SP register */
14964 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
14965 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
14966 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
14967 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
14968 + p_HcFrame->commandSequence = seqNum;
14969 +
14970 + BUILD_FD(sizeof(t_HcFrame));
14971 +
14972 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
14973 +
14974 + PutBuf(p_FmHc, p_HcFrame, seqNum);
14975 +
14976 + if (err != E_OK)
14977 + RETURN_ERROR(MINOR, err, NO_MSG);
14978 +
14979 + return E_OK;
14980 +}
14981 +
14982 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
14983 +{
14984 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
14985 + t_HcFrame *p_HcFrame;
14986 + t_DpaaFD fmFd;
14987 + t_Error err = E_OK;
14988 + uint32_t seqNum;
14989 +
14990 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
14991 +
14992 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
14993 + if (!p_HcFrame)
14994 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
14995 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
14996 +
14997 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
14998 + p_HcFrame->actionReg = newAdAddrOffset;
14999 + p_HcFrame->actionReg |= 0xc0000000;
15000 + p_HcFrame->extraReg = oldAdAddrOffset;
15001 + p_HcFrame->commandSequence = seqNum;
15002 +
15003 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
15004 +
15005 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15006 +
15007 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15008 +
15009 + if (err != E_OK)
15010 + RETURN_ERROR(MAJOR, err, NO_MSG);
15011 +
15012 + return E_OK;
15013 +}
15014 +
15015 +t_Error FmHcPcdSync(t_Handle h_FmHc)
15016 +{
15017 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15018 + t_HcFrame *p_HcFrame;
15019 + t_DpaaFD fmFd;
15020 + t_Error err = E_OK;
15021 + uint32_t seqNum;
15022 +
15023 + ASSERT_COND(p_FmHc);
15024 +
15025 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15026 + if (!p_HcFrame)
15027 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15028 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15029 + /* first read SP register */
15030 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
15031 + p_HcFrame->actionReg = 0;
15032 + p_HcFrame->extraReg = 0;
15033 + p_HcFrame->commandSequence = seqNum;
15034 +
15035 + BUILD_FD(sizeof(t_HcFrame));
15036 +
15037 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15038 +
15039 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15040 +
15041 + if (err != E_OK)
15042 + RETURN_ERROR(MINOR, err, NO_MSG);
15043 +
15044 + return E_OK;
15045 +}
15046 +
15047 +t_Handle FmHcGetPort(t_Handle h_FmHc)
15048 +{
15049 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15050 + return p_FmHc->h_HcPortDev;
15051 +}
15052 --- /dev/null
15053 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
15054 @@ -0,0 +1,28 @@
15055 +#
15056 +# Makefile for the Freescale Ethernet controllers
15057 +#
15058 +ccflags-y += -DVERSION=\"\"
15059 +#
15060 +#Include netcomm SW specific definitions
15061 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
15062 +
15063 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
15064 +
15065 +ccflags-y += -I$(NCSW_FM_INC)
15066 +
15067 +obj-y += fsl-ncsw-MAC.o
15068 +
15069 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
15070 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
15071 + fman_tgec.o fman_crc32.o
15072 +
15073 +ifeq ($(CONFIG_FMAN_V3H),y)
15074 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
15075 +endif
15076 +ifeq ($(CONFIG_FMAN_V3L),y)
15077 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
15078 +endif
15079 +ifeq ($(CONFIG_FMAN_ARM),y)
15080 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
15081 +endif
15082 +
15083 --- /dev/null
15084 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
15085 @@ -0,0 +1,1504 @@
15086 +/*
15087 + * Copyright 2008-2013 Freescale Semiconductor Inc.
15088 + *
15089 + * Redistribution and use in source and binary forms, with or without
15090 + * modification, are permitted provided that the following conditions are met:
15091 + * * Redistributions of source code must retain the above copyright
15092 + * notice, this list of conditions and the following disclaimer.
15093 + * * Redistributions in binary form must reproduce the above copyright
15094 + * notice, this list of conditions and the following disclaimer in the
15095 + * documentation and/or other materials provided with the distribution.
15096 + * * Neither the name of Freescale Semiconductor nor the
15097 + * names of its contributors may be used to endorse or promote products
15098 + * derived from this software without specific prior written permission.
15099 + *
15100 + *
15101 + * ALTERNATIVELY, this software may be distributed under the terms of the
15102 + * GNU General Public License ("GPL") as published by the Free Software
15103 + * Foundation, either version 2 of that License or (at your option) any
15104 + * later version.
15105 + *
15106 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15107 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15108 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15109 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15110 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15111 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15112 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15113 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15114 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15115 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15116 + */
15117 +
15118 +/******************************************************************************
15119 + @File dtsec.c
15120 +
15121 + @Description FMan dTSEC driver
15122 +*//***************************************************************************/
15123 +
15124 +#include "std_ext.h"
15125 +#include "error_ext.h"
15126 +#include "string_ext.h"
15127 +#include "xx_ext.h"
15128 +#include "endian_ext.h"
15129 +#include "debug_ext.h"
15130 +#include "crc_mac_addr_ext.h"
15131 +
15132 +#include "fm_common.h"
15133 +#include "dtsec.h"
15134 +#include "fsl_fman_dtsec.h"
15135 +#include "fsl_fman_dtsec_mii_acc.h"
15136 +
15137 +/*****************************************************************************/
15138 +/* Internal routines */
15139 +/*****************************************************************************/
15140 +
15141 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
15142 +{
15143 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
15144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
15145 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
15146 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
15147 + if (p_Dtsec->addr == 0)
15148 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
15149 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
15150 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
15151 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
15152 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
15153 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
15154 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
15155 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
15156 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
15157 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
15158 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
15159 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
15160 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
15161 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
15162 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
15163 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
15164 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
15165 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
15166 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
15167 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
15168 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
15169 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
15170 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
15171 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
15172 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
15173 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
15174 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
15175 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
15176 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
15177 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
15178 +
15179 + /* If Auto negotiation process is disabled, need to */
15180 + /* Set up the PHY using the MII Management Interface */
15181 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
15182 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
15183 + if (!p_Dtsec->f_Exception)
15184 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
15185 + if (!p_Dtsec->f_Event)
15186 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
15187 +
15188 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
15189 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
15190 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
15191 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
15192 +
15193 + return E_OK;
15194 +}
15195 +
15196 +/* ......................................................................... */
15197 +
15198 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
15199 +{
15200 + uint32_t crc;
15201 +
15202 + /* CRC calculation */
15203 + GET_MAC_ADDR_CRC(ethAddr, crc);
15204 +
15205 + crc = GetMirror32(crc);
15206 +
15207 + return crc;
15208 +}
15209 +
15210 +/* ......................................................................... */
15211 +
15212 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
15213 +{
15214 + uint32_t car1, car2;
15215 +
15216 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
15217 +
15218 + if (car1)
15219 + {
15220 + if (car1 & CAR1_TR64)
15221 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
15222 + if (car1 & CAR1_TR127)
15223 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
15224 + if (car1 & CAR1_TR255)
15225 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
15226 + if (car1 & CAR1_TR511)
15227 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
15228 + if (car1 & CAR1_TRK1)
15229 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
15230 + if (car1 & CAR1_TRMAX)
15231 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
15232 + if (car1 & CAR1_TRMGV)
15233 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
15234 + if (car1 & CAR1_RBYT)
15235 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
15236 + if (car1 & CAR1_RPKT)
15237 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
15238 + if (car1 & CAR1_RMCA)
15239 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
15240 + if (car1 & CAR1_RBCA)
15241 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
15242 + if (car1 & CAR1_RXPF)
15243 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
15244 + if (car1 & CAR1_RALN)
15245 + p_Dtsec->internalStatistics.raln += VAL16BIT;
15246 + if (car1 & CAR1_RFLR)
15247 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
15248 + if (car1 & CAR1_RCDE)
15249 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
15250 + if (car1 & CAR1_RCSE)
15251 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
15252 + if (car1 & CAR1_RUND)
15253 + p_Dtsec->internalStatistics.rund += VAL16BIT;
15254 + if (car1 & CAR1_ROVR)
15255 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
15256 + if (car1 & CAR1_RFRG)
15257 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
15258 + if (car1 & CAR1_RJBR)
15259 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
15260 + if (car1 & CAR1_RDRP)
15261 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
15262 + }
15263 + if (car2)
15264 + {
15265 + if (car2 & CAR2_TFCS)
15266 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
15267 + if (car2 & CAR2_TBYT)
15268 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
15269 + if (car2 & CAR2_TPKT)
15270 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
15271 + if (car2 & CAR2_TMCA)
15272 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
15273 + if (car2 & CAR2_TBCA)
15274 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
15275 + if (car2 & CAR2_TXPF)
15276 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
15277 + if (car2 & CAR2_TDRP)
15278 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
15279 + }
15280 +}
15281 +
15282 +/* .............................................................................. */
15283 +
15284 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
15285 +{
15286 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15287 +
15288 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
15289 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
15290 +
15291 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
15292 +}
15293 +
15294 +/* .............................................................................. */
15295 +
15296 +static void DtsecIsr(t_Handle h_Dtsec)
15297 +{
15298 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15299 + uint32_t event;
15300 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15301 +
15302 + /* do not handle MDIO events */
15303 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
15304 +
15305 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
15306 +
15307 + fman_dtsec_ack_event(p_DtsecMemMap, event);
15308 +
15309 + if (event & DTSEC_IMASK_BREN)
15310 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
15311 + if (event & DTSEC_IMASK_RXCEN)
15312 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
15313 + if (event & DTSEC_IMASK_MSROEN)
15314 + UpdateStatistics(p_Dtsec);
15315 + if (event & DTSEC_IMASK_GTSCEN)
15316 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
15317 + if (event & DTSEC_IMASK_BTEN)
15318 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
15319 + if (event & DTSEC_IMASK_TXCEN)
15320 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
15321 + if (event & DTSEC_IMASK_TXEEN)
15322 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
15323 + if (event & DTSEC_IMASK_LCEN)
15324 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
15325 + if (event & DTSEC_IMASK_CRLEN)
15326 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
15327 + if (event & DTSEC_IMASK_XFUNEN)
15328 + {
15329 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
15330 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15331 + {
15332 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
15333 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
15334 + /* This is a read only regidter */
15335 +
15336 + /* b. Read and save the value of TPKT */
15337 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
15338 +
15339 + /* c. Read the register at dTSEC address offset 0x32C */
15340 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15341 +
15342 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
15343 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
15344 + {
15345 + /* If they are not equal, save the value of this register and wait for at least
15346 + * MAXFRM*16 ns */
15347 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
15348 + }
15349 +
15350 + /* e. Read and save TPKT again and read the register at dTSEC address offset
15351 + 0x32C again*/
15352 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
15353 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
15354 +
15355 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
15356 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
15357 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
15358 + the transmit portion of the dTSEC controller is locked up and the user should
15359 + proceed to the recover sequence. */
15360 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
15361 + {
15362 + /* recover sequence */
15363 +
15364 + /* a.Write a 1 to RCTRL[GRS]*/
15365 +
15366 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
15367 +
15368 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
15369 + for (i = 0 ; i < 100 ; i++ )
15370 + {
15371 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15372 + break;
15373 + XX_UDelay(1);
15374 + }
15375 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
15376 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
15377 + else
15378 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
15379 +
15380 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
15381 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
15382 +
15383 + /* d.Wait 4 Tx clocks (32 ns) */
15384 + XX_UDelay(1);
15385 +
15386 + /* e.Write a 0 to bit n of FM_RSTC. */
15387 + /* cleared by FMAN */
15388 + }
15389 + }
15390 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
15391 +
15392 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
15393 + }
15394 + if (event & DTSEC_IMASK_MAGEN)
15395 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
15396 + if (event & DTSEC_IMASK_GRSCEN)
15397 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
15398 + if (event & DTSEC_IMASK_TDPEEN)
15399 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
15400 + if (event & DTSEC_IMASK_RDPEEN)
15401 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
15402 +
15403 + /* - masked interrupts */
15404 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
15405 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
15406 +}
15407 +
15408 +static void DtsecMdioIsr(t_Handle h_Dtsec)
15409 +{
15410 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15411 + uint32_t event;
15412 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15413 +
15414 + event = GET_UINT32(p_DtsecMemMap->ievent);
15415 + /* handle only MDIO events */
15416 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
15417 + if (event)
15418 + {
15419 + event &= GET_UINT32(p_DtsecMemMap->imask);
15420 +
15421 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
15422 +
15423 + if (event & DTSEC_IMASK_MMRDEN)
15424 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
15425 + if (event & DTSEC_IMASK_MMWREN)
15426 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
15427 + }
15428 +}
15429 +
15430 +static void Dtsec1588Isr(t_Handle h_Dtsec)
15431 +{
15432 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15433 + uint32_t event;
15434 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
15435 +
15436 + if (p_Dtsec->ptpTsuEnabled)
15437 + {
15438 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
15439 +
15440 + if (event)
15441 + {
15442 + ASSERT_COND(event & TMR_PEVENT_TSRE);
15443 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
15444 + }
15445 + }
15446 +}
15447 +
15448 +/* ........................................................................... */
15449 +
15450 +static void FreeInitResources(t_Dtsec *p_Dtsec)
15451 +{
15452 + if (p_Dtsec->mdioIrq != NO_IRQ)
15453 + {
15454 + XX_DisableIntr(p_Dtsec->mdioIrq);
15455 + XX_FreeIntr(p_Dtsec->mdioIrq);
15456 + }
15457 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
15458 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
15459 +
15460 + /* release the driver's group hash table */
15461 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
15462 + p_Dtsec->p_MulticastAddrHash = NULL;
15463 +
15464 + /* release the driver's individual hash table */
15465 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
15466 + p_Dtsec->p_UnicastAddrHash = NULL;
15467 +}
15468 +
15469 +/* ........................................................................... */
15470 +
15471 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
15472 +{
15473 + struct dtsec_regs *p_MemMap;
15474 + int pollTimeout = 0;
15475 +
15476 + ASSERT_COND(p_Dtsec);
15477 +
15478 + p_MemMap = p_Dtsec->p_MemMap;
15479 + ASSERT_COND(p_MemMap);
15480 +
15481 + /* Assert the graceful transmit stop bit */
15482 + if (mode & e_COMM_MODE_RX)
15483 + {
15484 + fman_dtsec_stop_rx(p_MemMap);
15485 +
15486 +#ifdef FM_GRS_ERRATA_DTSEC_A002
15487 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15488 + XX_UDelay(100);
15489 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
15490 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
15491 + XX_UDelay(10);
15492 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
15493 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
15494 + }
15495 +
15496 + if (mode & e_COMM_MODE_TX)
15497 + {
15498 +#if defined(FM_GTS_ERRATA_DTSEC_A004)
15499 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15500 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
15501 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) */
15502 +
15503 + fman_dtsec_stop_tx(p_MemMap);
15504 +
15505 +#if defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
15506 + XX_UDelay(10);
15507 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 || FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 */
15508 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) */
15509 + }
15510 +
15511 + /* Poll GRSC/GTSC bits in IEVENT register until both are set */
15512 +#if defined(FM_GRS_ERRATA_DTSEC_A002) || defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012) || defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839)
15513 + XX_UDelay(10);
15514 +#else
15515 + while (fman_dtsec_get_event(p_MemMap, DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN) != (DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN))
15516 + {
15517 + if (pollTimeout == 100)
15518 + break;
15519 + XX_UDelay(1);
15520 + pollTimeout++;
15521 + }
15522 +#endif
15523 +
15524 + return E_OK;
15525 +}
15526 +
15527 +/* .............................................................................. */
15528 +
15529 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
15530 +{
15531 + struct dtsec_regs *p_MemMap;
15532 +
15533 + ASSERT_COND(p_Dtsec);
15534 + p_MemMap = p_Dtsec->p_MemMap;
15535 + ASSERT_COND(p_MemMap);
15536 +
15537 + /* clear the graceful receive stop bit */
15538 + if (mode & e_COMM_MODE_TX)
15539 + fman_dtsec_start_tx(p_MemMap);
15540 +
15541 + if (mode & e_COMM_MODE_RX)
15542 + fman_dtsec_start_rx(p_MemMap);
15543 +
15544 + return E_OK;
15545 +}
15546 +
15547 +
15548 +/*****************************************************************************/
15549 +/* dTSEC Configs modification functions */
15550 +/*****************************************************************************/
15551 +
15552 +/* .............................................................................. */
15553 +
15554 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
15555 +{
15556 +
15557 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15558 +
15559 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15560 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15561 +
15562 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
15563 +
15564 + return E_OK;
15565 +}
15566 +
15567 +/* .............................................................................. */
15568 +
15569 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
15570 +{
15571 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15572 +
15573 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15574 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15575 +
15576 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
15577 +
15578 + return E_OK;
15579 +}
15580 +
15581 +/* .............................................................................. */
15582 +
15583 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
15584 +{
15585 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15586 +
15587 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15588 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15589 +
15590 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
15591 +
15592 + return E_OK;
15593 +}
15594 +
15595 +/* .............................................................................. */
15596 +
15597 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
15598 +{
15599 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15600 +
15601 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15602 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15603 +
15604 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
15605 +
15606 + return E_OK;
15607 +}
15608 +
15609 +/* .............................................................................. */
15610 +
15611 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
15612 +{
15613 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15614 +
15615 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15616 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15617 +
15618 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
15619 +
15620 + return E_OK;
15621 +}
15622 +
15623 +/* .............................................................................. */
15624 +
15625 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
15626 +{
15627 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15628 +
15629 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15630 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15631 +
15632 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
15633 +
15634 + return E_OK;
15635 +}
15636 +
15637 +/* .............................................................................. */
15638 +
15639 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
15640 +{
15641 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15642 + uint32_t bitMask = 0;
15643 +
15644 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15645 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15646 +
15647 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
15648 + {
15649 + GET_EXCEPTION_FLAG(bitMask, exception);
15650 + if (bitMask)
15651 + {
15652 + if (enable)
15653 + p_Dtsec->exceptions |= bitMask;
15654 + else
15655 + p_Dtsec->exceptions &= ~bitMask;
15656 + }
15657 + else
15658 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
15659 + }
15660 + else
15661 + {
15662 + if (!p_Dtsec->ptpTsuEnabled)
15663 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
15664 +
15665 + if (enable)
15666 + p_Dtsec->enTsuErrExeption = TRUE;
15667 + else
15668 + p_Dtsec->enTsuErrExeption = FALSE;
15669 + }
15670 +
15671 + return E_OK;
15672 +}
15673 +
15674 +
15675 +/*****************************************************************************/
15676 +/* dTSEC Run Time API functions */
15677 +/*****************************************************************************/
15678 +
15679 +/* .............................................................................. */
15680 +
15681 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
15682 +{
15683 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15684 +
15685 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15686 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15687 +
15688 + fman_dtsec_enable(p_Dtsec->p_MemMap,
15689 + (bool)!!(mode & e_COMM_MODE_RX),
15690 + (bool)!!(mode & e_COMM_MODE_TX));
15691 +
15692 + GracefulRestart(p_Dtsec, mode);
15693 +
15694 + return E_OK;
15695 +}
15696 +
15697 +/* .............................................................................. */
15698 +
15699 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
15700 +{
15701 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15702 +
15703 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15704 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15705 +
15706 + GracefulStop(p_Dtsec, mode);
15707 +
15708 + fman_dtsec_disable(p_Dtsec->p_MemMap,
15709 + (bool)!!(mode & e_COMM_MODE_RX),
15710 + (bool)!!(mode & e_COMM_MODE_TX));
15711 +
15712 + return E_OK;
15713 +}
15714 +
15715 +/* .............................................................................. */
15716 +
15717 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
15718 + uint8_t priority,
15719 + uint16_t pauseTime,
15720 + uint16_t threshTime)
15721 +{
15722 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15723 +
15724 + UNUSED(priority);UNUSED(threshTime);
15725 +
15726 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15727 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15728 +
15729 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
15730 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
15731 + if (0 < pauseTime && pauseTime <= 320)
15732 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
15733 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
15734 + " value should be greater than 320."));
15735 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
15736 +
15737 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15738 +
15739 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
15740 +
15741 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15742 +
15743 + return E_OK;
15744 +}
15745 +
15746 +/* .............................................................................. */
15747 +/* backward compatibility. will be removed in the future. */
15748 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
15749 +{
15750 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
15751 +}
15752 +
15753 +/* .............................................................................. */
15754 +
15755 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
15756 +{
15757 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15758 + bool accept_pause = !en;
15759 +
15760 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
15761 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15762 +
15763 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15764 +
15765 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
15766 +
15767 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15768 +
15769 + return E_OK;
15770 +}
15771 +
15772 +/* .............................................................................. */
15773 +
15774 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
15775 +{
15776 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15777 +
15778 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15779 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15780 +
15781 + p_Dtsec->ptpTsuEnabled = TRUE;
15782 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
15783 +
15784 + return E_OK;
15785 +}
15786 +
15787 +/* .............................................................................. */
15788 +
15789 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
15790 +{
15791 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15792 +
15793 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15794 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15795 +
15796 + p_Dtsec->ptpTsuEnabled = FALSE;
15797 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
15798 +
15799 + return E_OK;
15800 +}
15801 +
15802 +/* .............................................................................. */
15803 +
15804 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
15805 +{
15806 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15807 + struct dtsec_regs *p_DtsecMemMap;
15808 +
15809 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15810 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15811 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
15812 +
15813 + p_DtsecMemMap = p_Dtsec->p_MemMap;
15814 +
15815 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
15816 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
15817 +
15818 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
15819 +
15820 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
15821 + {
15822 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
15823 + + p_Dtsec->internalStatistics.tr64;
15824 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
15825 + + p_Dtsec->internalStatistics.tr127;
15826 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
15827 + + p_Dtsec->internalStatistics.tr255;
15828 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
15829 + + p_Dtsec->internalStatistics.tr511;
15830 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
15831 + + p_Dtsec->internalStatistics.tr1k;
15832 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
15833 + + p_Dtsec->internalStatistics.trmax;
15834 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
15835 + + p_Dtsec->internalStatistics.trmgv;
15836 +
15837 + /* MIB II */
15838 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
15839 + + p_Dtsec->internalStatistics.rbyt;
15840 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
15841 + + p_Dtsec->internalStatistics.rpkt;
15842 + p_Statistics->ifInUcastPkts = 0;
15843 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
15844 + + p_Dtsec->internalStatistics.rmca;
15845 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
15846 + + p_Dtsec->internalStatistics.rbca;
15847 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
15848 + + p_Dtsec->internalStatistics.tbyt;
15849 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
15850 + + p_Dtsec->internalStatistics.tpkt;
15851 + p_Statistics->ifOutUcastPkts = 0;
15852 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
15853 + + p_Dtsec->internalStatistics.tmca;
15854 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
15855 + + p_Dtsec->internalStatistics.tbca;
15856 + }
15857 +
15858 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
15859 + + p_Dtsec->internalStatistics.rfrg;
15860 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
15861 + + p_Dtsec->internalStatistics.rjbr;
15862 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
15863 + + p_Dtsec->internalStatistics.rdrp;
15864 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
15865 + + p_Dtsec->internalStatistics.raln;
15866 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
15867 + + p_Dtsec->internalStatistics.rund;
15868 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
15869 + + p_Dtsec->internalStatistics.rovr;
15870 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
15871 + + p_Dtsec->internalStatistics.rxpf;
15872 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
15873 + + p_Dtsec->internalStatistics.txpf;
15874 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
15875 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
15876 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
15877 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
15878 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
15879 +
15880 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
15881 + + p_Dtsec->internalStatistics.tdrp;
15882 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
15883 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
15884 + + p_Dtsec->internalStatistics.tfcs;
15885 +
15886 + return E_OK;
15887 +}
15888 +
15889 +/* .............................................................................. */
15890 +
15891 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
15892 +{
15893 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15894 +
15895 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15896 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15897 +
15898 + /* Initialize MAC Station Address registers (1 & 2) */
15899 + /* Station address have to be swapped (big endian to little endian */
15900 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
15901 +
15902 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15903 +
15904 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
15905 +
15906 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
15907 +
15908 + return E_OK;
15909 +}
15910 +
15911 +/* .............................................................................. */
15912 +
15913 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
15914 +{
15915 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
15916 +
15917 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15918 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15919 +
15920 + /* clear HW counters */
15921 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
15922 +
15923 + /* clear SW counters holding carries */
15924 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
15925 +
15926 + return E_OK;
15927 +}
15928 +
15929 +/* .............................................................................. */
15930 +
15931 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15932 +{
15933 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15934 + uint64_t ethAddr;
15935 + uint8_t paddrNum;
15936 +
15937 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15938 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15939 +
15940 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15941 +
15942 + if (ethAddr & GROUP_ADDRESS)
15943 + /* Multicast address has no effect in PADDR */
15944 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
15945 +
15946 + /* Make sure no PADDR contains this address */
15947 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15948 + if (p_Dtsec->indAddrRegUsed[paddrNum])
15949 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
15950 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
15951 +
15952 + /* Find first unused PADDR */
15953 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15954 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
15955 + {
15956 + /* mark this PADDR as used */
15957 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
15958 + /* store address */
15959 + p_Dtsec->paddr[paddrNum] = ethAddr;
15960 +
15961 + /* put in hardware */
15962 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
15963 + p_Dtsec->numOfIndAddrInRegs++;
15964 +
15965 + return E_OK;
15966 + }
15967 +
15968 + /* No free PADDR */
15969 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
15970 +}
15971 +
15972 +/* .............................................................................. */
15973 +
15974 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
15975 +{
15976 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
15977 + uint64_t ethAddr;
15978 + uint8_t paddrNum;
15979 +
15980 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
15981 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
15982 +
15983 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
15984 +
15985 + /* Find used PADDR containing this address */
15986 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
15987 + {
15988 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
15989 + (p_Dtsec->paddr[paddrNum] == ethAddr))
15990 + {
15991 + /* mark this PADDR as not used */
15992 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
15993 + /* clear in hardware */
15994 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
15995 + p_Dtsec->numOfIndAddrInRegs--;
15996 +
15997 + return E_OK;
15998 + }
15999 + }
16000 +
16001 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
16002 +}
16003 +
16004 +/* .............................................................................. */
16005 +
16006 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
16007 +{
16008 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16009 + t_EthHashEntry *p_HashEntry;
16010 + uint64_t ethAddr;
16011 + int32_t bucket;
16012 + uint32_t crc;
16013 + bool mcast, ghtx;
16014 +
16015 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16016 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16017 +
16018 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
16019 +
16020 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
16021 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
16022 +
16023 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
16024 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
16025 +
16026 + crc = GetMacAddrHashCode(ethAddr);
16027 +
16028 + /* considering the 9 highest order bits in crc H[8:0]:
16029 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
16030 + * and H[5:1] (next 5 bits) identify the hash bit
16031 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
16032 + * and H[4:0] (next 5 bits) identify the hash bit.
16033 + *
16034 + * In bucket index output the low 5 bits identify the hash register bit,
16035 + * while the higher 4 bits identify the hash register
16036 + */
16037 +
16038 + if (ghtx)
16039 + bucket = (int32_t)((crc >> 23) & 0x1ff);
16040 + else {
16041 + bucket = (int32_t)((crc >> 24) & 0xff);
16042 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
16043 + if (mcast)
16044 + bucket += 0x100;
16045 + }
16046 +
16047 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
16048 +
16049 + /* Create element to be added to the driver hash table */
16050 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
16051 + p_HashEntry->addr = ethAddr;
16052 + INIT_LIST(&p_HashEntry->node);
16053 +
16054 + if (ethAddr & MAC_GROUP_ADDRESS)
16055 + /* Group Address */
16056 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
16057 + else
16058 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
16059 +
16060 + return E_OK;
16061 +}
16062 +
16063 +/* .............................................................................. */
16064 +
16065 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
16066 +{
16067 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16068 + t_List *p_Pos;
16069 + t_EthHashEntry *p_HashEntry = NULL;
16070 + uint64_t ethAddr;
16071 + int32_t bucket;
16072 + uint32_t crc;
16073 + bool mcast, ghtx;
16074 +
16075 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16076 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16077 +
16078 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
16079 +
16080 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
16081 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
16082 +
16083 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
16084 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
16085 +
16086 + crc = GetMacAddrHashCode(ethAddr);
16087 +
16088 + if (ghtx)
16089 + bucket = (int32_t)((crc >> 23) & 0x1ff);
16090 + else {
16091 + bucket = (int32_t)((crc >> 24) & 0xff);
16092 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
16093 + if (mcast)
16094 + bucket += 0x100;
16095 + }
16096 +
16097 + if (ethAddr & MAC_GROUP_ADDRESS)
16098 + {
16099 + /* Group Address */
16100 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
16101 + {
16102 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
16103 + if (p_HashEntry->addr == ethAddr)
16104 + {
16105 + LIST_DelAndInit(&p_HashEntry->node);
16106 + XX_Free(p_HashEntry);
16107 + break;
16108 + }
16109 + }
16110 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
16111 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
16112 + }
16113 + else
16114 + {
16115 + /* Individual Address */
16116 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
16117 + {
16118 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
16119 + if (p_HashEntry->addr == ethAddr)
16120 + {
16121 + LIST_DelAndInit(&p_HashEntry->node);
16122 + XX_Free(p_HashEntry);
16123 + break;
16124 + }
16125 + }
16126 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
16127 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
16128 + }
16129 +
16130 + /* address does not exist */
16131 + ASSERT_COND(p_HashEntry != NULL);
16132 +
16133 + return E_OK;
16134 +}
16135 +
16136 +/* .............................................................................. */
16137 +
16138 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
16139 +{
16140 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16141 +
16142 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16143 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16144 +
16145 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
16146 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
16147 +
16148 + return E_OK;
16149 +}
16150 +
16151 +/* .............................................................................. */
16152 +
16153 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
16154 +{
16155 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16156 + t_Error err;
16157 +
16158 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16159 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16160 +
16161 + p_Dtsec->statisticsLevel = statisticsLevel;
16162 +
16163 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
16164 + (enum dtsec_stat_level)statisticsLevel);
16165 + if (err != E_OK)
16166 + return err;
16167 +
16168 + switch (statisticsLevel)
16169 + {
16170 + case (e_FM_MAC_NONE_STATISTICS):
16171 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
16172 + break;
16173 + case (e_FM_MAC_PARTIAL_STATISTICS):
16174 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16175 + break;
16176 + case (e_FM_MAC_FULL_STATISTICS):
16177 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
16178 + break;
16179 + default:
16180 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
16181 + }
16182 +
16183 + return E_OK;
16184 +}
16185 +
16186 +/* .............................................................................. */
16187 +
16188 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
16189 +{
16190 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16191 +
16192 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
16193 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16194 +
16195 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
16196 +
16197 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
16198 +
16199 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
16200 +
16201 + return E_OK;
16202 +}
16203 +
16204 +/* .............................................................................. */
16205 +
16206 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
16207 +{
16208 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16209 + int err;
16210 + enum enet_interface enet_interface;
16211 + enum enet_speed enet_speed;
16212 +
16213 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16214 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16215 +
16216 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
16217 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16218 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16219 + p_Dtsec->halfDuplex = !fullDuplex;
16220 +
16221 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
16222 +
16223 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
16224 +
16225 + if (err == -EINVAL)
16226 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
16227 +
16228 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
16229 +
16230 + return (t_Error)err;
16231 +}
16232 +
16233 +/* .............................................................................. */
16234 +
16235 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
16236 +{
16237 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16238 + uint16_t tmpReg16;
16239 +
16240 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16241 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16242 +
16243 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
16244 +
16245 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
16246 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16247 +
16248 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
16249 +
16250 + return E_OK;
16251 +}
16252 +
16253 +/* .............................................................................. */
16254 +
16255 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
16256 +{
16257 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16258 +
16259 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16260 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16261 +
16262 + *macId = p_Dtsec->macId;
16263 +
16264 + return E_OK;
16265 +}
16266 +
16267 +/* .............................................................................. */
16268 +
16269 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
16270 +{
16271 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16272 +
16273 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16274 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16275 +
16276 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
16277 +
16278 + return E_OK;
16279 +}
16280 +
16281 +/* .............................................................................. */
16282 +
16283 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
16284 +{
16285 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16286 + uint32_t bitMask = 0;
16287 +
16288 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16289 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16290 +
16291 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
16292 + {
16293 + GET_EXCEPTION_FLAG(bitMask, exception);
16294 + if (bitMask)
16295 + {
16296 + if (enable)
16297 + p_Dtsec->exceptions |= bitMask;
16298 + else
16299 + p_Dtsec->exceptions &= ~bitMask;
16300 + }
16301 + else
16302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
16303 +
16304 + if (enable)
16305 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
16306 + else
16307 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
16308 + }
16309 + else
16310 + {
16311 + if (!p_Dtsec->ptpTsuEnabled)
16312 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
16313 +
16314 + if (enable)
16315 + {
16316 + p_Dtsec->enTsuErrExeption = TRUE;
16317 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
16318 + }
16319 + else
16320 + {
16321 + p_Dtsec->enTsuErrExeption = FALSE;
16322 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
16323 + }
16324 + }
16325 +
16326 + return E_OK;
16327 +}
16328 +
16329 +
16330 +/*****************************************************************************/
16331 +/* dTSEC Init & Free API */
16332 +/*****************************************************************************/
16333 +
16334 +/* .............................................................................. */
16335 +
16336 +static t_Error DtsecInit(t_Handle h_Dtsec)
16337 +{
16338 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16339 + struct dtsec_cfg *p_DtsecDriverParam;
16340 + t_Error err;
16341 + uint16_t maxFrmLn;
16342 + enum enet_interface enet_interface;
16343 + enum enet_speed enet_speed;
16344 + t_EnetAddr ethAddr;
16345 +
16346 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16347 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
16348 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
16349 +
16350 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
16351 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
16352 +
16353 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
16354 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
16355 +
16356 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
16357 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
16358 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
16359 +
16360 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
16361 + p_DtsecDriverParam,
16362 + enet_interface,
16363 + enet_speed,
16364 + (uint8_t*)ethAddr,
16365 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
16366 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
16367 + p_Dtsec->exceptions);
16368 + if (err)
16369 + {
16370 + FreeInitResources(p_Dtsec);
16371 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
16372 + }
16373 +
16374 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
16375 + {
16376 + uint16_t tmpReg16;
16377 +
16378 + /* Configure the TBI PHY Control Register */
16379 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
16380 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16381 +
16382 + tmpReg16 = PHY_TBICON_CLK_SEL;
16383 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
16384 +
16385 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16386 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16387 +
16388 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
16389 + tmpReg16 = PHY_TBIANA_1000X;
16390 + else
16391 + tmpReg16 = PHY_TBIANA_SGMII;
16392 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
16393 +
16394 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
16395 +
16396 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
16397 + }
16398 +
16399 + /* Max Frame Length */
16400 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16401 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
16402 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
16403 + if (err)
16404 + RETURN_ERROR(MINOR,err, NO_MSG);
16405 +
16406 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
16407 + if (!p_Dtsec->p_MulticastAddrHash) {
16408 + FreeInitResources(p_Dtsec);
16409 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
16410 + }
16411 +
16412 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
16413 + if (!p_Dtsec->p_UnicastAddrHash)
16414 + {
16415 + FreeInitResources(p_Dtsec);
16416 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
16417 + }
16418 +
16419 + /* register err intr handler for dtsec to FPM (err)*/
16420 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16421 + e_FM_MOD_1G_MAC,
16422 + p_Dtsec->macId,
16423 + e_FM_INTR_TYPE_ERR,
16424 + DtsecIsr,
16425 + p_Dtsec);
16426 + /* register 1588 intr handler for TMR to FPM (normal)*/
16427 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
16428 + e_FM_MOD_1G_MAC,
16429 + p_Dtsec->macId,
16430 + e_FM_INTR_TYPE_NORMAL,
16431 + Dtsec1588Isr,
16432 + p_Dtsec);
16433 + /* register normal intr handler for dtsec to main interrupt controller. */
16434 + if (p_Dtsec->mdioIrq != NO_IRQ)
16435 + {
16436 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
16437 + XX_EnableIntr(p_Dtsec->mdioIrq);
16438 + }
16439 +
16440 + XX_Free(p_DtsecDriverParam);
16441 + p_Dtsec->p_DtsecDriverParam = NULL;
16442 +
16443 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
16444 + if (err)
16445 + {
16446 + FreeInitResources(p_Dtsec);
16447 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
16448 + }
16449 +
16450 + return E_OK;
16451 +}
16452 +
16453 +/* ........................................................................... */
16454 +
16455 +static t_Error DtsecFree(t_Handle h_Dtsec)
16456 +{
16457 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16458 +
16459 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16460 +
16461 + if (p_Dtsec->p_DtsecDriverParam)
16462 + {
16463 + /* Called after config */
16464 + XX_Free(p_Dtsec->p_DtsecDriverParam);
16465 + p_Dtsec->p_DtsecDriverParam = NULL;
16466 + }
16467 + else
16468 + /* Called after init */
16469 + FreeInitResources(p_Dtsec);
16470 +
16471 + XX_Free(p_Dtsec);
16472 +
16473 + return E_OK;
16474 +}
16475 +
16476 +/* .............................................................................. */
16477 +
16478 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
16479 +{
16480 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
16481 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
16482 +
16483 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
16484 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
16485 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
16486 +
16487 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
16488 +
16489 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
16490 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
16491 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
16492 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
16493 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
16494 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
16495 +
16496 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
16497 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
16498 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
16499 +
16500 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
16501 +
16502 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
16503 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
16504 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
16505 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
16506 +
16507 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
16508 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
16509 +
16510 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
16511 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
16512 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
16513 +
16514 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
16515 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
16516 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
16517 +
16518 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
16519 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
16520 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
16521 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
16522 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
16523 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
16524 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
16525 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
16526 +
16527 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
16528 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
16529 +
16530 +}
16531 +
16532 +
16533 +/*****************************************************************************/
16534 +/* dTSEC Config Main Entry */
16535 +/*****************************************************************************/
16536 +
16537 +/* .............................................................................. */
16538 +
16539 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
16540 +{
16541 + t_Dtsec *p_Dtsec;
16542 + struct dtsec_cfg *p_DtsecDriverParam;
16543 + uintptr_t baseAddr;
16544 +
16545 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
16546 +
16547 + baseAddr = p_FmMacParam->baseAddr;
16548 +
16549 + /* allocate memory for the UCC GETH data structure. */
16550 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
16551 + if (!p_Dtsec)
16552 + {
16553 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
16554 + return NULL;
16555 + }
16556 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
16557 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
16558 +
16559 + /* allocate memory for the dTSEC driver parameters data structure. */
16560 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
16561 + if (!p_DtsecDriverParam)
16562 + {
16563 + XX_Free(p_Dtsec);
16564 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
16565 + return NULL;
16566 + }
16567 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
16568 +
16569 + /* Plant parameter structure pointer */
16570 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
16571 +
16572 + fman_dtsec_defconfig(p_DtsecDriverParam);
16573 +
16574 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
16575 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
16576 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
16577 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
16578 + p_Dtsec->macId = p_FmMacParam->macId;
16579 + p_Dtsec->exceptions = DEFAULT_exceptions;
16580 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
16581 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
16582 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
16583 + p_Dtsec->h_App = p_FmMacParam->h_App;
16584 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
16585 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
16586 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
16587 +
16588 + return p_Dtsec;
16589 +}
16590 --- /dev/null
16591 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
16592 @@ -0,0 +1,228 @@
16593 +/*
16594 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16595 + *
16596 + * Redistribution and use in source and binary forms, with or without
16597 + * modification, are permitted provided that the following conditions are met:
16598 + * * Redistributions of source code must retain the above copyright
16599 + * notice, this list of conditions and the following disclaimer.
16600 + * * Redistributions in binary form must reproduce the above copyright
16601 + * notice, this list of conditions and the following disclaimer in the
16602 + * documentation and/or other materials provided with the distribution.
16603 + * * Neither the name of Freescale Semiconductor nor the
16604 + * names of its contributors may be used to endorse or promote products
16605 + * derived from this software without specific prior written permission.
16606 + *
16607 + *
16608 + * ALTERNATIVELY, this software may be distributed under the terms of the
16609 + * GNU General Public License ("GPL") as published by the Free Software
16610 + * Foundation, either version 2 of that License or (at your option) any
16611 + * later version.
16612 + *
16613 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16614 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16615 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16616 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16617 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16618 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16619 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16620 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16621 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16622 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16623 + */
16624 +
16625 +/******************************************************************************
16626 + @File dtsec.h
16627 +
16628 + @Description FM dTSEC ...
16629 +*//***************************************************************************/
16630 +#ifndef __DTSEC_H
16631 +#define __DTSEC_H
16632 +
16633 +#include "std_ext.h"
16634 +#include "error_ext.h"
16635 +#include "list_ext.h"
16636 +#include "enet_ext.h"
16637 +
16638 +#include "dtsec_mii_acc.h"
16639 +#include "fm_mac.h"
16640 +
16641 +
16642 +#define DEFAULT_exceptions \
16643 + ((uint32_t)(DTSEC_IMASK_BREN | \
16644 + DTSEC_IMASK_RXCEN | \
16645 + DTSEC_IMASK_BTEN | \
16646 + DTSEC_IMASK_TXCEN | \
16647 + DTSEC_IMASK_TXEEN | \
16648 + DTSEC_IMASK_ABRTEN | \
16649 + DTSEC_IMASK_LCEN | \
16650 + DTSEC_IMASK_CRLEN | \
16651 + DTSEC_IMASK_XFUNEN | \
16652 + DTSEC_IMASK_IFERREN | \
16653 + DTSEC_IMASK_MAGEN | \
16654 + DTSEC_IMASK_TDPEEN | \
16655 + DTSEC_IMASK_RDPEEN))
16656 +
16657 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
16658 + case e_FM_MAC_EX_1G_BAB_RX: \
16659 + bitMask = DTSEC_IMASK_BREN; break; \
16660 + case e_FM_MAC_EX_1G_RX_CTL: \
16661 + bitMask = DTSEC_IMASK_RXCEN; break; \
16662 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
16663 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
16664 + case e_FM_MAC_EX_1G_BAB_TX: \
16665 + bitMask = DTSEC_IMASK_BTEN ; break; \
16666 + case e_FM_MAC_EX_1G_TX_CTL: \
16667 + bitMask = DTSEC_IMASK_TXCEN ; break; \
16668 + case e_FM_MAC_EX_1G_TX_ERR: \
16669 + bitMask = DTSEC_IMASK_TXEEN ; break; \
16670 + case e_FM_MAC_EX_1G_LATE_COL: \
16671 + bitMask = DTSEC_IMASK_LCEN ; break; \
16672 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
16673 + bitMask = DTSEC_IMASK_CRLEN ; break; \
16674 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
16675 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
16676 + case e_FM_MAC_EX_1G_MAG_PCKT: \
16677 + bitMask = DTSEC_IMASK_MAGEN ; break; \
16678 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
16679 + bitMask = DTSEC_IMASK_MMRDEN; break; \
16680 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
16681 + bitMask = DTSEC_IMASK_MMWREN ; break; \
16682 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
16683 + bitMask = DTSEC_IMASK_GRSCEN; break; \
16684 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
16685 + bitMask = DTSEC_IMASK_TDPEEN; break; \
16686 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
16687 + bitMask = DTSEC_IMASK_MSROEN ; break; \
16688 + default: bitMask = 0;break;}
16689 +
16690 +
16691 +#define MAX_PACKET_ALIGNMENT 31
16692 +#define MAX_INTER_PACKET_GAP 0x7f
16693 +#define MAX_INTER_PALTERNATE_BEB 0x0f
16694 +#define MAX_RETRANSMISSION 0x0f
16695 +#define MAX_COLLISION_WINDOW 0x03ff
16696 +
16697 +
16698 +/********************* From mac ext ******************************************/
16699 +typedef uint32_t t_ErrorDisable;
16700 +
16701 +#define ERROR_DISABLE_TRANSMIT 0x00400000
16702 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
16703 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
16704 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
16705 +#define ERROR_DISABLE_TxABORT 0x00008000
16706 +#define ERROR_DISABLE_INTERFACE 0x00004000
16707 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
16708 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
16709 +
16710 +/*****************************************************************************/
16711 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
16712 +
16713 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
16714 +
16715 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
16716 +
16717 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
16718 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
16719 +
16720 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
16721 +
16722 +#define MAX_PHYS 32 /* maximum number of phys */
16723 +
16724 +#define VAL32BIT 0x100000000LL
16725 +#define VAL22BIT 0x00400000
16726 +#define VAL16BIT 0x00010000
16727 +#define VAL12BIT 0x00001000
16728 +
16729 +/* CAR1/2 bits */
16730 +#define CAR1_TR64 0x80000000
16731 +#define CAR1_TR127 0x40000000
16732 +#define CAR1_TR255 0x20000000
16733 +#define CAR1_TR511 0x10000000
16734 +#define CAR1_TRK1 0x08000000
16735 +#define CAR1_TRMAX 0x04000000
16736 +#define CAR1_TRMGV 0x02000000
16737 +
16738 +#define CAR1_RBYT 0x00010000
16739 +#define CAR1_RPKT 0x00008000
16740 +#define CAR1_RMCA 0x00002000
16741 +#define CAR1_RBCA 0x00001000
16742 +#define CAR1_RXPF 0x00000400
16743 +#define CAR1_RALN 0x00000100
16744 +#define CAR1_RFLR 0x00000080
16745 +#define CAR1_RCDE 0x00000040
16746 +#define CAR1_RCSE 0x00000020
16747 +#define CAR1_RUND 0x00000010
16748 +#define CAR1_ROVR 0x00000008
16749 +#define CAR1_RFRG 0x00000004
16750 +#define CAR1_RJBR 0x00000002
16751 +#define CAR1_RDRP 0x00000001
16752 +
16753 +#define CAR2_TFCS 0x00040000
16754 +#define CAR2_TBYT 0x00002000
16755 +#define CAR2_TPKT 0x00001000
16756 +#define CAR2_TMCA 0x00000800
16757 +#define CAR2_TBCA 0x00000400
16758 +#define CAR2_TXPF 0x00000200
16759 +#define CAR2_TDRP 0x00000001
16760 +
16761 +typedef struct t_InternalStatistics
16762 +{
16763 + uint64_t tr64;
16764 + uint64_t tr127;
16765 + uint64_t tr255;
16766 + uint64_t tr511;
16767 + uint64_t tr1k;
16768 + uint64_t trmax;
16769 + uint64_t trmgv;
16770 + uint64_t rfrg;
16771 + uint64_t rjbr;
16772 + uint64_t rdrp;
16773 + uint64_t raln;
16774 + uint64_t rund;
16775 + uint64_t rovr;
16776 + uint64_t rxpf;
16777 + uint64_t txpf;
16778 + uint64_t rbyt;
16779 + uint64_t rpkt;
16780 + uint64_t rmca;
16781 + uint64_t rbca;
16782 + uint64_t rflr;
16783 + uint64_t rcde;
16784 + uint64_t rcse;
16785 + uint64_t tbyt;
16786 + uint64_t tpkt;
16787 + uint64_t tmca;
16788 + uint64_t tbca;
16789 + uint64_t tdrp;
16790 + uint64_t tfcs;
16791 +} t_InternalStatistics;
16792 +
16793 +typedef struct {
16794 + t_FmMacControllerDriver fmMacControllerDriver;
16795 + t_Handle h_App; /**< Handle to the upper layer application */
16796 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
16797 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
16798 + uint64_t addr; /**< MAC address of device; */
16799 + e_EnetMode enetMode; /**< Ethernet physical interface */
16800 + t_FmMacExceptionCallback *f_Exception;
16801 + int mdioIrq;
16802 + t_FmMacExceptionCallback *f_Event;
16803 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
16804 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
16805 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
16806 + bool halfDuplex;
16807 + t_InternalStatistics internalStatistics;
16808 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
16809 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
16810 + uint8_t macId;
16811 + uint8_t tbi_phy_addr;
16812 + uint32_t exceptions;
16813 + bool ptpTsuEnabled;
16814 + bool enTsuErrExeption;
16815 + e_FmMacStatisticsLevel statisticsLevel;
16816 + struct dtsec_cfg *p_DtsecDriverParam;
16817 +} t_Dtsec;
16818 +
16819 +
16820 +#endif /* __DTSEC_H */
16821 --- /dev/null
16822 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
16823 @@ -0,0 +1,97 @@
16824 +/*
16825 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16826 + *
16827 + * Redistribution and use in source and binary forms, with or without
16828 + * modification, are permitted provided that the following conditions are met:
16829 + * * Redistributions of source code must retain the above copyright
16830 + * notice, this list of conditions and the following disclaimer.
16831 + * * Redistributions in binary form must reproduce the above copyright
16832 + * notice, this list of conditions and the following disclaimer in the
16833 + * documentation and/or other materials provided with the distribution.
16834 + * * Neither the name of Freescale Semiconductor nor the
16835 + * names of its contributors may be used to endorse or promote products
16836 + * derived from this software without specific prior written permission.
16837 + *
16838 + *
16839 + * ALTERNATIVELY, this software may be distributed under the terms of the
16840 + * GNU General Public License ("GPL") as published by the Free Software
16841 + * Foundation, either version 2 of that License or (at your option) any
16842 + * later version.
16843 + *
16844 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16845 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16846 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16847 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16848 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16849 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16850 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16851 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16852 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16853 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16854 + */
16855 +
16856 +
16857 +/******************************************************************************
16858 + @File dtsec_mii_acc.c
16859 +
16860 + @Description FM dtsec MII register access MAC ...
16861 +*//***************************************************************************/
16862 +
16863 +#include "error_ext.h"
16864 +#include "std_ext.h"
16865 +#include "fm_mac.h"
16866 +#include "dtsec.h"
16867 +#include "fsl_fman_dtsec_mii_acc.h"
16868 +
16869 +
16870 +/*****************************************************************************/
16871 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
16872 + uint8_t phyAddr,
16873 + uint8_t reg,
16874 + uint16_t data)
16875 +{
16876 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16877 + struct dtsec_mii_reg *miiregs;
16878 + uint16_t dtsec_freq;
16879 + t_Error err;
16880 +
16881 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16882 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16883 +
16884 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16885 + miiregs = p_Dtsec->p_MiiMemMap;
16886 +
16887 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
16888 +
16889 + return err;
16890 +}
16891 +
16892 +/*****************************************************************************/
16893 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
16894 + uint8_t phyAddr,
16895 + uint8_t reg,
16896 + uint16_t *p_Data)
16897 +{
16898 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16899 + struct dtsec_mii_reg *miiregs;
16900 + uint16_t dtsec_freq;
16901 + t_Error err;
16902 +
16903 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
16904 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
16905 +
16906 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
16907 + miiregs = p_Dtsec->p_MiiMemMap;
16908 +
16909 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
16910 +
16911 + if (*p_Data == 0xffff)
16912 + RETURN_ERROR(MINOR, E_NO_DEVICE,
16913 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
16914 + phyAddr, reg));
16915 + if (err)
16916 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
16917 +
16918 + return E_OK;
16919 +}
16920 +
16921 --- /dev/null
16922 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
16923 @@ -0,0 +1,42 @@
16924 +/*
16925 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16926 + *
16927 + * Redistribution and use in source and binary forms, with or without
16928 + * modification, are permitted provided that the following conditions are met:
16929 + * * Redistributions of source code must retain the above copyright
16930 + * notice, this list of conditions and the following disclaimer.
16931 + * * Redistributions in binary form must reproduce the above copyright
16932 + * notice, this list of conditions and the following disclaimer in the
16933 + * documentation and/or other materials provided with the distribution.
16934 + * * Neither the name of Freescale Semiconductor nor the
16935 + * names of its contributors may be used to endorse or promote products
16936 + * derived from this software without specific prior written permission.
16937 + *
16938 + *
16939 + * ALTERNATIVELY, this software may be distributed under the terms of the
16940 + * GNU General Public License ("GPL") as published by the Free Software
16941 + * Foundation, either version 2 of that License or (at your option) any
16942 + * later version.
16943 + *
16944 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16945 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16946 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16947 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16948 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16949 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16950 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16951 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16952 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16953 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16954 + */
16955 +
16956 +#ifndef __DTSEC_MII_ACC_H
16957 +#define __DTSEC_MII_ACC_H
16958 +
16959 +#include "std_ext.h"
16960 +
16961 +
16962 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
16963 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
16964 +
16965 +#endif /* __DTSEC_MII_ACC_H */
16966 --- /dev/null
16967 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
16968 @@ -0,0 +1,674 @@
16969 +/*
16970 + * Copyright 2008-2012 Freescale Semiconductor Inc.
16971 + *
16972 + * Redistribution and use in source and binary forms, with or without
16973 + * modification, are permitted provided that the following conditions are met:
16974 + * * Redistributions of source code must retain the above copyright
16975 + * notice, this list of conditions and the following disclaimer.
16976 + * * Redistributions in binary form must reproduce the above copyright
16977 + * notice, this list of conditions and the following disclaimer in the
16978 + * documentation and/or other materials provided with the distribution.
16979 + * * Neither the name of Freescale Semiconductor nor the
16980 + * names of its contributors may be used to endorse or promote products
16981 + * derived from this software without specific prior written permission.
16982 + *
16983 + *
16984 + * ALTERNATIVELY, this software may be distributed under the terms of the
16985 + * GNU General Public License ("GPL") as published by the Free Software
16986 + * Foundation, either version 2 of that License or (at your option) any
16987 + * later version.
16988 + *
16989 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16990 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16991 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16992 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16993 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16994 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16995 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16996 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16997 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16998 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16999 + */
17000 +
17001 +
17002 +/******************************************************************************
17003 + @File fm_mac.c
17004 +
17005 + @Description FM MAC ...
17006 +*//***************************************************************************/
17007 +#include "std_ext.h"
17008 +#include "string_ext.h"
17009 +#include "sprint_ext.h"
17010 +#include "error_ext.h"
17011 +#include "fm_ext.h"
17012 +
17013 +#include "fm_common.h"
17014 +#include "fm_mac.h"
17015 +
17016 +
17017 +/* ......................................................................... */
17018 +
17019 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
17020 +{
17021 + t_FmMacControllerDriver *p_FmMacControllerDriver;
17022 + uint16_t fmClkFreq;
17023 +
17024 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
17025 +
17026 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
17027 + if (fmClkFreq == 0)
17028 + {
17029 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
17030 + return NULL;
17031 + }
17032 +
17033 +#if (DPAA_VERSION == 10)
17034 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
17035 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
17036 + else
17037 +#if FM_MAX_NUM_OF_10G_MACS > 0
17038 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
17039 +#else
17040 + p_FmMacControllerDriver = NULL;
17041 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
17042 +#else
17043 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
17044 +#endif /* (DPAA_VERSION == 10) */
17045 +
17046 + if (!p_FmMacControllerDriver)
17047 + return NULL;
17048 +
17049 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
17050 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
17051 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
17052 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
17053 +
17054 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
17055 +
17056 + return (t_Handle)p_FmMacControllerDriver;
17057 +}
17058 +
17059 +/* ......................................................................... */
17060 +
17061 +t_Error FM_MAC_Init (t_Handle h_FmMac)
17062 +{
17063 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17064 +
17065 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17066 +
17067 + if (p_FmMacControllerDriver->resetOnInit &&
17068 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
17069 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
17070 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
17071 + e_FM_MAC_10G : e_FM_MAC_1G),
17072 + p_FmMacControllerDriver->macId) != E_OK))
17073 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
17074 +
17075 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
17076 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
17077 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17078 +}
17079 +
17080 +/* ......................................................................... */
17081 +
17082 +t_Error FM_MAC_Free (t_Handle h_FmMac)
17083 +{
17084 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17085 +
17086 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17087 +
17088 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
17089 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
17090 +
17091 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17092 +}
17093 +
17094 +/* ......................................................................... */
17095 +
17096 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
17097 +{
17098 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17099 +
17100 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17101 +
17102 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit)
17103 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
17104 +
17105 + p_FmMacControllerDriver->resetOnInit = enable;
17106 +
17107 + return E_OK;
17108 +}
17109 +
17110 +/* ......................................................................... */
17111 +
17112 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
17113 +{
17114 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17115 +
17116 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17117 +
17118 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
17119 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
17120 +
17121 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17122 +}
17123 +
17124 +/* ......................................................................... */
17125 +
17126 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
17127 +{
17128 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17129 +
17130 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17131 +
17132 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
17133 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
17134 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17135 +}
17136 +
17137 +/* ......................................................................... */
17138 +
17139 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
17140 +{
17141 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17142 +
17143 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17144 +
17145 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
17146 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
17147 +
17148 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17149 +}
17150 +
17151 +/* ......................................................................... */
17152 +
17153 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
17154 +{
17155 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17156 +
17157 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17158 +
17159 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
17160 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
17161 +
17162 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17163 +}
17164 +
17165 +/* ......................................................................... */
17166 +
17167 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
17168 +{
17169 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17170 +
17171 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17172 +
17173 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
17174 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
17175 +
17176 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17177 +}
17178 +
17179 +/* ......................................................................... */
17180 +
17181 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
17182 +{
17183 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17184 +
17185 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17186 +
17187 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr)
17188 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
17189 +
17190 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17191 +}
17192 +
17193 +/* ......................................................................... */
17194 +
17195 +t_Error FM_MAC_ConfigLengthCheck (t_Handle h_FmMac, bool newVal)
17196 +{
17197 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17198 +
17199 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17200 +
17201 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck)
17202 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
17203 +
17204 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17205 +}
17206 +
17207 +/* ......................................................................... */
17208 +
17209 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17210 +{
17211 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17212 +
17213 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17214 +
17215 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigException)
17216 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
17217 +
17218 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17219 +}
17220 +
17221 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17222 +/* ......................................................................... */
17223 +
17224 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
17225 +{
17226 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17227 +
17228 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17229 +
17230 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
17231 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
17232 +
17233 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17234 +}
17235 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17236 +
17237 +
17238 +/*****************************************************************************/
17239 +/* Run Time Control */
17240 +/*****************************************************************************/
17241 +
17242 +/* ......................................................................... */
17243 +
17244 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
17245 +{
17246 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17247 +
17248 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17249 +
17250 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
17251 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
17252 +
17253 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17254 +}
17255 +
17256 +/* ......................................................................... */
17257 +
17258 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
17259 +{
17260 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17261 +
17262 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17263 +
17264 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
17265 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
17266 +
17267 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17268 +}
17269 +
17270 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
17271 +{
17272 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17273 +
17274 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17275 +
17276 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
17277 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
17278 +
17279 + return E_OK;
17280 +}
17281 +
17282 +/* ......................................................................... */
17283 +
17284 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
17285 +{
17286 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17287 +
17288 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17289 +
17290 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
17291 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
17292 +
17293 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17294 +}
17295 +
17296 +/* ......................................................................... */
17297 +
17298 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
17299 +{
17300 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17301 +
17302 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17303 +
17304 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
17305 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
17306 +
17307 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17308 +}
17309 +
17310 +/* ......................................................................... */
17311 +
17312 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
17313 + uint16_t pauseTime)
17314 +{
17315 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17316 +
17317 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17318 +
17319 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
17320 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
17321 + pauseTime);
17322 +
17323 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17324 +}
17325 +
17326 +/* ......................................................................... */
17327 +
17328 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
17329 + uint8_t priority,
17330 + uint16_t pauseTime,
17331 + uint16_t threshTime)
17332 +{
17333 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17334 +
17335 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17336 +
17337 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
17338 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
17339 + priority,
17340 + pauseTime,
17341 + threshTime);
17342 +
17343 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
17344 +}
17345 +
17346 +/* ......................................................................... */
17347 +
17348 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
17349 +{
17350 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17351 +
17352 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17353 +
17354 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
17355 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
17356 +
17357 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17358 +}
17359 +
17360 +/* ......................................................................... */
17361 +
17362 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
17363 +{
17364 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17365 +
17366 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17367 +
17368 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
17369 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
17370 +
17371 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17372 +}
17373 +
17374 +/* ......................................................................... */
17375 +
17376 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
17377 +{
17378 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17379 +
17380 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17381 +
17382 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
17383 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
17384 +
17385 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17386 +}
17387 +
17388 +/* ......................................................................... */
17389 +
17390 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
17391 +{
17392 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17393 +
17394 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17395 +
17396 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
17397 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
17398 +
17399 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17400 +}
17401 +
17402 +/* ......................................................................... */
17403 +
17404 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
17405 +{
17406 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17407 +
17408 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17409 +
17410 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
17411 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
17412 +
17413 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17414 +}
17415 +
17416 +/* ......................................................................... */
17417 +
17418 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
17419 +{
17420 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17421 +
17422 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17423 +
17424 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
17425 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
17426 +
17427 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17428 +}
17429 +
17430 +/* ......................................................................... */
17431 +
17432 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
17433 +{
17434 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17435 +
17436 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17437 +
17438 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
17439 +
17440 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
17441 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
17442 +
17443 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17444 +}
17445 +
17446 +/* ......................................................................... */
17447 +
17448 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17449 +{
17450 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17451 +
17452 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17453 +
17454 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
17455 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
17456 +
17457 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17458 +}
17459 +
17460 +/* ......................................................................... */
17461 +
17462 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17463 +{
17464 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17465 +
17466 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17467 +
17468 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
17469 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
17470 +
17471 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17472 +}
17473 +
17474 +/* ......................................................................... */
17475 +
17476 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17477 +{
17478 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17479 +
17480 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17481 +
17482 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
17483 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
17484 +
17485 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17486 +}
17487 +
17488 +/* ......................................................................... */
17489 +
17490 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17491 +{
17492 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17493 +
17494 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17495 +
17496 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
17497 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
17498 +
17499 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17500 +}
17501 +
17502 +/* ......................................................................... */
17503 +
17504 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
17505 +{
17506 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17507 +
17508 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17509 +
17510 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
17511 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
17512 +
17513 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17514 +}
17515 +
17516 +/* ......................................................................... */
17517 +
17518 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
17519 +{
17520 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17521 +
17522 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17523 +
17524 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
17525 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
17526 +
17527 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17528 +
17529 +}
17530 +
17531 +/* ......................................................................... */
17532 +
17533 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
17534 +{
17535 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17536 +
17537 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17538 +
17539 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
17540 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
17541 +
17542 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17543 +}
17544 +
17545 +/* ......................................................................... */
17546 +
17547 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
17548 +{
17549 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17550 +
17551 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17552 +
17553 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
17554 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
17555 +
17556 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17557 +}
17558 +
17559 +/* ......................................................................... */
17560 +
17561 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
17562 +{
17563 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17564 +
17565 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17566 +
17567 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
17568 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
17569 +
17570 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17571 +}
17572 +
17573 +/* ......................................................................... */
17574 +
17575 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
17576 +{
17577 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17578 +
17579 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17580 +
17581 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
17582 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
17583 +
17584 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17585 +}
17586 +
17587 +/* ......................................................................... */
17588 +
17589 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
17590 +{
17591 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17592 +
17593 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17594 +
17595 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
17596 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
17597 +
17598 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17599 +}
17600 +
17601 +/* ......................................................................... */
17602 +
17603 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
17604 +{
17605 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17606 +
17607 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17608 +
17609 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
17610 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
17611 +
17612 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17613 +}
17614 +
17615 +/* ......................................................................... */
17616 +
17617 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
17618 +{
17619 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17620 +
17621 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
17622 +
17623 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
17624 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
17625 +
17626 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17627 + return 0;
17628 +}
17629 +
17630 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17631 +/*****************************************************************************/
17632 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
17633 +{
17634 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
17635 +
17636 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
17637 +
17638 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
17639 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
17640 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
17641 +}
17642 +#endif /* (defined(DEBUG_ERRORS) && ... */
17643 --- /dev/null
17644 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
17645 @@ -0,0 +1,226 @@
17646 +/*
17647 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17648 + *
17649 + * Redistribution and use in source and binary forms, with or without
17650 + * modification, are permitted provided that the following conditions are met:
17651 + * * Redistributions of source code must retain the above copyright
17652 + * notice, this list of conditions and the following disclaimer.
17653 + * * Redistributions in binary form must reproduce the above copyright
17654 + * notice, this list of conditions and the following disclaimer in the
17655 + * documentation and/or other materials provided with the distribution.
17656 + * * Neither the name of Freescale Semiconductor nor the
17657 + * names of its contributors may be used to endorse or promote products
17658 + * derived from this software without specific prior written permission.
17659 + *
17660 + *
17661 + * ALTERNATIVELY, this software may be distributed under the terms of the
17662 + * GNU General Public License ("GPL") as published by the Free Software
17663 + * Foundation, either version 2 of that License or (at your option) any
17664 + * later version.
17665 + *
17666 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17667 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17668 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17669 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17670 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17671 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17672 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17673 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17674 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17675 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17676 + */
17677 +
17678 +
17679 +/******************************************************************************
17680 + @File fm_mac.h
17681 +
17682 + @Description FM MAC ...
17683 +*//***************************************************************************/
17684 +#ifndef __FM_MAC_H
17685 +#define __FM_MAC_H
17686 +
17687 +#include "std_ext.h"
17688 +#include "error_ext.h"
17689 +#include "list_ext.h"
17690 +#include "fm_mac_ext.h"
17691 +#include "fm_common.h"
17692 +
17693 +
17694 +#define __ERR_MODULE__ MODULE_FM_MAC
17695 +
17696 +/**************************************************************************//**
17697 + @Description defaults
17698 +*//***************************************************************************/
17699 +
17700 +
17701 +#define DEFAULT_halfDuplex FALSE
17702 +#define DEFAULT_padAndCrcEnable TRUE
17703 +#define DEFAULT_resetOnInit FALSE
17704 +
17705 +
17706 +typedef struct {
17707 + uint64_t addr; /* Ethernet Address */
17708 + t_List node;
17709 +} t_EthHashEntry;
17710 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
17711 +
17712 +typedef struct {
17713 + uint16_t size;
17714 + t_List *p_Lsts;
17715 +} t_EthHash;
17716 +
17717 +typedef struct {
17718 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
17719 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
17720 +
17721 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
17722 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
17723 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
17724 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
17725 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
17726 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
17727 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
17728 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
17729 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
17730 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
17731 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
17732 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
17733 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
17734 +
17735 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
17736 +
17737 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
17738 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
17739 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
17740 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
17741 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
17742 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
17743 +
17744 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
17745 + uint16_t pauseTime);
17746 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
17747 + uint8_t priority,
17748 + uint16_t pauseTime,
17749 + uint16_t threshTime);
17750 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
17751 +
17752 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
17753 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
17754 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
17755 +
17756 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17757 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17758 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17759 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17760 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
17761 +
17762 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
17763 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
17764 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
17765 +
17766 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
17767 +
17768 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
17769 +
17770 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
17771 +
17772 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
17773 +
17774 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
17775 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
17776 +
17777 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
17778 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
17779 +#endif /* (defined(DEBUG_ERRORS) && ... */
17780 +
17781 + t_Handle h_Fm;
17782 + t_FmRevisionInfo fmRevInfo;
17783 + e_EnetMode enetMode;
17784 + uint8_t macId;
17785 + bool resetOnInit;
17786 + uint16_t clkFreq;
17787 +} t_FmMacControllerDriver;
17788 +
17789 +
17790 +#if (DPAA_VERSION == 10)
17791 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
17792 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
17793 +#else
17794 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
17795 +#endif /* (DPAA_VERSION == 10) */
17796 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
17797 +
17798 +
17799 +/* ........................................................................... */
17800 +
17801 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
17802 +{
17803 + t_EthHashEntry *p_HashEntry = NULL;
17804 + if (!LIST_IsEmpty(p_AddrLst))
17805 + {
17806 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
17807 + LIST_DelAndInit(&p_HashEntry->node);
17808 + }
17809 + return p_HashEntry;
17810 +}
17811 +
17812 +/* ........................................................................... */
17813 +
17814 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
17815 +{
17816 + t_EthHashEntry *p_HashEntry;
17817 + int i = 0;
17818 +
17819 + if (p_Hash)
17820 + {
17821 + if (p_Hash->p_Lsts)
17822 + {
17823 + for (i=0; i<p_Hash->size; i++)
17824 + {
17825 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17826 + while (p_HashEntry)
17827 + {
17828 + XX_Free(p_HashEntry);
17829 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
17830 + }
17831 + }
17832 +
17833 + XX_Free(p_Hash->p_Lsts);
17834 + }
17835 +
17836 + XX_Free(p_Hash);
17837 + }
17838 +}
17839 +
17840 +/* ........................................................................... */
17841 +
17842 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
17843 +{
17844 + uint32_t i;
17845 + t_EthHash *p_Hash;
17846 +
17847 + /* Allocate address hash table */
17848 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
17849 + if (!p_Hash)
17850 + {
17851 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17852 + return NULL;
17853 + }
17854 + p_Hash->size = size;
17855 +
17856 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
17857 + if (!p_Hash->p_Lsts)
17858 + {
17859 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
17860 + XX_Free(p_Hash);
17861 + return NULL;
17862 + }
17863 +
17864 + for (i=0 ; i<p_Hash->size; i++)
17865 + INIT_LIST(&p_Hash->p_Lsts[i]);
17866 +
17867 + return p_Hash;
17868 +}
17869 +
17870 +
17871 +#endif /* __FM_MAC_H */
17872 --- /dev/null
17873 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
17874 @@ -0,0 +1,119 @@
17875 +/*
17876 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17877 + *
17878 + * Redistribution and use in source and binary forms, with or without
17879 + * modification, are permitted provided that the following conditions are met:
17880 + * * Redistributions of source code must retain the above copyright
17881 + * notice, this list of conditions and the following disclaimer.
17882 + * * Redistributions in binary form must reproduce the above copyright
17883 + * notice, this list of conditions and the following disclaimer in the
17884 + * documentation and/or other materials provided with the distribution.
17885 + * * Neither the name of Freescale Semiconductor nor the
17886 + * names of its contributors may be used to endorse or promote products
17887 + * derived from this software without specific prior written permission.
17888 + *
17889 + *
17890 + * ALTERNATIVELY, this software may be distributed under the terms of the
17891 + * GNU General Public License ("GPL") as published by the Free Software
17892 + * Foundation, either version 2 of that License or (at your option) any
17893 + * later version.
17894 + *
17895 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
17896 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17897 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17898 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
17899 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17900 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
17901 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
17902 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17903 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
17904 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17905 + */
17906 +
17907 +
17908 +#include "fman_crc32.h"
17909 +#include "common/general.h"
17910 +
17911 +
17912 +/* precomputed CRC values for address hashing */
17913 +static const uint32_t crc_tbl[256] = {
17914 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
17915 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
17916 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
17917 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
17918 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
17919 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
17920 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
17921 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
17922 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
17923 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
17924 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
17925 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
17926 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
17927 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
17928 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
17929 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
17930 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
17931 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
17932 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
17933 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
17934 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
17935 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
17936 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
17937 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
17938 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
17939 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
17940 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
17941 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
17942 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
17943 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
17944 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
17945 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
17946 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
17947 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
17948 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
17949 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
17950 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
17951 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
17952 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
17953 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
17954 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
17955 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
17956 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
17957 +};
17958 +
17959 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
17960 +static inline uint8_t get_mirror8(uint8_t n)
17961 +{
17962 + uint8_t mirror[16] = {
17963 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
17964 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
17965 + };
17966 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
17967 +}
17968 +
17969 +static inline uint32_t get_mirror32(uint32_t n)
17970 +{
17971 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
17972 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
17973 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
17974 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
17975 +}
17976 +
17977 +uint32_t get_mac_addr_crc(uint64_t _addr)
17978 +{
17979 + uint32_t i;
17980 + uint8_t data;
17981 + uint32_t crc;
17982 +
17983 + /* CRC calculation */
17984 + crc = 0xffffffff;
17985 + for (i = 0; i < 6; i++) {
17986 + data = (uint8_t)(_addr >> ((5-i)*8));
17987 + crc = crc ^ data;
17988 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
17989 + }
17990 +
17991 + crc = get_mirror32(crc);
17992 + return crc;
17993 +}
17994 --- /dev/null
17995 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
17996 @@ -0,0 +1,43 @@
17997 +/*
17998 + * Copyright 2008-2012 Freescale Semiconductor Inc.
17999 + *
18000 + * Redistribution and use in source and binary forms, with or without
18001 + * modification, are permitted provided that the following conditions are met:
18002 + * * Redistributions of source code must retain the above copyright
18003 + * notice, this list of conditions and the following disclaimer.
18004 + * * Redistributions in binary form must reproduce the above copyright
18005 + * notice, this list of conditions and the following disclaimer in the
18006 + * documentation and/or other materials provided with the distribution.
18007 + * * Neither the name of Freescale Semiconductor nor the
18008 + * names of its contributors may be used to endorse or promote products
18009 + * derived from this software without specific prior written permission.
18010 + *
18011 + *
18012 + * ALTERNATIVELY, this software may be distributed under the terms of the
18013 + * GNU General Public License ("GPL") as published by the Free Software
18014 + * Foundation, either version 2 of that License or (at your option) any
18015 + * later version.
18016 + *
18017 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18018 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18019 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18020 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18021 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18022 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18023 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18024 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18025 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18026 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18027 + */
18028 +
18029 +
18030 +#ifndef __FMAN_CRC32_H
18031 +#define __FMAN_CRC32_H
18032 +
18033 +#include "common/general.h"
18034 +
18035 +
18036 +uint32_t get_mac_addr_crc(uint64_t _addr);
18037 +
18038 +
18039 +#endif /* __FMAN_CRC32_H */
18040 --- /dev/null
18041 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
18042 @@ -0,0 +1,845 @@
18043 +/*
18044 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18045 + *
18046 + * Redistribution and use in source and binary forms, with or without
18047 + * modification, are permitted provided that the following conditions are met:
18048 + * * Redistributions of source code must retain the above copyright
18049 + * notice, this list of conditions and the following disclaimer.
18050 + * * Redistributions in binary form must reproduce the above copyright
18051 + * notice, this list of conditions and the following disclaimer in the
18052 + * documentation and/or other materials provided with the distribution.
18053 + * * Neither the name of Freescale Semiconductor nor the
18054 + * names of its contributors may be used to endorse or promote products
18055 + * derived from this software without specific prior written permission.
18056 + *
18057 + *
18058 + * ALTERNATIVELY, this software may be distributed under the terms of the
18059 + * GNU General Public License ("GPL") as published by the Free Software
18060 + * Foundation, either version 2 of that License or (at your option) any
18061 + * later version.
18062 + *
18063 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18064 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18065 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18066 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18067 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18068 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18069 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18070 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18071 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18072 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18073 + */
18074 +
18075 +
18076 +#include "fsl_fman_dtsec.h"
18077 +
18078 +
18079 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
18080 +{
18081 + /* Assert the graceful stop bit */
18082 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
18083 +}
18084 +
18085 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
18086 +{
18087 + /* Assert the graceful stop bit */
18088 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
18089 +}
18090 +
18091 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
18092 +{
18093 + /* clear the graceful stop bit */
18094 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
18095 +}
18096 +
18097 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
18098 +{
18099 + /* clear the graceful stop bit */
18100 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
18101 +}
18102 +
18103 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
18104 +{
18105 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
18106 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
18107 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
18108 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
18109 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
18110 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
18111 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
18112 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
18113 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
18114 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
18115 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
18116 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
18117 + cfg->tx_crc = DEFAULT_TX_CRC;
18118 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
18119 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
18120 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
18121 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
18122 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
18123 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
18124 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
18125 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
18126 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
18127 + cfg->loopback = DEFAULT_LOOPBACK;
18128 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
18129 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
18130 + cfg->rx_flow = DEFAULT_RX_FLOW;
18131 + cfg->tx_flow = DEFAULT_TX_FLOW;
18132 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
18133 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
18134 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
18135 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
18136 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
18137 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
18138 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
18139 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
18140 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
18141 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
18142 +}
18143 +
18144 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
18145 + enum enet_interface iface_mode,
18146 + enum enet_speed iface_speed,
18147 + uint8_t *macaddr,
18148 + uint8_t fm_rev_maj,
18149 + uint8_t fm_rev_min,
18150 + uint32_t exception_mask)
18151 +{
18152 + bool is_rgmii = FALSE;
18153 + bool is_sgmii = FALSE;
18154 + bool is_qsgmii = FALSE;
18155 + int i;
18156 + uint32_t tmp;
18157 +
18158 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
18159 +
18160 + /* let's start with a soft reset */
18161 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
18162 + iowrite32be(0, &regs->maccfg1);
18163 +
18164 + /*************dtsec_id2******************/
18165 + tmp = ioread32be(&regs->tsec_id2);
18166 +
18167 + /* check RGMII support */
18168 + if (iface_mode == E_ENET_IF_RGMII ||
18169 + iface_mode == E_ENET_IF_RMII)
18170 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18171 + return -EINVAL;
18172 +
18173 + if (iface_mode == E_ENET_IF_SGMII ||
18174 + iface_mode == E_ENET_IF_MII)
18175 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
18176 + return -EINVAL;
18177 +
18178 + /***************ECNTRL************************/
18179 +
18180 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
18181 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
18182 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
18183 +
18184 + tmp = 0;
18185 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
18186 + tmp |= DTSEC_ECNTRL_GMIIM;
18187 + if (is_sgmii)
18188 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
18189 + if (is_qsgmii)
18190 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
18191 + DTSEC_ECNTRL_QSGMIIM);
18192 + if (is_rgmii)
18193 + tmp |= DTSEC_ECNTRL_RPM;
18194 + if (iface_speed == E_ENET_SPEED_100)
18195 + tmp |= DTSEC_ECNTRL_R100M;
18196 +
18197 + iowrite32be(tmp, &regs->ecntrl);
18198 + /***************ECNTRL************************/
18199 +
18200 + /***************TCTRL************************/
18201 + tmp = 0;
18202 + if (cfg->halfdup_on)
18203 + tmp |= DTSEC_TCTRL_THDF;
18204 + if (cfg->tx_time_stamp_en)
18205 + tmp |= DTSEC_TCTRL_TTSE;
18206 +
18207 + iowrite32be(tmp, &regs->tctrl);
18208 +
18209 + /***************TCTRL************************/
18210 +
18211 + /***************PTV************************/
18212 + tmp = 0;
18213 +
18214 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
18215 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
18216 + cfg->tx_pause_time += 2;
18217 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
18218 +
18219 + if (cfg->tx_pause_time)
18220 + tmp |= cfg->tx_pause_time;
18221 + if (cfg->tx_pause_time_extd)
18222 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
18223 + iowrite32be(tmp, &regs->ptv);
18224 +
18225 + /***************RCTRL************************/
18226 + tmp = 0;
18227 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
18228 + if (cfg->rx_ctrl_acc)
18229 + tmp |= RCTRL_CFA;
18230 + if (cfg->rx_group_hash_exd)
18231 + tmp |= RCTRL_GHTX;
18232 + if (cfg->rx_time_stamp_en)
18233 + tmp |= RCTRL_RTSE;
18234 + if (cfg->rx_drop_bcast)
18235 + tmp |= RCTRL_BC_REJ;
18236 + if (cfg->rx_short_frm)
18237 + tmp |= RCTRL_RSF;
18238 + if (cfg->rx_promisc)
18239 + tmp |= RCTRL_PROM;
18240 +
18241 + iowrite32be(tmp, &regs->rctrl);
18242 + /***************RCTRL************************/
18243 +
18244 + /*
18245 + * Assign a Phy Address to the TBI (TBIPA).
18246 + * Done also in cases where TBI is not selected to avoid conflict with
18247 + * the external PHY's Physical address
18248 + */
18249 + iowrite32be(cfg->tbipa, &regs->tbipa);
18250 +
18251 + /***************TMR_CTL************************/
18252 + iowrite32be(0, &regs->tmr_ctrl);
18253 +
18254 + if (cfg->ptp_tsu_en) {
18255 + tmp = 0;
18256 + tmp |= TMR_PEVENT_TSRE;
18257 + iowrite32be(tmp, &regs->tmr_pevent);
18258 +
18259 + if (cfg->ptp_exception_en) {
18260 + tmp = 0;
18261 + tmp |= TMR_PEMASK_TSREEN;
18262 + iowrite32be(tmp, &regs->tmr_pemask);
18263 + }
18264 + }
18265 +
18266 + /***************MACCFG1***********************/
18267 + tmp = 0;
18268 + if (cfg->loopback)
18269 + tmp |= MACCFG1_LOOPBACK;
18270 + if (cfg->rx_flow)
18271 + tmp |= MACCFG1_RX_FLOW;
18272 + if (cfg->tx_flow)
18273 + tmp |= MACCFG1_TX_FLOW;
18274 + iowrite32be(tmp, &regs->maccfg1);
18275 +
18276 + /***************MACCFG1***********************/
18277 +
18278 + /***************MACCFG2***********************/
18279 + tmp = 0;
18280 +
18281 + if (iface_speed < E_ENET_SPEED_1000)
18282 + tmp |= MACCFG2_NIBBLE_MODE;
18283 + else if (iface_speed == E_ENET_SPEED_1000)
18284 + tmp |= MACCFG2_BYTE_MODE;
18285 +
18286 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
18287 + << PREAMBLE_LENGTH_SHIFT;
18288 +
18289 + if (cfg->rx_preamble)
18290 + tmp |= MACCFG2_PRE_AM_Rx_EN;
18291 + if (cfg->tx_preamble)
18292 + tmp |= MACCFG2_PRE_AM_Tx_EN;
18293 + if (cfg->rx_len_check)
18294 + tmp |= MACCFG2_LENGTH_CHECK;
18295 + if (cfg->tx_pad_crc)
18296 + tmp |= MACCFG2_PAD_CRC_EN;
18297 + if (cfg->tx_crc)
18298 + tmp |= MACCFG2_CRC_EN;
18299 + if (!cfg->halfdup_on)
18300 + tmp |= MACCFG2_FULL_DUPLEX;
18301 + iowrite32be(tmp, &regs->maccfg2);
18302 +
18303 + /***************MACCFG2***********************/
18304 +
18305 + /***************IPGIFG************************/
18306 + tmp = (((cfg->non_back_to_back_ipg1 <<
18307 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
18308 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
18309 + | ((cfg->non_back_to_back_ipg2 <<
18310 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
18311 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
18312 + | ((cfg->min_ifg_enforcement <<
18313 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
18314 + & IPGIFG_MIN_IFG_ENFORCEMENT)
18315 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
18316 + iowrite32be(tmp, &regs->ipgifg);
18317 +
18318 + /***************IPGIFG************************/
18319 +
18320 + /***************HAFDUP************************/
18321 + tmp = 0;
18322 +
18323 + if (cfg->halfdup_alt_backoff_en)
18324 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
18325 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
18326 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
18327 + if (cfg->halfdup_bp_no_backoff)
18328 + tmp |= HAFDUP_BP_NO_BACKOFF;
18329 + if (cfg->halfdup_no_backoff)
18330 + tmp |= HAFDUP_NO_BACKOFF;
18331 + if (cfg->halfdup_excess_defer)
18332 + tmp |= HAFDUP_EXCESS_DEFER;
18333 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
18334 + & HAFDUP_RETRANSMISSION_MAX);
18335 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
18336 +
18337 + iowrite32be(tmp, &regs->hafdup);
18338 + /***************HAFDUP************************/
18339 +
18340 + /***************MAXFRM************************/
18341 + /* Initialize MAXFRM */
18342 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
18343 +
18344 + /***************MAXFRM************************/
18345 +
18346 + /***************CAM1************************/
18347 + iowrite32be(0xffffffff, &regs->cam1);
18348 + iowrite32be(0xffffffff, &regs->cam2);
18349 +
18350 + /***************IMASK************************/
18351 + iowrite32be(exception_mask, &regs->imask);
18352 + /***************IMASK************************/
18353 +
18354 + /***************IEVENT************************/
18355 + iowrite32be(0xffffffff, &regs->ievent);
18356 +
18357 + /***************MACSTNADDR1/2*****************/
18358 +
18359 + tmp = (uint32_t)((macaddr[5] << 24) |
18360 + (macaddr[4] << 16) |
18361 + (macaddr[3] << 8) |
18362 + macaddr[2]);
18363 + iowrite32be(tmp, &regs->macstnaddr1);
18364 +
18365 + tmp = (uint32_t)((macaddr[1] << 24) |
18366 + (macaddr[0] << 16));
18367 + iowrite32be(tmp, &regs->macstnaddr2);
18368 +
18369 + /***************MACSTNADDR1/2*****************/
18370 +
18371 + /*****************HASH************************/
18372 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
18373 + /* Initialize IADDRx */
18374 + iowrite32be(0, &regs->igaddr[i]);
18375 + /* Initialize GADDRx */
18376 + iowrite32be(0, &regs->gaddr[i]);
18377 + }
18378 +
18379 + fman_dtsec_reset_stat(regs);
18380 +
18381 + return 0;
18382 +}
18383 +
18384 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
18385 +{
18386 + return (uint16_t)ioread32be(&regs->maxfrm);
18387 +}
18388 +
18389 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
18390 +{
18391 + iowrite32be(length, &regs->maxfrm);
18392 +}
18393 +
18394 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
18395 +{
18396 + uint32_t tmp;
18397 +
18398 + tmp = (uint32_t)((adr[5] << 24) |
18399 + (adr[4] << 16) |
18400 + (adr[3] << 8) |
18401 + adr[2]);
18402 + iowrite32be(tmp, &regs->macstnaddr1);
18403 +
18404 + tmp = (uint32_t)((adr[1] << 24) |
18405 + (adr[0] << 16));
18406 + iowrite32be(tmp, &regs->macstnaddr2);
18407 +}
18408 +
18409 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
18410 +{
18411 + uint32_t tmp1, tmp2;
18412 +
18413 + tmp1 = ioread32be(&regs->macstnaddr1);
18414 + tmp2 = ioread32be(&regs->macstnaddr2);
18415 +
18416 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
18417 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
18418 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
18419 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
18420 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
18421 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
18422 +}
18423 +
18424 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
18425 +{
18426 + int32_t bucket;
18427 + if (ghtx)
18428 + bucket = (int32_t)((crc >> 23) & 0x1ff);
18429 + else {
18430 + bucket = (int32_t)((crc >> 24) & 0xff);
18431 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
18432 + if (mcast)
18433 + bucket += 0x100;
18434 + }
18435 + fman_dtsec_set_bucket(regs, bucket, TRUE);
18436 +}
18437 +
18438 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
18439 +{
18440 + int reg_idx = (bucket >> 5) & 0xf;
18441 + int bit_idx = bucket & 0x1f;
18442 + uint32_t bit_mask = 0x80000000 >> bit_idx;
18443 + uint32_t *reg;
18444 +
18445 + if (reg_idx > 7)
18446 + reg = &regs->gaddr[reg_idx-8];
18447 + else
18448 + reg = &regs->igaddr[reg_idx];
18449 +
18450 + if (enable)
18451 + iowrite32be(ioread32be(reg) | bit_mask, reg);
18452 + else
18453 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
18454 +}
18455 +
18456 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
18457 +{
18458 + int i;
18459 + bool ghtx;
18460 +
18461 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
18462 +
18463 + if (ucast || (ghtx && mcast)) {
18464 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18465 + iowrite32be(0, &regs->igaddr[i]);
18466 + }
18467 + if (mcast) {
18468 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
18469 + iowrite32be(0, &regs->gaddr[i]);
18470 + }
18471 +}
18472 +
18473 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
18474 + uint8_t addr)
18475 +{
18476 + if (addr > 0 && addr < 32)
18477 + iowrite32be(addr, &regs->tbipa);
18478 + else
18479 + return -EINVAL;
18480 +
18481 + return 0;
18482 +}
18483 +
18484 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
18485 +{
18486 + uint32_t tmp;
18487 +
18488 + tmp = ioread32be(&regs->maccfg2);
18489 + if (en)
18490 + tmp |= MACCFG2_MAGIC_PACKET_EN;
18491 + else
18492 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
18493 + iowrite32be(tmp, &regs->maccfg2);
18494 +}
18495 +
18496 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
18497 + enum enet_interface iface_mode,
18498 + enum enet_speed speed, bool full_dx)
18499 +{
18500 + uint32_t tmp;
18501 +
18502 + UNUSED(iface_mode);
18503 +
18504 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
18505 + return -EINVAL;
18506 +
18507 + tmp = ioread32be(&regs->maccfg2);
18508 + if (!full_dx)
18509 + tmp &= ~MACCFG2_FULL_DUPLEX;
18510 + else
18511 + tmp |= MACCFG2_FULL_DUPLEX;
18512 +
18513 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
18514 + if (speed < E_ENET_SPEED_1000)
18515 + tmp |= MACCFG2_NIBBLE_MODE;
18516 + else if (speed == E_ENET_SPEED_1000)
18517 + tmp |= MACCFG2_BYTE_MODE;
18518 + iowrite32be(tmp, &regs->maccfg2);
18519 +
18520 + tmp = ioread32be(&regs->ecntrl);
18521 + if (speed == E_ENET_SPEED_100)
18522 + tmp |= DTSEC_ECNTRL_R100M;
18523 + else
18524 + tmp &= ~DTSEC_ECNTRL_R100M;
18525 + iowrite32be(tmp, &regs->ecntrl);
18526 +
18527 + return 0;
18528 +}
18529 +
18530 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
18531 +{
18532 + uint32_t tmp;
18533 +
18534 + tmp = ioread32be(&regs->rctrl);
18535 +
18536 + if (enable)
18537 + tmp |= RCTRL_UPROM;
18538 + else
18539 + tmp &= ~RCTRL_UPROM;
18540 +
18541 + iowrite32be(tmp, &regs->rctrl);
18542 +}
18543 +
18544 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
18545 +{
18546 + uint32_t tmp;
18547 +
18548 + tmp = ioread32be(&regs->rctrl);
18549 +
18550 + if (enable)
18551 + tmp |= RCTRL_MPROM;
18552 + else
18553 + tmp &= ~RCTRL_MPROM;
18554 +
18555 + iowrite32be(tmp, &regs->rctrl);
18556 +}
18557 +
18558 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
18559 + uint32_t *car1, uint32_t *car2)
18560 +{
18561 + /* read carry registers */
18562 + *car1 = ioread32be(&regs->car1);
18563 + *car2 = ioread32be(&regs->car2);
18564 + /* clear carry registers */
18565 + if (*car1)
18566 + iowrite32be(*car1, &regs->car1);
18567 + if (*car2)
18568 + iowrite32be(*car2, &regs->car2);
18569 +
18570 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
18571 +}
18572 +
18573 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
18574 +{
18575 + /* clear HW counters */
18576 + iowrite32be(ioread32be(&regs->ecntrl) |
18577 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
18578 +}
18579 +
18580 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
18581 +{
18582 + switch (level) {
18583 + case E_MAC_STAT_NONE:
18584 + iowrite32be(0xffffffff, &regs->cam1);
18585 + iowrite32be(0xffffffff, &regs->cam2);
18586 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
18587 + &regs->ecntrl);
18588 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
18589 + &regs->imask);
18590 + break;
18591 + case E_MAC_STAT_PARTIAL:
18592 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
18593 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
18594 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18595 + &regs->ecntrl);
18596 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18597 + &regs->imask);
18598 + break;
18599 + case E_MAC_STAT_MIB_GRP1:
18600 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
18601 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
18602 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18603 + &regs->ecntrl);
18604 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18605 + &regs->imask);
18606 + break;
18607 + case E_MAC_STAT_FULL:
18608 + iowrite32be(0, &regs->cam1);
18609 + iowrite32be(0, &regs->cam2);
18610 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
18611 + &regs->ecntrl);
18612 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
18613 + &regs->imask);
18614 + break;
18615 + default:
18616 + return -EINVAL;
18617 + }
18618 +
18619 + return 0;
18620 +}
18621 +
18622 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
18623 +{
18624 + if (en) {
18625 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
18626 + &regs->rctrl);
18627 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
18628 + &regs->tctrl);
18629 + } else {
18630 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
18631 + &regs->rctrl);
18632 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
18633 + &regs->tctrl);
18634 + }
18635 +}
18636 +
18637 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18638 +{
18639 + uint32_t tmp;
18640 +
18641 + tmp = ioread32be(&regs->maccfg1);
18642 +
18643 + if (apply_rx)
18644 + tmp |= MACCFG1_RX_EN ;
18645 +
18646 + if (apply_tx)
18647 + tmp |= MACCFG1_TX_EN ;
18648 +
18649 + iowrite32be(tmp, &regs->maccfg1);
18650 +}
18651 +
18652 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
18653 +{
18654 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
18655 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
18656 +}
18657 +
18658 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
18659 + uint64_t addr,
18660 + uint8_t paddr_num)
18661 +{
18662 + uint32_t tmp;
18663 +
18664 + tmp = (uint32_t)(addr);
18665 + /* swap */
18666 + tmp = (((tmp & 0x000000FF) << 24) |
18667 + ((tmp & 0x0000FF00) << 8) |
18668 + ((tmp & 0x00FF0000) >> 8) |
18669 + ((tmp & 0xFF000000) >> 24));
18670 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
18671 +
18672 + tmp = (uint32_t)(addr>>32);
18673 + /* swap */
18674 + tmp = (((tmp & 0x000000FF) << 24) |
18675 + ((tmp & 0x0000FF00) << 8) |
18676 + ((tmp & 0x00FF0000) >> 8) |
18677 + ((tmp & 0xFF000000) >> 24));
18678 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
18679 +}
18680 +
18681 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
18682 +{
18683 + uint32_t tmp;
18684 +
18685 + tmp = ioread32be(&regs->maccfg1);
18686 +
18687 + if (apply_rx)
18688 + tmp &= ~MACCFG1_RX_EN;
18689 +
18690 + if (apply_tx)
18691 + tmp &= ~MACCFG1_TX_EN;
18692 +
18693 + iowrite32be(tmp, &regs->maccfg1);
18694 +}
18695 +
18696 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
18697 +{
18698 + uint32_t ptv = 0;
18699 +
18700 + /* fixme: don't enable tx pause for half-duplex */
18701 +
18702 + if (time) {
18703 + ptv = ioread32be(&regs->ptv);
18704 + ptv &= 0xffff0000;
18705 + ptv |= time & 0x0000ffff;
18706 + iowrite32be(ptv, &regs->ptv);
18707 +
18708 + /* trigger the transmission of a flow-control pause frame */
18709 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
18710 + &regs->maccfg1);
18711 + } else
18712 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
18713 + &regs->maccfg1);
18714 +}
18715 +
18716 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
18717 +{
18718 + uint32_t tmp;
18719 +
18720 + /* todo: check if mac is set to full-duplex */
18721 +
18722 + tmp = ioread32be(&regs->maccfg1);
18723 + if (en)
18724 + tmp |= MACCFG1_RX_FLOW;
18725 + else
18726 + tmp &= ~MACCFG1_RX_FLOW;
18727 + iowrite32be(tmp, &regs->maccfg1);
18728 +}
18729 +
18730 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
18731 +{
18732 + return ioread32be(&regs->rctrl);
18733 +}
18734 +
18735 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
18736 +{
18737 + return ioread32be(&regs->tsec_id);
18738 +}
18739 +
18740 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
18741 +{
18742 + return ioread32be(&regs->ievent) & ev_mask;
18743 +}
18744 +
18745 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
18746 +{
18747 + iowrite32be(ev_mask, &regs->ievent);
18748 +}
18749 +
18750 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
18751 +{
18752 + return ioread32be(&regs->imask);
18753 +}
18754 +
18755 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
18756 +{
18757 + uint32_t event;
18758 +
18759 + event = ioread32be(&regs->tmr_pevent);
18760 + event &= ioread32be(&regs->tmr_pemask);
18761 +
18762 + if (event)
18763 + iowrite32be(event, &regs->tmr_pevent);
18764 + return event;
18765 +}
18766 +
18767 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
18768 +{
18769 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
18770 + &regs->tmr_pemask);
18771 +}
18772 +
18773 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
18774 +{
18775 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
18776 + &regs->tmr_pemask);
18777 +}
18778 +
18779 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18780 +{
18781 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
18782 +}
18783 +
18784 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
18785 +{
18786 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
18787 +}
18788 +
18789 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
18790 + enum dtsec_stat_counters reg_name)
18791 +{
18792 + uint32_t ret_val;
18793 +
18794 + switch (reg_name) {
18795 + case E_DTSEC_STAT_TR64:
18796 + ret_val = ioread32be(&regs->tr64);
18797 + break;
18798 + case E_DTSEC_STAT_TR127:
18799 + ret_val = ioread32be(&regs->tr127);
18800 + break;
18801 + case E_DTSEC_STAT_TR255:
18802 + ret_val = ioread32be(&regs->tr255);
18803 + break;
18804 + case E_DTSEC_STAT_TR511:
18805 + ret_val = ioread32be(&regs->tr511);
18806 + break;
18807 + case E_DTSEC_STAT_TR1K:
18808 + ret_val = ioread32be(&regs->tr1k);
18809 + break;
18810 + case E_DTSEC_STAT_TRMAX:
18811 + ret_val = ioread32be(&regs->trmax);
18812 + break;
18813 + case E_DTSEC_STAT_TRMGV:
18814 + ret_val = ioread32be(&regs->trmgv);
18815 + break;
18816 + case E_DTSEC_STAT_RBYT:
18817 + ret_val = ioread32be(&regs->rbyt);
18818 + break;
18819 + case E_DTSEC_STAT_RPKT:
18820 + ret_val = ioread32be(&regs->rpkt);
18821 + break;
18822 + case E_DTSEC_STAT_RMCA:
18823 + ret_val = ioread32be(&regs->rmca);
18824 + break;
18825 + case E_DTSEC_STAT_RBCA:
18826 + ret_val = ioread32be(&regs->rbca);
18827 + break;
18828 + case E_DTSEC_STAT_RXPF:
18829 + ret_val = ioread32be(&regs->rxpf);
18830 + break;
18831 + case E_DTSEC_STAT_RALN:
18832 + ret_val = ioread32be(&regs->raln);
18833 + break;
18834 + case E_DTSEC_STAT_RFLR:
18835 + ret_val = ioread32be(&regs->rflr);
18836 + break;
18837 + case E_DTSEC_STAT_RCDE:
18838 + ret_val = ioread32be(&regs->rcde);
18839 + break;
18840 + case E_DTSEC_STAT_RCSE:
18841 + ret_val = ioread32be(&regs->rcse);
18842 + break;
18843 + case E_DTSEC_STAT_RUND:
18844 + ret_val = ioread32be(&regs->rund);
18845 + break;
18846 + case E_DTSEC_STAT_ROVR:
18847 + ret_val = ioread32be(&regs->rovr);
18848 + break;
18849 + case E_DTSEC_STAT_RFRG:
18850 + ret_val = ioread32be(&regs->rfrg);
18851 + break;
18852 + case E_DTSEC_STAT_RJBR:
18853 + ret_val = ioread32be(&regs->rjbr);
18854 + break;
18855 + case E_DTSEC_STAT_RDRP:
18856 + ret_val = ioread32be(&regs->rdrp);
18857 + break;
18858 + case E_DTSEC_STAT_TFCS:
18859 + ret_val = ioread32be(&regs->tfcs);
18860 + break;
18861 + case E_DTSEC_STAT_TBYT:
18862 + ret_val = ioread32be(&regs->tbyt);
18863 + break;
18864 + case E_DTSEC_STAT_TPKT:
18865 + ret_val = ioread32be(&regs->tpkt);
18866 + break;
18867 + case E_DTSEC_STAT_TMCA:
18868 + ret_val = ioread32be(&regs->tmca);
18869 + break;
18870 + case E_DTSEC_STAT_TBCA:
18871 + ret_val = ioread32be(&regs->tbca);
18872 + break;
18873 + case E_DTSEC_STAT_TXPF:
18874 + ret_val = ioread32be(&regs->txpf);
18875 + break;
18876 + case E_DTSEC_STAT_TNCL:
18877 + ret_val = ioread32be(&regs->tncl);
18878 + break;
18879 + case E_DTSEC_STAT_TDRP:
18880 + ret_val = ioread32be(&regs->tdrp);
18881 + break;
18882 + default:
18883 + ret_val = 0;
18884 + }
18885 +
18886 + return ret_val;
18887 +}
18888 --- /dev/null
18889 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
18890 @@ -0,0 +1,163 @@
18891 +/*
18892 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18893 + *
18894 + * Redistribution and use in source and binary forms, with or without
18895 + * modification, are permitted provided that the following conditions are met:
18896 + * * Redistributions of source code must retain the above copyright
18897 + * notice, this list of conditions and the following disclaimer.
18898 + * * Redistributions in binary form must reproduce the above copyright
18899 + * notice, this list of conditions and the following disclaimer in the
18900 + * documentation and/or other materials provided with the distribution.
18901 + * * Neither the name of Freescale Semiconductor nor the
18902 + * names of its contributors may be used to endorse or promote products
18903 + * derived from this software without specific prior written permission.
18904 + *
18905 + *
18906 + * ALTERNATIVELY, this software may be distributed under the terms of the
18907 + * GNU General Public License ("GPL") as published by the Free Software
18908 + * Foundation, either version 2 of that License or (at your option) any
18909 + * later version.
18910 + *
18911 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18912 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18913 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18914 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18915 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18916 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18917 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18918 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18919 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18920 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18921 + */
18922 +
18923 +
18924 +#include "common/general.h"
18925 +#include "fsl_fman_dtsec_mii_acc.h"
18926 +
18927 +
18928 +/**
18929 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
18930 + * @dtsec_freq: dtsec clock frequency (in Mhz)
18931 + *
18932 + * This function calculates the dtsec mii clock divider that determines
18933 + * the MII MDC clock. MII MDC clock will be set to work in the range
18934 + * of 1.5 to 2.5Mhz
18935 + * The output of this function is the value of MIIMCFG[MgmtClk] which
18936 + * implicitly determines the divider value.
18937 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
18938 + *
18939 + * The table below which reflects dtsec_mii_get_div() functionality
18940 + * shows the relations among dtsec_freq, MgmtClk, actual divider
18941 + * and the MII frequency:
18942 + *
18943 + * dtsec freq MgmtClk div MII freq Mhz
18944 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
18945 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
18946 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
18947 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
18948 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
18949 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
18950 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
18951 + * [560..frq] 7 (1/28)(1/8) [frq/224]
18952 + *
18953 + * Returns: the MIIMCFG[MgmtClk] appropriate value
18954 + */
18955 +
18956 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
18957 +{
18958 + uint16_t mgmt_clk;
18959 +
18960 + if (dtsec_freq < 80) mgmt_clk = 1;
18961 + else if (dtsec_freq < 120) mgmt_clk = 2;
18962 + else if (dtsec_freq < 160) mgmt_clk = 3;
18963 + else if (dtsec_freq < 200) mgmt_clk = 4;
18964 + else if (dtsec_freq < 280) mgmt_clk = 5;
18965 + else if (dtsec_freq < 400) mgmt_clk = 6;
18966 + else mgmt_clk = 7;
18967 +
18968 + return (uint8_t)mgmt_clk;
18969 +}
18970 +
18971 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
18972 +{
18973 + /* Reset the management interface */
18974 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
18975 + &regs->miimcfg);
18976 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
18977 + &regs->miimcfg);
18978 +}
18979 +
18980 +
18981 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
18982 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
18983 +{
18984 + uint32_t tmp;
18985 +
18986 + /* Setup the MII Mgmt clock speed */
18987 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
18988 + wmb();
18989 +
18990 + /* Stop the MII management read cycle */
18991 + iowrite32be(0, &regs->miimcom);
18992 + /* Dummy read to make sure MIIMCOM is written */
18993 + tmp = ioread32be(&regs->miimcom);
18994 + wmb();
18995 +
18996 + /* Setting up MII Management Address Register */
18997 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
18998 + iowrite32be(tmp, &regs->miimadd);
18999 + wmb();
19000 +
19001 + /* Setting up MII Management Control Register with data */
19002 + iowrite32be((uint32_t)data, &regs->miimcon);
19003 + /* Dummy read to make sure MIIMCON is written */
19004 + tmp = ioread32be(&regs->miimcon);
19005 + wmb();
19006 +
19007 + /* Wait until MII management write is complete */
19008 + /* todo: a timeout could be useful here */
19009 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
19010 + /* busy wait */;
19011 +
19012 + return 0;
19013 +}
19014 +
19015 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
19016 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
19017 +{
19018 + uint32_t tmp;
19019 +
19020 + /* Setup the MII Mgmt clock speed */
19021 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
19022 + wmb();
19023 +
19024 + /* Setting up the MII Management Address Register */
19025 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
19026 + iowrite32be(tmp, &regs->miimadd);
19027 + wmb();
19028 +
19029 + /* Perform an MII management read cycle */
19030 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
19031 + /* Dummy read to make sure MIIMCOM is written */
19032 + tmp = ioread32be(&regs->miimcom);
19033 + wmb();
19034 +
19035 + /* Wait until MII management read is complete */
19036 + /* todo: a timeout could be useful here */
19037 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
19038 + /* busy wait */;
19039 +
19040 + /* Read MII management status */
19041 + *data = (uint16_t)ioread32be(&regs->miimstat);
19042 + wmb();
19043 +
19044 + iowrite32be(0, &regs->miimcom);
19045 + /* Dummy read to make sure MIIMCOM is written */
19046 + tmp = ioread32be(&regs->miimcom);
19047 +
19048 + if (*data == 0xffff)
19049 + return -ENXIO;
19050 +
19051 + return 0;
19052 +}
19053 +
19054 --- /dev/null
19055 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
19056 @@ -0,0 +1,532 @@
19057 +/*
19058 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19059 + *
19060 + * Redistribution and use in source and binary forms, with or without
19061 + * modification, are permitted provided that the following conditions are met:
19062 + * * Redistributions of source code must retain the above copyright
19063 + * notice, this list of conditions and the following disclaimer.
19064 + * * Redistributions in binary form must reproduce the above copyright
19065 + * notice, this list of conditions and the following disclaimer in the
19066 + * documentation and/or other materials provided with the distribution.
19067 + * * Neither the name of Freescale Semiconductor nor the
19068 + * names of its contributors may be used to endorse or promote products
19069 + * derived from this software without specific prior written permission.
19070 + *
19071 + *
19072 + * ALTERNATIVELY, this software may be distributed under the terms of the
19073 + * GNU General Public License ("GPL") as published by the Free Software
19074 + * Foundation, either version 2 of that License or (at your option) any
19075 + * later version.
19076 + *
19077 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19078 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19079 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19080 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19081 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19082 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19083 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19084 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19085 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19086 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19087 + */
19088 +
19089 +
19090 +#include "fsl_fman_memac.h"
19091 +
19092 +
19093 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
19094 +{
19095 + return ioread32be(&regs->ievent) & ev_mask;
19096 +}
19097 +
19098 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
19099 +{
19100 + return ioread32be(&regs->imask);
19101 +}
19102 +
19103 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
19104 +{
19105 + iowrite32be(ev_mask, &regs->ievent);
19106 +}
19107 +
19108 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
19109 +{
19110 + uint32_t tmp;
19111 +
19112 + tmp = ioread32be(&regs->command_config);
19113 +
19114 + if (val)
19115 + tmp |= CMD_CFG_PROMIS_EN;
19116 + else
19117 + tmp &= ~CMD_CFG_PROMIS_EN;
19118 +
19119 + iowrite32be(tmp, &regs->command_config);
19120 +}
19121 +
19122 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
19123 + uint8_t paddr_num)
19124 +{
19125 + if (paddr_num == 0) {
19126 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
19127 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
19128 + } else {
19129 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
19130 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
19131 + }
19132 +}
19133 +
19134 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
19135 + uint8_t *adr,
19136 + uint8_t paddr_num)
19137 +{
19138 + uint32_t tmp0, tmp1;
19139 +
19140 + tmp0 = (uint32_t)(adr[0] |
19141 + adr[1] << 8 |
19142 + adr[2] << 16 |
19143 + adr[3] << 24);
19144 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19145 +
19146 + if (paddr_num == 0) {
19147 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
19148 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
19149 + } else {
19150 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
19151 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
19152 + }
19153 +}
19154 +
19155 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19156 +{
19157 + uint32_t tmp;
19158 +
19159 + tmp = ioread32be(&regs->command_config);
19160 +
19161 + if (apply_rx)
19162 + tmp |= CMD_CFG_RX_EN;
19163 +
19164 + if (apply_tx)
19165 + tmp |= CMD_CFG_TX_EN;
19166 +
19167 + iowrite32be(tmp, &regs->command_config);
19168 +}
19169 +
19170 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
19171 +{
19172 + uint32_t tmp;
19173 +
19174 + tmp = ioread32be(&regs->command_config);
19175 +
19176 + if (apply_rx)
19177 + tmp &= ~CMD_CFG_RX_EN;
19178 +
19179 + if (apply_tx)
19180 + tmp &= ~CMD_CFG_TX_EN;
19181 +
19182 + iowrite32be(tmp, &regs->command_config);
19183 +}
19184 +
19185 +void fman_memac_reset_stat(struct memac_regs *regs)
19186 +{
19187 + uint32_t tmp;
19188 +
19189 + tmp = ioread32be(&regs->statn_config);
19190 +
19191 + tmp |= STATS_CFG_CLR;
19192 +
19193 + iowrite32be(tmp, &regs->statn_config);
19194 +
19195 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
19196 +}
19197 +
19198 +void fman_memac_reset(struct memac_regs *regs)
19199 +{
19200 + uint32_t tmp;
19201 +
19202 + tmp = ioread32be(&regs->command_config);
19203 +
19204 + tmp |= CMD_CFG_SW_RESET;
19205 +
19206 + iowrite32be(tmp, &regs->command_config);
19207 +
19208 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
19209 +}
19210 +
19211 +int fman_memac_init(struct memac_regs *regs,
19212 + struct memac_cfg *cfg,
19213 + enum enet_interface enet_interface,
19214 + enum enet_speed enet_speed,
19215 + bool slow_10g_if,
19216 + uint32_t exceptions)
19217 +{
19218 + uint32_t tmp;
19219 +
19220 + /* Config */
19221 + tmp = 0;
19222 + if (cfg->wan_mode_enable)
19223 + tmp |= CMD_CFG_WAN_MODE;
19224 + if (cfg->promiscuous_mode_enable)
19225 + tmp |= CMD_CFG_PROMIS_EN;
19226 + if (cfg->pause_forward_enable)
19227 + tmp |= CMD_CFG_PAUSE_FWD;
19228 + if (cfg->pause_ignore)
19229 + tmp |= CMD_CFG_PAUSE_IGNORE;
19230 + if (cfg->tx_addr_ins_enable)
19231 + tmp |= CMD_CFG_TX_ADDR_INS;
19232 + if (cfg->loopback_enable)
19233 + tmp |= CMD_CFG_LOOPBACK_EN;
19234 + if (cfg->cmd_frame_enable)
19235 + tmp |= CMD_CFG_CNT_FRM_EN;
19236 + if (cfg->send_idle_enable)
19237 + tmp |= CMD_CFG_SEND_IDLE;
19238 + if (cfg->no_length_check_enable)
19239 + tmp |= CMD_CFG_NO_LEN_CHK;
19240 + if (cfg->rx_sfd_any)
19241 + tmp |= CMD_CFG_SFD_ANY;
19242 + if (cfg->pad_enable)
19243 + tmp |= CMD_CFG_TX_PAD_EN;
19244 + if (cfg->wake_on_lan)
19245 + tmp |= CMD_CFG_MG;
19246 +
19247 + tmp |= CMD_CFG_CRC_FWD;
19248 +
19249 + iowrite32be(tmp, &regs->command_config);
19250 +
19251 + /* Max Frame Length */
19252 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
19253 +
19254 + /* Pause Time */
19255 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
19256 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
19257 +
19258 + /* IF_MODE */
19259 + tmp = 0;
19260 + switch (enet_interface) {
19261 + case E_ENET_IF_XGMII:
19262 + case E_ENET_IF_XFI:
19263 + tmp |= IF_MODE_XGMII;
19264 + break;
19265 + default:
19266 + tmp |= IF_MODE_GMII;
19267 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
19268 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
19269 + }
19270 + iowrite32be(tmp, &regs->if_mode);
19271 +
19272 + /* TX_FIFO_SECTIONS */
19273 + tmp = 0;
19274 + if (enet_interface == E_ENET_IF_XGMII ||
19275 + enet_interface == E_ENET_IF_XFI) {
19276 + if(slow_10g_if) {
19277 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
19278 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19279 + } else {
19280 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
19281 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
19282 + }
19283 + } else {
19284 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
19285 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
19286 + }
19287 + iowrite32be(tmp, &regs->tx_fifo_sections);
19288 +
19289 + /* clear all pending events and set-up interrupts */
19290 + fman_memac_ack_event(regs, 0xffffffff);
19291 + fman_memac_set_exception(regs, exceptions, TRUE);
19292 +
19293 + return 0;
19294 +}
19295 +
19296 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
19297 +{
19298 + uint32_t tmp;
19299 +
19300 + tmp = ioread32be(&regs->imask);
19301 + if (enable)
19302 + tmp |= val;
19303 + else
19304 + tmp &= ~val;
19305 +
19306 + iowrite32be(tmp, &regs->imask);
19307 +}
19308 +
19309 +void fman_memac_reset_filter_table(struct memac_regs *regs)
19310 +{
19311 + uint32_t i;
19312 + for (i = 0; i < 64; i++)
19313 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19314 +}
19315 +
19316 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
19317 +{
19318 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
19319 +}
19320 +
19321 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
19322 +{
19323 + iowrite32be(val, &regs->hashtable_ctrl);
19324 +}
19325 +
19326 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
19327 +{
19328 + uint32_t tmp;
19329 +
19330 + tmp = ioread32be(&regs->maxfrm);
19331 +
19332 + return(uint16_t)tmp;
19333 +}
19334 +
19335 +
19336 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
19337 + uint8_t priority,
19338 + uint16_t pause_time,
19339 + uint16_t thresh_time)
19340 +{
19341 + uint32_t tmp;
19342 +
19343 + tmp = ioread32be(&regs->tx_fifo_sections);
19344 +
19345 + if (priority == 0xff) {
19346 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
19347 + iowrite32be(tmp, &regs->tx_fifo_sections);
19348 +
19349 + tmp = ioread32be(&regs->command_config);
19350 + tmp &= ~CMD_CFG_PFC_MODE;
19351 + priority = 0;
19352 + } else {
19353 + GET_TX_EMPTY_PFC_VALUE(tmp);
19354 + iowrite32be(tmp, &regs->tx_fifo_sections);
19355 +
19356 + tmp = ioread32be(&regs->command_config);
19357 + tmp |= CMD_CFG_PFC_MODE;
19358 + }
19359 +
19360 + iowrite32be(tmp, &regs->command_config);
19361 +
19362 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
19363 + if (priority % 2)
19364 + tmp &= 0x0000FFFF;
19365 + else
19366 + tmp &= 0xFFFF0000;
19367 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
19368 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
19369 +
19370 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
19371 + if (priority % 2)
19372 + tmp &= 0x0000FFFF;
19373 + else
19374 + tmp &= 0xFFFF0000;
19375 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
19376 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
19377 +}
19378 +
19379 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
19380 +{
19381 + uint32_t tmp;
19382 +
19383 + tmp = ioread32be(&regs->command_config);
19384 + if (enable)
19385 + tmp |= CMD_CFG_PAUSE_IGNORE;
19386 + else
19387 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
19388 +
19389 + iowrite32be(tmp, &regs->command_config);
19390 +}
19391 +
19392 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
19393 +{
19394 + uint32_t tmp;
19395 +
19396 + tmp = ioread32be(&regs->command_config);
19397 +
19398 + if (enable)
19399 + tmp |= CMD_CFG_MG;
19400 + else
19401 + tmp &= ~CMD_CFG_MG;
19402 +
19403 + iowrite32be(tmp, &regs->command_config);
19404 +}
19405 +
19406 +#define GET_MEMAC_CNTR_64(bn) \
19407 + (ioread32be(&regs->bn ## _l) | \
19408 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
19409 +
19410 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
19411 + enum memac_counters reg_name)
19412 +{
19413 + uint64_t ret_val;
19414 +
19415 + switch (reg_name) {
19416 + case E_MEMAC_COUNTER_R64:
19417 + ret_val = GET_MEMAC_CNTR_64(r64);
19418 + break;
19419 + case E_MEMAC_COUNTER_T64:
19420 + ret_val = GET_MEMAC_CNTR_64(t64);
19421 + break;
19422 + case E_MEMAC_COUNTER_R127:
19423 + ret_val = GET_MEMAC_CNTR_64(r127);
19424 + break;
19425 + case E_MEMAC_COUNTER_T127:
19426 + ret_val = GET_MEMAC_CNTR_64(t127);
19427 + break;
19428 + case E_MEMAC_COUNTER_R255:
19429 + ret_val = GET_MEMAC_CNTR_64(r255);
19430 + break;
19431 + case E_MEMAC_COUNTER_T255:
19432 + ret_val = GET_MEMAC_CNTR_64(t255);
19433 + break;
19434 + case E_MEMAC_COUNTER_R511:
19435 + ret_val = GET_MEMAC_CNTR_64(r511);
19436 + break;
19437 + case E_MEMAC_COUNTER_T511:
19438 + ret_val = GET_MEMAC_CNTR_64(t511);
19439 + break;
19440 + case E_MEMAC_COUNTER_R1023:
19441 + ret_val = GET_MEMAC_CNTR_64(r1023);
19442 + break;
19443 + case E_MEMAC_COUNTER_T1023:
19444 + ret_val = GET_MEMAC_CNTR_64(t1023);
19445 + break;
19446 + case E_MEMAC_COUNTER_R1518:
19447 + ret_val = GET_MEMAC_CNTR_64(r1518);
19448 + break;
19449 + case E_MEMAC_COUNTER_T1518:
19450 + ret_val = GET_MEMAC_CNTR_64(t1518);
19451 + break;
19452 + case E_MEMAC_COUNTER_R1519X:
19453 + ret_val = GET_MEMAC_CNTR_64(r1519x);
19454 + break;
19455 + case E_MEMAC_COUNTER_T1519X:
19456 + ret_val = GET_MEMAC_CNTR_64(t1519x);
19457 + break;
19458 + case E_MEMAC_COUNTER_RFRG:
19459 + ret_val = GET_MEMAC_CNTR_64(rfrg);
19460 + break;
19461 + case E_MEMAC_COUNTER_RJBR:
19462 + ret_val = GET_MEMAC_CNTR_64(rjbr);
19463 + break;
19464 + case E_MEMAC_COUNTER_RDRP:
19465 + ret_val = GET_MEMAC_CNTR_64(rdrp);
19466 + break;
19467 + case E_MEMAC_COUNTER_RALN:
19468 + ret_val = GET_MEMAC_CNTR_64(raln);
19469 + break;
19470 + case E_MEMAC_COUNTER_TUND:
19471 + ret_val = GET_MEMAC_CNTR_64(tund);
19472 + break;
19473 + case E_MEMAC_COUNTER_ROVR:
19474 + ret_val = GET_MEMAC_CNTR_64(rovr);
19475 + break;
19476 + case E_MEMAC_COUNTER_RXPF:
19477 + ret_val = GET_MEMAC_CNTR_64(rxpf);
19478 + break;
19479 + case E_MEMAC_COUNTER_TXPF:
19480 + ret_val = GET_MEMAC_CNTR_64(txpf);
19481 + break;
19482 + case E_MEMAC_COUNTER_ROCT:
19483 + ret_val = GET_MEMAC_CNTR_64(roct);
19484 + break;
19485 + case E_MEMAC_COUNTER_RMCA:
19486 + ret_val = GET_MEMAC_CNTR_64(rmca);
19487 + break;
19488 + case E_MEMAC_COUNTER_RBCA:
19489 + ret_val = GET_MEMAC_CNTR_64(rbca);
19490 + break;
19491 + case E_MEMAC_COUNTER_RPKT:
19492 + ret_val = GET_MEMAC_CNTR_64(rpkt);
19493 + break;
19494 + case E_MEMAC_COUNTER_RUCA:
19495 + ret_val = GET_MEMAC_CNTR_64(ruca);
19496 + break;
19497 + case E_MEMAC_COUNTER_RERR:
19498 + ret_val = GET_MEMAC_CNTR_64(rerr);
19499 + break;
19500 + case E_MEMAC_COUNTER_TOCT:
19501 + ret_val = GET_MEMAC_CNTR_64(toct);
19502 + break;
19503 + case E_MEMAC_COUNTER_TMCA:
19504 + ret_val = GET_MEMAC_CNTR_64(tmca);
19505 + break;
19506 + case E_MEMAC_COUNTER_TBCA:
19507 + ret_val = GET_MEMAC_CNTR_64(tbca);
19508 + break;
19509 + case E_MEMAC_COUNTER_TUCA:
19510 + ret_val = GET_MEMAC_CNTR_64(tuca);
19511 + break;
19512 + case E_MEMAC_COUNTER_TERR:
19513 + ret_val = GET_MEMAC_CNTR_64(terr);
19514 + break;
19515 + default:
19516 + ret_val = 0;
19517 + }
19518 +
19519 + return ret_val;
19520 +}
19521 +
19522 +void fman_memac_adjust_link(struct memac_regs *regs,
19523 + enum enet_interface iface_mode,
19524 + enum enet_speed speed, bool full_dx)
19525 +{
19526 + uint32_t tmp;
19527 +
19528 + tmp = ioread32be(&regs->if_mode);
19529 +
19530 + if (full_dx)
19531 + tmp &= ~IF_MODE_HD;
19532 + else
19533 + tmp |= IF_MODE_HD;
19534 +
19535 + if (iface_mode == E_ENET_IF_RGMII) {
19536 + /* Configure RGMII in manual mode */
19537 + tmp &= ~IF_MODE_RGMII_AUTO;
19538 + tmp &= ~IF_MODE_RGMII_SP_MASK;
19539 +
19540 + if (full_dx)
19541 + tmp |= IF_MODE_RGMII_FD;
19542 + else
19543 + tmp &= ~IF_MODE_RGMII_FD;
19544 +
19545 + switch (speed) {
19546 + case E_ENET_SPEED_1000:
19547 + tmp |= IF_MODE_RGMII_1000;
19548 + break;
19549 + case E_ENET_SPEED_100:
19550 + tmp |= IF_MODE_RGMII_100;
19551 + break;
19552 + case E_ENET_SPEED_10:
19553 + tmp |= IF_MODE_RGMII_10;
19554 + break;
19555 + default:
19556 + break;
19557 + }
19558 + }
19559 +
19560 + iowrite32be(tmp, &regs->if_mode);
19561 +}
19562 +
19563 +void fman_memac_defconfig(struct memac_cfg *cfg)
19564 +{
19565 + cfg->reset_on_init = FALSE;
19566 + cfg->wan_mode_enable = FALSE;
19567 + cfg->promiscuous_mode_enable = FALSE;
19568 + cfg->pause_forward_enable = FALSE;
19569 + cfg->pause_ignore = FALSE;
19570 + cfg->tx_addr_ins_enable = FALSE;
19571 + cfg->loopback_enable = FALSE;
19572 + cfg->cmd_frame_enable = FALSE;
19573 + cfg->rx_error_discard = FALSE;
19574 + cfg->send_idle_enable = FALSE;
19575 + cfg->no_length_check_enable = TRUE;
19576 + cfg->lgth_check_nostdr = FALSE;
19577 + cfg->time_stamp_enable = FALSE;
19578 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
19579 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
19580 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
19581 + cfg->pad_enable = TRUE;
19582 + cfg->phy_tx_ena_on = FALSE;
19583 + cfg->rx_sfd_any = FALSE;
19584 + cfg->rx_pbl_fwd = FALSE;
19585 + cfg->tx_pbl_fwd = FALSE;
19586 + cfg->debug_mode = FALSE;
19587 + cfg->wake_on_lan = FALSE;
19588 +}
19589 --- /dev/null
19590 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
19591 @@ -0,0 +1,213 @@
19592 +/*
19593 + * Copyright 2008-2013 Freescale Semiconductor Inc.
19594 + *
19595 + * Redistribution and use in source and binary forms, with or without
19596 + * modification, are permitted provided that the following conditions are met:
19597 + * * Redistributions of source code must retain the above copyright
19598 + * notice, this list of conditions and the following disclaimer.
19599 + * * Redistributions in binary form must reproduce the above copyright
19600 + * notice, this list of conditions and the following disclaimer in the
19601 + * documentation and/or other materials provided with the distribution.
19602 + * * Neither the name of Freescale Semiconductor nor the
19603 + * names of its contributors may be used to endorse or promote products
19604 + * derived from this software without specific prior written permission.
19605 + *
19606 + *
19607 + * ALTERNATIVELY, this software may be distributed under the terms of the
19608 + * GNU General Public License ("GPL") as published by the Free Software
19609 + * Foundation, either version 2 of that License or (at your option) any
19610 + * later version.
19611 + *
19612 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19613 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19614 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19615 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19616 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19617 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19618 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19619 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19620 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19621 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19622 + */
19623 +
19624 +
19625 +#include "fsl_fman_memac_mii_acc.h"
19626 +
19627 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19628 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19629 +{
19630 + uint32_t tmp_reg;
19631 +
19632 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19633 + /* Leave only MDIO_CLK_DIV bits set on */
19634 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19635 + /* Set maximum MDIO_HOLD value to allow phy to see
19636 + change of data signal */
19637 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19638 + /* Add 10G interface mode */
19639 + tmp_reg |= MDIO_CFG_ENC45;
19640 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19641 +
19642 + /* Wait for command completion */
19643 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19644 + udelay(1);
19645 +
19646 + /* Specify phy and register to be accessed */
19647 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19648 + iowrite32be(reg, &mii_regs->mdio_addr);
19649 + wmb();
19650 +
19651 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19652 + udelay(1);
19653 +
19654 + /* Write data */
19655 + iowrite32be(data, &mii_regs->mdio_data);
19656 + wmb();
19657 +
19658 + /* Wait for write transaction end */
19659 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19660 + udelay(1);
19661 +}
19662 +
19663 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
19664 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19665 +{
19666 + uint32_t tmp_reg;
19667 +
19668 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19669 + /* Leave only MDIO_CLK_DIV bits set on */
19670 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
19671 + /* Set maximum MDIO_HOLD value to allow phy to see
19672 + change of data signal */
19673 + tmp_reg |= MDIO_CFG_HOLD_MASK;
19674 + /* Add 10G interface mode */
19675 + tmp_reg |= MDIO_CFG_ENC45;
19676 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19677 +
19678 + /* Wait for command completion */
19679 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19680 + udelay(1);
19681 +
19682 + /* Specify phy and register to be accessed */
19683 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
19684 + iowrite32be(reg, &mii_regs->mdio_addr);
19685 + wmb();
19686 +
19687 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19688 + udelay(1);
19689 +
19690 + /* Read cycle */
19691 + tmp_reg = phy_addr;
19692 + tmp_reg |= MDIO_CTL_READ;
19693 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19694 + wmb();
19695 +
19696 + /* Wait for data to be available */
19697 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19698 + udelay(1);
19699 +
19700 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19701 +
19702 + /* Check if there was an error */
19703 + return ioread32be(&mii_regs->mdio_cfg);
19704 +}
19705 +
19706 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19707 + uint8_t phy_addr, uint8_t reg, uint16_t data)
19708 +{
19709 + uint32_t tmp_reg;
19710 +
19711 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19712 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19713 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19714 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19715 +
19716 + /* Wait for command completion */
19717 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19718 + udelay(1);
19719 +
19720 + /* Write transaction */
19721 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19722 + tmp_reg |= reg;
19723 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19724 +
19725 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19726 + udelay(1);
19727 +
19728 + iowrite32be(data, &mii_regs->mdio_data);
19729 +
19730 + wmb();
19731 +
19732 + /* Wait for write transaction to end */
19733 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19734 + udelay(1);
19735 +}
19736 +
19737 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
19738 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
19739 +{
19740 + uint32_t tmp_reg;
19741 +
19742 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
19743 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
19744 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
19745 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
19746 +
19747 + /* Wait for command completion */
19748 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19749 + udelay(1);
19750 +
19751 + /* Read transaction */
19752 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
19753 + tmp_reg |= reg;
19754 + tmp_reg |= MDIO_CTL_READ;
19755 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
19756 +
19757 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
19758 + udelay(1);
19759 +
19760 + /* Wait for data to be available */
19761 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
19762 + udelay(1);
19763 +
19764 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
19765 +
19766 + /* Check error */
19767 + return ioread32be(&mii_regs->mdio_cfg);
19768 +}
19769 +
19770 +/*****************************************************************************/
19771 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19772 + uint8_t phy_addr, uint8_t reg, uint16_t data,
19773 + enum enet_speed enet_speed)
19774 +{
19775 + /* Figure out interface type - 10G vs 1G.
19776 + In 10G interface both phy_addr and devAddr present. */
19777 + if (enet_speed == E_ENET_SPEED_10000)
19778 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
19779 + else
19780 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
19781 +
19782 + return 0;
19783 +}
19784 +
19785 +/*****************************************************************************/
19786 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
19787 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
19788 + enum enet_speed enet_speed)
19789 +{
19790 + uint32_t ans;
19791 + /* Figure out interface type - 10G vs 1G.
19792 + In 10G interface both phy_addr and devAddr present. */
19793 + if (enet_speed == E_ENET_SPEED_10000)
19794 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
19795 + else
19796 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
19797 +
19798 + if (ans & MDIO_CFG_READ_ERR)
19799 + return -EINVAL;
19800 + return 0;
19801 +}
19802 +
19803 +/* ......................................................................... */
19804 +
19805 --- /dev/null
19806 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
19807 @@ -0,0 +1,367 @@
19808 +/*
19809 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19810 + *
19811 + * Redistribution and use in source and binary forms, with or without
19812 + * modification, are permitted provided that the following conditions are met:
19813 + * * Redistributions of source code must retain the above copyright
19814 + * notice, this list of conditions and the following disclaimer.
19815 + * * Redistributions in binary form must reproduce the above copyright
19816 + * notice, this list of conditions and the following disclaimer in the
19817 + * documentation and/or other materials provided with the distribution.
19818 + * * Neither the name of Freescale Semiconductor nor the
19819 + * names of its contributors may be used to endorse or promote products
19820 + * derived from this software without specific prior written permission.
19821 + *
19822 + *
19823 + * ALTERNATIVELY, this software may be distributed under the terms of the
19824 + * GNU General Public License ("GPL") as published by the Free Software
19825 + * Foundation, either version 2 of that License or (at your option) any
19826 + * later version.
19827 + *
19828 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19829 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19830 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19831 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19832 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19833 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19834 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19835 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19836 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19837 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19838 + */
19839 +
19840 +
19841 +#include "fsl_fman_tgec.h"
19842 +
19843 +
19844 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
19845 +{
19846 + uint32_t tmp0, tmp1;
19847 +
19848 + tmp0 = (uint32_t)(adr[0] |
19849 + adr[1] << 8 |
19850 + adr[2] << 16 |
19851 + adr[3] << 24);
19852 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
19853 + iowrite32be(tmp0, &regs->mac_addr_0);
19854 + iowrite32be(tmp1, &regs->mac_addr_1);
19855 +}
19856 +
19857 +void fman_tgec_reset_stat(struct tgec_regs *regs)
19858 +{
19859 + uint32_t tmp;
19860 +
19861 + tmp = ioread32be(&regs->command_config);
19862 +
19863 + tmp |= CMD_CFG_STAT_CLR;
19864 +
19865 + iowrite32be(tmp, &regs->command_config);
19866 +
19867 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
19868 +}
19869 +
19870 +#define GET_TGEC_CNTR_64(bn) \
19871 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
19872 + ioread32be(&regs->bn ## _l))
19873 +
19874 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
19875 +{
19876 + uint64_t ret_val;
19877 +
19878 + switch (reg_name) {
19879 + case E_TGEC_COUNTER_R64:
19880 + ret_val = GET_TGEC_CNTR_64(r64);
19881 + break;
19882 + case E_TGEC_COUNTER_R127:
19883 + ret_val = GET_TGEC_CNTR_64(r127);
19884 + break;
19885 + case E_TGEC_COUNTER_R255:
19886 + ret_val = GET_TGEC_CNTR_64(r255);
19887 + break;
19888 + case E_TGEC_COUNTER_R511:
19889 + ret_val = GET_TGEC_CNTR_64(r511);
19890 + break;
19891 + case E_TGEC_COUNTER_R1023:
19892 + ret_val = GET_TGEC_CNTR_64(r1023);
19893 + break;
19894 + case E_TGEC_COUNTER_R1518:
19895 + ret_val = GET_TGEC_CNTR_64(r1518);
19896 + break;
19897 + case E_TGEC_COUNTER_R1519X:
19898 + ret_val = GET_TGEC_CNTR_64(r1519x);
19899 + break;
19900 + case E_TGEC_COUNTER_TRFRG:
19901 + ret_val = GET_TGEC_CNTR_64(trfrg);
19902 + break;
19903 + case E_TGEC_COUNTER_TRJBR:
19904 + ret_val = GET_TGEC_CNTR_64(trjbr);
19905 + break;
19906 + case E_TGEC_COUNTER_RDRP:
19907 + ret_val = GET_TGEC_CNTR_64(rdrp);
19908 + break;
19909 + case E_TGEC_COUNTER_RALN:
19910 + ret_val = GET_TGEC_CNTR_64(raln);
19911 + break;
19912 + case E_TGEC_COUNTER_TRUND:
19913 + ret_val = GET_TGEC_CNTR_64(trund);
19914 + break;
19915 + case E_TGEC_COUNTER_TROVR:
19916 + ret_val = GET_TGEC_CNTR_64(trovr);
19917 + break;
19918 + case E_TGEC_COUNTER_RXPF:
19919 + ret_val = GET_TGEC_CNTR_64(rxpf);
19920 + break;
19921 + case E_TGEC_COUNTER_TXPF:
19922 + ret_val = GET_TGEC_CNTR_64(txpf);
19923 + break;
19924 + case E_TGEC_COUNTER_ROCT:
19925 + ret_val = GET_TGEC_CNTR_64(roct);
19926 + break;
19927 + case E_TGEC_COUNTER_RMCA:
19928 + ret_val = GET_TGEC_CNTR_64(rmca);
19929 + break;
19930 + case E_TGEC_COUNTER_RBCA:
19931 + ret_val = GET_TGEC_CNTR_64(rbca);
19932 + break;
19933 + case E_TGEC_COUNTER_RPKT:
19934 + ret_val = GET_TGEC_CNTR_64(rpkt);
19935 + break;
19936 + case E_TGEC_COUNTER_RUCA:
19937 + ret_val = GET_TGEC_CNTR_64(ruca);
19938 + break;
19939 + case E_TGEC_COUNTER_RERR:
19940 + ret_val = GET_TGEC_CNTR_64(rerr);
19941 + break;
19942 + case E_TGEC_COUNTER_TOCT:
19943 + ret_val = GET_TGEC_CNTR_64(toct);
19944 + break;
19945 + case E_TGEC_COUNTER_TMCA:
19946 + ret_val = GET_TGEC_CNTR_64(tmca);
19947 + break;
19948 + case E_TGEC_COUNTER_TBCA:
19949 + ret_val = GET_TGEC_CNTR_64(tbca);
19950 + break;
19951 + case E_TGEC_COUNTER_TUCA:
19952 + ret_val = GET_TGEC_CNTR_64(tuca);
19953 + break;
19954 + case E_TGEC_COUNTER_TERR:
19955 + ret_val = GET_TGEC_CNTR_64(terr);
19956 + break;
19957 + default:
19958 + ret_val = 0;
19959 + }
19960 +
19961 + return ret_val;
19962 +}
19963 +
19964 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19965 +{
19966 + uint32_t tmp;
19967 +
19968 + tmp = ioread32be(&regs->command_config);
19969 + if (apply_rx)
19970 + tmp |= CMD_CFG_RX_EN;
19971 + if (apply_tx)
19972 + tmp |= CMD_CFG_TX_EN;
19973 + iowrite32be(tmp, &regs->command_config);
19974 +}
19975 +
19976 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
19977 +{
19978 + uint32_t tmp_reg_32;
19979 +
19980 + tmp_reg_32 = ioread32be(&regs->command_config);
19981 + if (apply_rx)
19982 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
19983 + if (apply_tx)
19984 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
19985 + iowrite32be(tmp_reg_32, &regs->command_config);
19986 +}
19987 +
19988 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
19989 +{
19990 + uint32_t tmp;
19991 +
19992 + tmp = ioread32be(&regs->command_config);
19993 + if (val)
19994 + tmp |= CMD_CFG_PROMIS_EN;
19995 + else
19996 + tmp &= ~CMD_CFG_PROMIS_EN;
19997 + iowrite32be(tmp, &regs->command_config);
19998 +}
19999 +
20000 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
20001 +{
20002 + uint32_t i;
20003 + for (i = 0; i < 512; i++)
20004 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
20005 +}
20006 +
20007 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
20008 +{
20009 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
20010 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
20011 +}
20012 +
20013 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
20014 +{
20015 + iowrite32be(value, &regs->hashtable_ctrl);
20016 +}
20017 +
20018 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
20019 +{
20020 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
20021 +}
20022 +
20023 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
20024 +{
20025 + uint32_t tmp;
20026 +
20027 + tmp = ioread32be(&regs->command_config);
20028 + if (en)
20029 + tmp |= CMD_CFG_PAUSE_IGNORE;
20030 + else
20031 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
20032 + iowrite32be(tmp, &regs->command_config);
20033 +}
20034 +
20035 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
20036 +{
20037 + uint32_t tmp;
20038 +
20039 + tmp = ioread32be(&regs->command_config);
20040 + if (en)
20041 + tmp |= CMD_CFG_EN_TIMESTAMP;
20042 + else
20043 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
20044 + iowrite32be(tmp, &regs->command_config);
20045 +}
20046 +
20047 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
20048 +{
20049 + return ioread32be(&regs->ievent) & ev_mask;
20050 +}
20051 +
20052 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
20053 +{
20054 + iowrite32be(ev_mask, &regs->ievent);
20055 +}
20056 +
20057 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
20058 +{
20059 + return ioread32be(&regs->imask);
20060 +}
20061 +
20062 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
20063 +{
20064 + uint32_t tmp0, tmp1;
20065 +
20066 + tmp0 = (uint32_t)(adr[0] |
20067 + adr[1] << 8 |
20068 + adr[2] << 16 |
20069 + adr[3] << 24);
20070 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
20071 + iowrite32be(tmp0, &regs->mac_addr_2);
20072 + iowrite32be(tmp1, &regs->mac_addr_3);
20073 +}
20074 +
20075 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
20076 +{
20077 + iowrite32be(0, &regs->mac_addr_2);
20078 + iowrite32be(0, &regs->mac_addr_3);
20079 +}
20080 +
20081 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
20082 +{
20083 + return ioread32be(&regs->tgec_id);
20084 +}
20085 +
20086 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
20087 +{
20088 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
20089 +}
20090 +
20091 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
20092 +{
20093 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
20094 +}
20095 +
20096 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
20097 +{
20098 + return (uint16_t) ioread32be(&regs->maxfrm);
20099 +}
20100 +
20101 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
20102 +{
20103 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
20104 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
20105 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
20106 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
20107 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
20108 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
20109 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
20110 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
20111 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
20112 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
20113 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
20114 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
20115 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
20116 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
20117 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
20118 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
20119 + cfg->skip_fman11_workaround = FALSE;
20120 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
20121 +}
20122 +
20123 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
20124 + uint32_t exception_mask)
20125 +{
20126 + uint32_t tmp;
20127 +
20128 + /* Config */
20129 + tmp = 0x40; /* CRC forward */
20130 + if (cfg->wan_mode_enable)
20131 + tmp |= CMD_CFG_WAN_MODE;
20132 + if (cfg->promiscuous_mode_enable)
20133 + tmp |= CMD_CFG_PROMIS_EN;
20134 + if (cfg->pause_forward_enable)
20135 + tmp |= CMD_CFG_PAUSE_FWD;
20136 + if (cfg->pause_ignore)
20137 + tmp |= CMD_CFG_PAUSE_IGNORE;
20138 + if (cfg->tx_addr_ins_enable)
20139 + tmp |= CMD_CFG_TX_ADDR_INS;
20140 + if (cfg->loopback_enable)
20141 + tmp |= CMD_CFG_LOOPBACK_EN;
20142 + if (cfg->cmd_frame_enable)
20143 + tmp |= CMD_CFG_CMD_FRM_EN;
20144 + if (cfg->rx_error_discard)
20145 + tmp |= CMD_CFG_RX_ER_DISC;
20146 + if (cfg->send_idle_enable)
20147 + tmp |= CMD_CFG_SEND_IDLE;
20148 + if (cfg->no_length_check_enable)
20149 + tmp |= CMD_CFG_NO_LEN_CHK;
20150 + if (cfg->time_stamp_enable)
20151 + tmp |= CMD_CFG_EN_TIMESTAMP;
20152 + iowrite32be(tmp, &regs->command_config);
20153 +
20154 + /* Max Frame Length */
20155 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
20156 + /* Pause Time */
20157 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
20158 +
20159 + /* clear all pending events and set-up interrupts */
20160 + fman_tgec_ack_event(regs, 0xffffffff);
20161 + fman_tgec_enable_interrupt(regs, exception_mask);
20162 +
20163 + return 0;
20164 +}
20165 +
20166 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
20167 +{
20168 + uint32_t tmp;
20169 +
20170 + /* restore the default tx ipg Length */
20171 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
20172 +
20173 + iowrite32be(tmp, &regs->tx_ipg_len);
20174 +}
20175 --- /dev/null
20176 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
20177 @@ -0,0 +1,1153 @@
20178 +/*
20179 + * Copyright 2008-2012 Freescale Semiconductor Inc.
20180 + *
20181 + * Redistribution and use in source and binary forms, with or without
20182 + * modification, are permitted provided that the following conditions are met:
20183 + * * Redistributions of source code must retain the above copyright
20184 + * notice, this list of conditions and the following disclaimer.
20185 + * * Redistributions in binary form must reproduce the above copyright
20186 + * notice, this list of conditions and the following disclaimer in the
20187 + * documentation and/or other materials provided with the distribution.
20188 + * * Neither the name of Freescale Semiconductor nor the
20189 + * names of its contributors may be used to endorse or promote products
20190 + * derived from this software without specific prior written permission.
20191 + *
20192 + *
20193 + * ALTERNATIVELY, this software may be distributed under the terms of the
20194 + * GNU General Public License ("GPL") as published by the Free Software
20195 + * Foundation, either version 2 of that License or (at your option) any
20196 + * later version.
20197 + *
20198 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20199 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20200 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20201 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20202 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20203 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20204 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20205 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20206 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20207 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20208 + */
20209 +
20210 +
20211 +/******************************************************************************
20212 + @File memac.c
20213 +
20214 + @Description FM mEMAC driver
20215 +*//***************************************************************************/
20216 +
20217 +#include "std_ext.h"
20218 +#include "string_ext.h"
20219 +#include "error_ext.h"
20220 +#include "xx_ext.h"
20221 +#include "endian_ext.h"
20222 +#include "debug_ext.h"
20223 +
20224 +#include "fm_common.h"
20225 +#include "memac.h"
20226 +
20227 +
20228 +/*****************************************************************************/
20229 +/* Internal routines */
20230 +/*****************************************************************************/
20231 +
20232 +/* ......................................................................... */
20233 +
20234 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
20235 +{
20236 + uint64_t mask1, mask2;
20237 + uint32_t xorVal = 0;
20238 + uint8_t i, j;
20239 +
20240 + for (i=0; i<6; i++)
20241 + {
20242 + mask1 = ethAddr & (uint64_t)0x01;
20243 + ethAddr >>= 1;
20244 +
20245 + for (j=0; j<7; j++)
20246 + {
20247 + mask2 = ethAddr & (uint64_t)0x01;
20248 + mask1 ^= mask2;
20249 + ethAddr >>= 1;
20250 + }
20251 +
20252 + xorVal |= (mask1 << (5-i));
20253 + }
20254 +
20255 + return xorVal;
20256 +}
20257 +
20258 +/* ......................................................................... */
20259 +
20260 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
20261 +{
20262 + uint16_t tmpReg16;
20263 + e_EnetMode enetMode;
20264 +
20265 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20266 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20267 + to 1G one, so MII functions can work correctly. */
20268 + enetMode = p_Memac->enetMode;
20269 +
20270 + /* SGMII mode + AN enable */
20271 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
20272 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
20273 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
20274 +
20275 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20276 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20277 +
20278 + /* Device ability according to SGMII specification */
20279 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
20280 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20281 +
20282 + /* Adjust link timer for SGMII -
20283 + According to Cisco SGMII specification the timer should be 1.6 ms.
20284 + The link_timer register is configured in units of the clock.
20285 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20286 + unit = 1 / (125*10^6 Hz) = 8 ns.
20287 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
20288 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20289 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20290 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
20291 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20292 + we always set up here a value of 2.5 SGMII. */
20293 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
20294 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
20295 +
20296 + /* Restart AN */
20297 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20298 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20299 +
20300 + /* Restore original enet mode */
20301 + p_Memac->enetMode = enetMode;
20302 +}
20303 +
20304 +/* ......................................................................... */
20305 +
20306 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
20307 +{
20308 + uint16_t tmpReg16;
20309 + e_EnetMode enetMode;
20310 +
20311 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
20312 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
20313 + to 1G one, so MII functions can work correctly. */
20314 + enetMode = p_Memac->enetMode;
20315 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
20316 +
20317 + /* 1000BaseX mode */
20318 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
20319 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
20320 +
20321 + /* AN Device capability */
20322 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
20323 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
20324 +
20325 + /* Adjust link timer for SGMII -
20326 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
20327 + The link_timer register is configured in units of the clock.
20328 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
20329 + unit = 1 / (125*10^6 Hz) = 8 ns.
20330 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
20331 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
20332 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
20333 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
20334 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
20335 + we always set up here a value of 2.5 SGMII. */
20336 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
20337 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
20338 +
20339 + /* Restart AN */
20340 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
20341 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
20342 +
20343 + /* Restore original enet mode */
20344 + p_Memac->enetMode = enetMode;
20345 +}
20346 +
20347 +/* ......................................................................... */
20348 +
20349 +static t_Error CheckInitParameters(t_Memac *p_Memac)
20350 +{
20351 + e_FmMacType portType;
20352 +
20353 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20354 +
20355 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
20356 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
20357 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
20358 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
20359 +
20360 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
20361 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
20362 + if (p_Memac->addr == 0)
20363 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
20364 + if (!p_Memac->f_Exception)
20365 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
20366 + if (!p_Memac->f_Event)
20367 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
20368 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
20369 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
20370 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
20371 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
20372 +
20373 + return E_OK;
20374 +}
20375 +
20376 +/* ........................................................................... */
20377 +
20378 +static void MemacErrException(t_Handle h_Memac)
20379 +{
20380 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20381 + uint32_t event, imask;
20382 +
20383 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20384 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20385 +
20386 + /* Imask include both error and notification/event bits.
20387 + Leaving only error bits enabled by imask.
20388 + The imask error bits are shifted by 16 bits offset from
20389 + their corresponding location in the ievent - hence the >> 16 */
20390 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20391 +
20392 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20393 +
20394 + if (event & MEMAC_IEVNT_TS_ECC_ER)
20395 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
20396 + if (event & MEMAC_IEVNT_TX_ECC_ER)
20397 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
20398 + if (event & MEMAC_IEVNT_RX_ECC_ER)
20399 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
20400 +}
20401 +
20402 +static void MemacException(t_Handle h_Memac)
20403 +{
20404 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20405 + uint32_t event, imask;
20406 +
20407 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
20408 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
20409 +
20410 + /* Imask include both error and notification/event bits.
20411 + Leaving only error bits enabled by imask.
20412 + The imask error bits are shifted by 16 bits offset from
20413 + their corresponding location in the ievent - hence the >> 16 */
20414 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
20415 +
20416 + fman_memac_ack_event(p_Memac->p_MemMap, event);
20417 +
20418 + if (event & MEMAC_IEVNT_MGI)
20419 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
20420 +}
20421 +
20422 +/* ......................................................................... */
20423 +
20424 +static void FreeInitResources(t_Memac *p_Memac)
20425 +{
20426 + e_FmMacType portType;
20427 +
20428 + portType =
20429 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
20430 +
20431 + if (portType == e_FM_MAC_10G)
20432 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20433 + else
20434 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
20435 +
20436 + /* release the driver's group hash table */
20437 + FreeHashTable(p_Memac->p_MulticastAddrHash);
20438 + p_Memac->p_MulticastAddrHash = NULL;
20439 +
20440 + /* release the driver's individual hash table */
20441 + FreeHashTable(p_Memac->p_UnicastAddrHash);
20442 + p_Memac->p_UnicastAddrHash = NULL;
20443 +}
20444 +
20445 +
20446 +/*****************************************************************************/
20447 +/* mEMAC API routines */
20448 +/*****************************************************************************/
20449 +
20450 +/* ......................................................................... */
20451 +
20452 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
20453 +{
20454 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20455 +
20456 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20457 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20458 +
20459 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20460 +
20461 + return E_OK;
20462 +}
20463 +
20464 +/* ......................................................................... */
20465 +
20466 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
20467 +{
20468 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20469 +
20470 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20471 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20472 +
20473 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
20474 +
20475 + return E_OK;
20476 +}
20477 +
20478 +/* ......................................................................... */
20479 +
20480 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
20481 +{
20482 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20483 +
20484 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20485 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20486 +
20487 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
20488 +
20489 + return E_OK;
20490 +}
20491 +
20492 +/* .............................................................................. */
20493 +
20494 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
20495 +{
20496 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20497 +
20498 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20499 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20500 +
20501 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
20502 + RETURN_ERROR(MAJOR, E_CONFLICT,
20503 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
20504 +
20505 + fman_memac_adjust_link(p_Memac->p_MemMap,
20506 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
20507 + (enum enet_speed)speed,
20508 + fullDuplex);
20509 + return E_OK;
20510 +}
20511 +
20512 +
20513 +/*****************************************************************************/
20514 +/* Memac Configs modification functions */
20515 +/*****************************************************************************/
20516 +
20517 +/* ......................................................................... */
20518 +
20519 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
20520 +{
20521 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20522 +
20523 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20524 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20525 +
20526 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
20527 +
20528 + return E_OK;
20529 +}
20530 +
20531 +/* ......................................................................... */
20532 +
20533 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
20534 +{
20535 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20536 +
20537 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20538 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20539 +
20540 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
20541 +
20542 + return E_OK;
20543 +}
20544 +
20545 +/* ......................................................................... */
20546 +
20547 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
20548 +{
20549 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20550 +
20551 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20552 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20553 +
20554 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
20555 +
20556 + return E_OK;
20557 +}
20558 +
20559 +/* ......................................................................... */
20560 +
20561 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
20562 +{
20563 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20564 +
20565 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20566 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20567 +
20568 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
20569 +
20570 + return E_OK;
20571 +}
20572 +
20573 +/* ......................................................................... */
20574 +
20575 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
20576 +{
20577 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20578 +
20579 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20580 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20581 +
20582 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
20583 +
20584 + return E_OK;
20585 +}
20586 +
20587 +/* ......................................................................... */
20588 +
20589 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
20590 +{
20591 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20592 + uint32_t bitMask = 0;
20593 +
20594 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20595 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20596 +
20597 + GET_EXCEPTION_FLAG(bitMask, exception);
20598 + if (bitMask)
20599 + {
20600 + if (enable)
20601 + p_Memac->exceptions |= bitMask;
20602 + else
20603 + p_Memac->exceptions &= ~bitMask;
20604 + }
20605 + else
20606 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
20607 +
20608 + return E_OK;
20609 +}
20610 +
20611 +/* ......................................................................... */
20612 +
20613 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
20614 +{
20615 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20616 +
20617 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20618 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20619 +
20620 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
20621 +
20622 + return E_OK;
20623 +}
20624 +
20625 +
20626 +/*****************************************************************************/
20627 +/* Memac Run Time API functions */
20628 +/*****************************************************************************/
20629 +
20630 +/* ......................................................................... */
20631 +
20632 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
20633 + uint8_t priority,
20634 + uint16_t pauseTime,
20635 + uint16_t threshTime)
20636 +{
20637 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20638 +
20639 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20640 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20641 +
20642 + if (priority != 0xFF)
20643 + {
20644 + bool PortConfigured, PreFetchEnabled;
20645 +
20646 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
20647 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
20648 +
20649 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
20650 + p_Memac->fmMacControllerDriver.macId,
20651 + &PortConfigured,
20652 + &PreFetchEnabled);
20653 +
20654 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
20655 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20656 +
20657 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
20658 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
20659 + }
20660 +
20661 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
20662 +
20663 + return E_OK;
20664 +}
20665 +
20666 +/* ......................................................................... */
20667 +
20668 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
20669 + uint16_t pauseTime)
20670 +{
20671 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
20672 +}
20673 +
20674 +/* ......................................................................... */
20675 +
20676 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
20677 +{
20678 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20679 +
20680 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20681 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20682 +
20683 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
20684 +
20685 + return E_OK;
20686 +}
20687 +
20688 +/* ......................................................................... */
20689 +
20690 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
20691 +{
20692 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20693 +
20694 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
20695 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20696 +
20697 + fman_memac_set_wol(p_Memac->p_MemMap, en);
20698 +
20699 + return E_OK;
20700 +}
20701 +
20702 +/* .............................................................................. */
20703 +
20704 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
20705 +{
20706 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20707 +
20708 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20709 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20710 +UNUSED(p_Memac);
20711 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
20712 +
20713 + return E_OK;
20714 +}
20715 +
20716 +/* Counters handling */
20717 +/* ......................................................................... */
20718 +
20719 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
20720 +{
20721 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20722 +
20723 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20724 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20725 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
20726 +
20727 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20728 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20729 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20730 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20731 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20732 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20733 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20734 +/* */
20735 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
20736 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
20737 +
20738 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
20739 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
20740 +
20741 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
20742 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
20743 +/* Pause */
20744 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
20745 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
20746 +
20747 +/* MIB II */
20748 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
20749 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
20750 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
20751 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
20752 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
20753 + + p_Statistics->ifInMcastPkts
20754 + + p_Statistics->ifInBcastPkts;
20755 + p_Statistics->ifInDiscards = 0;
20756 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
20757 +
20758 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
20759 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
20760 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
20761 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
20762 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
20763 + + p_Statistics->ifOutMcastPkts
20764 + + p_Statistics->ifOutBcastPkts;
20765 + p_Statistics->ifOutDiscards = 0;
20766 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
20767 +
20768 + return E_OK;
20769 +}
20770 +
20771 +/* ......................................................................... */
20772 +
20773 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
20774 +{
20775 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20776 +
20777 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20778 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20779 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
20780 +
20781 + switch (type)
20782 + {
20783 + case e_COMM_MODE_NONE:
20784 + break;
20785 +
20786 + case e_COMM_MODE_RX:
20787 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
20788 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
20789 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
20790 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
20791 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
20792 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
20793 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
20794 + break;
20795 +
20796 + case e_COMM_MODE_TX:
20797 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20798 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20799 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20800 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20801 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20802 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20803 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20804 + break;
20805 +
20806 + case e_COMM_MODE_RX_AND_TX:
20807 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
20808 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
20809 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
20810 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
20811 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
20812 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
20813 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
20814 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
20815 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
20816 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
20817 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
20818 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
20819 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
20820 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
20821 + break;
20822 + }
20823 +
20824 + return E_OK;
20825 +}
20826 +
20827 +/* ......................................................................... */
20828 +
20829 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
20830 +{
20831 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20832 +
20833 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20834 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20835 +
20836 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
20837 +
20838 + return E_OK;
20839 +}
20840 +
20841 +/* ......................................................................... */
20842 +
20843 +static t_Error MemacResetCounters (t_Handle h_Memac)
20844 +{
20845 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20846 +
20847 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20848 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20849 +
20850 + fman_memac_reset_stat(p_Memac->p_MemMap);
20851 +
20852 + return E_OK;
20853 +}
20854 +
20855 +/* ......................................................................... */
20856 +
20857 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20858 +{
20859 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20860 + uint64_t ethAddr;
20861 + uint8_t paddrNum;
20862 +
20863 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20864 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20865 +
20866 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20867 +
20868 + if (ethAddr & GROUP_ADDRESS)
20869 + /* Multicast address has no effect in PADDR */
20870 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
20871 +
20872 + /* Make sure no PADDR contains this address */
20873 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20874 + if (p_Memac->indAddrRegUsed[paddrNum])
20875 + if (p_Memac->paddr[paddrNum] == ethAddr)
20876 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
20877 +
20878 + /* Find first unused PADDR */
20879 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20880 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
20881 + {
20882 + /* mark this PADDR as used */
20883 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
20884 + /* store address */
20885 + p_Memac->paddr[paddrNum] = ethAddr;
20886 +
20887 + /* put in hardware */
20888 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
20889 + p_Memac->numOfIndAddrInRegs++;
20890 +
20891 + return E_OK;
20892 + }
20893 +
20894 + /* No free PADDR */
20895 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
20896 +}
20897 +
20898 +/* ......................................................................... */
20899 +
20900 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20901 +{
20902 + t_Memac *p_Memac = (t_Memac *) h_Memac;
20903 + uint64_t ethAddr;
20904 + uint8_t paddrNum;
20905 +
20906 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20907 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20908 +
20909 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20910 +
20911 + /* Find used PADDR containing this address */
20912 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
20913 + {
20914 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
20915 + (p_Memac->paddr[paddrNum] == ethAddr))
20916 + {
20917 + /* mark this PADDR as not used */
20918 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
20919 + /* clear in hardware */
20920 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
20921 + p_Memac->numOfIndAddrInRegs--;
20922 +
20923 + return E_OK;
20924 + }
20925 + }
20926 +
20927 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
20928 +}
20929 +
20930 +/* ......................................................................... */
20931 +
20932 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
20933 +{
20934 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20935 +
20936 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
20937 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20938 +
20939 + *macId = p_Memac->macId;
20940 +
20941 + return E_OK;
20942 +}
20943 +
20944 +/* ......................................................................... */
20945 +
20946 +
20947 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20948 +{
20949 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20950 + t_EthHashEntry *p_HashEntry;
20951 + uint32_t hash;
20952 + uint64_t ethAddr;
20953 +
20954 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20955 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20956 +
20957 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20958 +
20959 + if (!(ethAddr & GROUP_ADDRESS))
20960 + /* Unicast addresses not supported in hash */
20961 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
20962 +
20963 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20964 +
20965 + /* Create element to be added to the driver hash table */
20966 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
20967 + p_HashEntry->addr = ethAddr;
20968 + INIT_LIST(&p_HashEntry->node);
20969 +
20970 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
20971 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
20972 +
20973 + return E_OK;
20974 +}
20975 +
20976 +/* ......................................................................... */
20977 +
20978 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
20979 +{
20980 + t_Memac *p_Memac = (t_Memac *)h_Memac;
20981 + t_EthHashEntry *p_HashEntry = NULL;
20982 + t_List *p_Pos;
20983 + uint32_t hash;
20984 + uint64_t ethAddr;
20985 +
20986 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
20987 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
20988 +
20989 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
20990 +
20991 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
20992 +
20993 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
20994 + {
20995 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
20996 + if (p_HashEntry->addr == ethAddr)
20997 + {
20998 + LIST_DelAndInit(&p_HashEntry->node);
20999 + XX_Free(p_HashEntry);
21000 + break;
21001 + }
21002 + }
21003 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
21004 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
21005 +
21006 + return E_OK;
21007 +}
21008 +
21009 +
21010 +/* ......................................................................... */
21011 +
21012 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
21013 +{
21014 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21015 + uint32_t bitMask = 0;
21016 +
21017 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21018 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21019 +
21020 + GET_EXCEPTION_FLAG(bitMask, exception);
21021 + if (bitMask)
21022 + {
21023 + if (enable)
21024 + p_Memac->exceptions |= bitMask;
21025 + else
21026 + p_Memac->exceptions &= ~bitMask;
21027 + }
21028 + else
21029 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21030 +
21031 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
21032 +
21033 + return E_OK;
21034 +}
21035 +
21036 +/* ......................................................................... */
21037 +
21038 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
21039 +{
21040 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21041 +
21042 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
21043 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
21044 +
21045 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
21046 +}
21047 +
21048 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
21049 +{
21050 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21051 + uint8_t i, phyAddr;
21052 +
21053 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
21054 + {
21055 + /* Configure internal SGMII PHY */
21056 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
21057 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
21058 + else
21059 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
21060 + }
21061 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
21062 + {
21063 + /* Configure 4 internal SGMII PHYs */
21064 + for (i = 0; i < 4; i++)
21065 + {
21066 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
21067 + phyAddress; the lower 2 bits are used to extend
21068 + register address space and access each one of 4
21069 + ports inside QSGMII. */
21070 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
21071 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
21072 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
21073 + else
21074 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
21075 + }
21076 + }
21077 + return E_OK;
21078 +}
21079 +
21080 +/*****************************************************************************/
21081 +/* mEMAC Init & Free API */
21082 +/*****************************************************************************/
21083 +
21084 +/* ......................................................................... */
21085 +void *g_MemacRegs;
21086 +static t_Error MemacInit(t_Handle h_Memac)
21087 +{
21088 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21089 + struct memac_cfg *p_MemacDriverParam;
21090 + enum enet_interface enet_interface;
21091 + enum enet_speed enet_speed;
21092 + t_EnetAddr ethAddr;
21093 + e_FmMacType portType;
21094 + t_Error err;
21095 + bool slow_10g_if = FALSE;
21096 + if (p_Memac->macId == 3) /* This is a quick WA */
21097 + g_MemacRegs = p_Memac->p_MemMap;
21098 +
21099 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21100 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
21101 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
21102 +
21103 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
21104 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
21105 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
21106 + slow_10g_if = TRUE;
21107 +
21108 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
21109 +
21110 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
21111 +
21112 + portType =
21113 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
21114 +
21115 + /* First, reset the MAC if desired. */
21116 + if (p_MemacDriverParam->reset_on_init)
21117 + fman_memac_reset(p_Memac->p_MemMap);
21118 +
21119 + /* MAC Address */
21120 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
21121 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
21122 +
21123 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
21124 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
21125 +
21126 + fman_memac_init(p_Memac->p_MemMap,
21127 + p_Memac->p_MemacDriverParam,
21128 + enet_interface,
21129 + enet_speed,
21130 + slow_10g_if,
21131 + p_Memac->exceptions);
21132 +
21133 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
21134 + {
21135 + uint32_t tmpReg = 0;
21136 +
21137 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
21138 + /* check the FMAN version - the bug exists only in rev1 */
21139 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
21140 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
21141 + {
21142 + /* MAC strips CRC from received frames - this workaround should
21143 + decrease the likelihood of bug appearance
21144 + */
21145 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
21146 + tmpReg &= ~CMD_CFG_CRC_FWD;
21147 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
21148 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
21149 + }
21150 + }
21151 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
21152 +
21153 + MemacInitInternalPhy(h_Memac);
21154 +
21155 + /* Max Frame Length */
21156 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
21157 + portType,
21158 + p_Memac->fmMacControllerDriver.macId,
21159 + p_MemacDriverParam->max_frame_length);
21160 + if (err)
21161 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
21162 +
21163 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
21164 + if (!p_Memac->p_MulticastAddrHash)
21165 + {
21166 + FreeInitResources(p_Memac);
21167 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
21168 + }
21169 +
21170 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
21171 + if (!p_Memac->p_UnicastAddrHash)
21172 + {
21173 + FreeInitResources(p_Memac);
21174 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
21175 + }
21176 +
21177 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
21178 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
21179 + p_Memac->macId,
21180 + e_FM_INTR_TYPE_ERR,
21181 + MemacErrException,
21182 + p_Memac);
21183 +
21184 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
21185 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
21186 + p_Memac->macId,
21187 + e_FM_INTR_TYPE_NORMAL,
21188 + MemacException,
21189 + p_Memac);
21190 +
21191 + XX_Free(p_MemacDriverParam);
21192 + p_Memac->p_MemacDriverParam = NULL;
21193 +
21194 + return E_OK;
21195 +}
21196 +
21197 +/* ......................................................................... */
21198 +
21199 +static t_Error MemacFree(t_Handle h_Memac)
21200 +{
21201 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21202 +
21203 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21204 +
21205 + if (p_Memac->p_MemacDriverParam)
21206 + {
21207 + /* Called after config */
21208 + XX_Free(p_Memac->p_MemacDriverParam);
21209 + p_Memac->p_MemacDriverParam = NULL;
21210 + }
21211 + else
21212 + /* Called after init */
21213 + FreeInitResources(p_Memac);
21214 +
21215 + XX_Free(p_Memac);
21216 +
21217 + return E_OK;
21218 +}
21219 +
21220 +/* ......................................................................... */
21221 +
21222 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
21223 +{
21224 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
21225 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
21226 +
21227 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
21228 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
21229 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
21230 +
21231 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
21232 +
21233 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
21234 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
21235 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
21236 +
21237 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
21238 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
21239 +
21240 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
21241 +
21242 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
21243 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
21244 +
21245 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
21246 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
21247 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
21248 +
21249 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
21250 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
21251 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
21252 +
21253 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
21254 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
21255 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
21256 +
21257 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
21258 +
21259 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
21260 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
21261 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
21262 +
21263 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
21264 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
21265 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
21266 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
21267 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
21268 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
21269 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
21270 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
21271 +
21272 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
21273 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
21274 +}
21275 +
21276 +
21277 +/*****************************************************************************/
21278 +/* mEMAC Config Main Entry */
21279 +/*****************************************************************************/
21280 +
21281 +/* ......................................................................... */
21282 +
21283 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
21284 +{
21285 + t_Memac *p_Memac;
21286 + struct memac_cfg *p_MemacDriverParam;
21287 + uintptr_t baseAddr;
21288 +
21289 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
21290 +
21291 + baseAddr = p_FmMacParam->baseAddr;
21292 + /* Allocate memory for the mEMAC data structure */
21293 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
21294 + if (!p_Memac)
21295 + {
21296 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
21297 + return NULL;
21298 + }
21299 + memset(p_Memac, 0, sizeof(t_Memac));
21300 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
21301 +
21302 + /* Allocate memory for the mEMAC driver parameters data structure */
21303 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
21304 + if (!p_MemacDriverParam)
21305 + {
21306 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
21307 + XX_Free(p_Memac);
21308 + return NULL;
21309 + }
21310 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
21311 +
21312 + /* Plant parameter structure pointer */
21313 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
21314 +
21315 + fman_memac_defconfig(p_MemacDriverParam);
21316 +
21317 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
21318 +
21319 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
21320 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
21321 +
21322 + p_Memac->enetMode = p_FmMacParam->enetMode;
21323 + p_Memac->macId = p_FmMacParam->macId;
21324 + p_Memac->exceptions = MEMAC_default_exceptions;
21325 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
21326 + p_Memac->f_Event = p_FmMacParam->f_Event;
21327 + p_Memac->h_App = p_FmMacParam->h_App;
21328 +
21329 + return p_Memac;
21330 +}
21331 --- /dev/null
21332 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
21333 @@ -0,0 +1,110 @@
21334 +/*
21335 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21336 + *
21337 + * Redistribution and use in source and binary forms, with or without
21338 + * modification, are permitted provided that the following conditions are met:
21339 + * * Redistributions of source code must retain the above copyright
21340 + * notice, this list of conditions and the following disclaimer.
21341 + * * Redistributions in binary form must reproduce the above copyright
21342 + * notice, this list of conditions and the following disclaimer in the
21343 + * documentation and/or other materials provided with the distribution.
21344 + * * Neither the name of Freescale Semiconductor nor the
21345 + * names of its contributors may be used to endorse or promote products
21346 + * derived from this software without specific prior written permission.
21347 + *
21348 + *
21349 + * ALTERNATIVELY, this software may be distributed under the terms of the
21350 + * GNU General Public License ("GPL") as published by the Free Software
21351 + * Foundation, either version 2 of that License or (at your option) any
21352 + * later version.
21353 + *
21354 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21355 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21356 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21357 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21358 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21359 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21360 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21361 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21362 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21363 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21364 + */
21365 +
21366 +
21367 +/******************************************************************************
21368 + @File memac.h
21369 +
21370 + @Description FM Multirate Ethernet MAC (mEMAC)
21371 +*//***************************************************************************/
21372 +#ifndef __MEMAC_H
21373 +#define __MEMAC_H
21374 +
21375 +#include "std_ext.h"
21376 +#include "error_ext.h"
21377 +#include "list_ext.h"
21378 +
21379 +#include "fsl_fman_memac_mii_acc.h"
21380 +#include "fm_mac.h"
21381 +#include "fsl_fman_memac.h"
21382 +
21383 +
21384 +#define MEMAC_default_exceptions \
21385 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
21386 +
21387 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
21388 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
21389 + bitMask = MEMAC_IMASK_TECC_ER; break; \
21390 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
21391 + bitMask = MEMAC_IMASK_RECC_ER; break; \
21392 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
21393 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
21394 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
21395 + bitMask = MEMAC_IMASK_MGI; break; \
21396 + default: bitMask = 0;break;}
21397 +
21398 +
21399 +typedef struct
21400 +{
21401 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
21402 + t_Handle h_App; /**< Handle to the upper layer application */
21403 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
21404 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
21405 + uint64_t addr; /**< MAC address of device */
21406 + e_EnetMode enetMode; /**< Ethernet physical interface */
21407 + t_FmMacExceptionCallback *f_Exception;
21408 + int mdioIrq;
21409 + t_FmMacExceptionCallback *f_Event;
21410 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
21411 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
21412 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
21413 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
21414 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
21415 + bool debugMode;
21416 + uint8_t macId;
21417 + uint32_t exceptions;
21418 + struct memac_cfg *p_MemacDriverParam;
21419 +} t_Memac;
21420 +
21421 +
21422 +/* Internal PHY access */
21423 +#define PHY_MDIO_ADDR 0
21424 +
21425 +/* Internal PHY Registers - SGMII */
21426 +#define PHY_SGMII_CR_PHY_RESET 0x8000
21427 +#define PHY_SGMII_CR_RESET_AN 0x0200
21428 +#define PHY_SGMII_CR_DEF_VAL 0x1140
21429 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
21430 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
21431 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
21432 +#define PHY_SGMII_IF_MODE_AN 0x0002
21433 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
21434 +#define PHY_SGMII_IF_MODE_1000X 0x0000
21435 +
21436 +
21437 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
21438 +
21439 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
21440 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
21441 +
21442 +
21443 +#endif /* __MEMAC_H */
21444 --- /dev/null
21445 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
21446 @@ -0,0 +1,78 @@
21447 +/*
21448 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21449 + *
21450 + * Redistribution and use in source and binary forms, with or without
21451 + * modification, are permitted provided that the following conditions are met:
21452 + * * Redistributions of source code must retain the above copyright
21453 + * notice, this list of conditions and the following disclaimer.
21454 + * * Redistributions in binary form must reproduce the above copyright
21455 + * notice, this list of conditions and the following disclaimer in the
21456 + * documentation and/or other materials provided with the distribution.
21457 + * * Neither the name of Freescale Semiconductor nor the
21458 + * names of its contributors may be used to endorse or promote products
21459 + * derived from this software without specific prior written permission.
21460 + *
21461 + *
21462 + * ALTERNATIVELY, this software may be distributed under the terms of the
21463 + * GNU General Public License ("GPL") as published by the Free Software
21464 + * Foundation, either version 2 of that License or (at your option) any
21465 + * later version.
21466 + *
21467 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21468 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21469 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21470 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21471 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21472 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21473 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21474 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21475 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21476 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21477 + */
21478 +
21479 +
21480 +#include "error_ext.h"
21481 +#include "std_ext.h"
21482 +#include "fm_mac.h"
21483 +#include "memac.h"
21484 +#include "xx_ext.h"
21485 +
21486 +#include "fm_common.h"
21487 +#include "memac_mii_acc.h"
21488 +
21489 +
21490 +/*****************************************************************************/
21491 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
21492 + uint8_t phyAddr,
21493 + uint8_t reg,
21494 + uint16_t data)
21495 +{
21496 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21497 +
21498 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21499 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21500 +
21501 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
21502 + phyAddr,
21503 + reg,
21504 + data,
21505 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21506 +}
21507 +
21508 +/*****************************************************************************/
21509 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
21510 + uint8_t phyAddr,
21511 + uint8_t reg,
21512 + uint16_t *p_Data)
21513 +{
21514 + t_Memac *p_Memac = (t_Memac *)h_Memac;
21515 +
21516 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
21517 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
21518 +
21519 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
21520 + phyAddr,
21521 + reg,
21522 + p_Data,
21523 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
21524 +}
21525 --- /dev/null
21526 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
21527 @@ -0,0 +1,73 @@
21528 +/*
21529 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21530 + *
21531 + * Redistribution and use in source and binary forms, with or without
21532 + * modification, are permitted provided that the following conditions are met:
21533 + * * Redistributions of source code must retain the above copyright
21534 + * notice, this list of conditions and the following disclaimer.
21535 + * * Redistributions in binary form must reproduce the above copyright
21536 + * notice, this list of conditions and the following disclaimer in the
21537 + * documentation and/or other materials provided with the distribution.
21538 + * * Neither the name of Freescale Semiconductor nor the
21539 + * names of its contributors may be used to endorse or promote products
21540 + * derived from this software without specific prior written permission.
21541 + *
21542 + *
21543 + * ALTERNATIVELY, this software may be distributed under the terms of the
21544 + * GNU General Public License ("GPL") as published by the Free Software
21545 + * Foundation, either version 2 of that License or (at your option) any
21546 + * later version.
21547 + *
21548 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21549 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21550 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21551 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21552 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21553 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21554 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21555 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21556 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21557 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21558 + */
21559 +
21560 +
21561 +#ifndef __MEMAC_MII_ACC_H
21562 +#define __MEMAC_MII_ACC_H
21563 +
21564 +#include "std_ext.h"
21565 +
21566 +
21567 +/* MII Management Registers */
21568 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
21569 +#define MDIO_CFG_CLK_DIV_SHIFT 7
21570 +#define MDIO_CFG_HOLD_MASK 0x0000001c
21571 +#define MDIO_CFG_ENC45 0x00000040
21572 +#define MDIO_CFG_READ_ERR 0x00000002
21573 +#define MDIO_CFG_BSY 0x00000001
21574 +
21575 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
21576 +#define MDIO_CTL_READ 0x00008000
21577 +
21578 +#define MDIO_DATA_BSY 0x80000000
21579 +
21580 +#if defined(__MWERKS__) && !defined(__GNUC__)
21581 +#pragma pack(push,1)
21582 +#endif /* defined(__MWERKS__) && ... */
21583 +
21584 +/*----------------------------------------------------*/
21585 +/* MII Configuration Control Memory Map Registers */
21586 +/*----------------------------------------------------*/
21587 +typedef struct t_MemacMiiAccessMemMap
21588 +{
21589 + volatile uint32_t mdio_cfg; /* 0x030 */
21590 + volatile uint32_t mdio_ctrl; /* 0x034 */
21591 + volatile uint32_t mdio_data; /* 0x038 */
21592 + volatile uint32_t mdio_addr; /* 0x03c */
21593 +} t_MemacMiiAccessMemMap ;
21594 +
21595 +#if defined(__MWERKS__) && !defined(__GNUC__)
21596 +#pragma pack(pop)
21597 +#endif /* defined(__MWERKS__) && ... */
21598 +
21599 +
21600 +#endif /* __MEMAC_MII_ACC_H */
21601 --- /dev/null
21602 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
21603 @@ -0,0 +1,1017 @@
21604 +/*
21605 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21606 + *
21607 + * Redistribution and use in source and binary forms, with or without
21608 + * modification, are permitted provided that the following conditions are met:
21609 + * * Redistributions of source code must retain the above copyright
21610 + * notice, this list of conditions and the following disclaimer.
21611 + * * Redistributions in binary form must reproduce the above copyright
21612 + * notice, this list of conditions and the following disclaimer in the
21613 + * documentation and/or other materials provided with the distribution.
21614 + * * Neither the name of Freescale Semiconductor nor the
21615 + * names of its contributors may be used to endorse or promote products
21616 + * derived from this software without specific prior written permission.
21617 + *
21618 + *
21619 + * ALTERNATIVELY, this software may be distributed under the terms of the
21620 + * GNU General Public License ("GPL") as published by the Free Software
21621 + * Foundation, either version 2 of that License or (at your option) any
21622 + * later version.
21623 + *
21624 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21625 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21626 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21627 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21628 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21629 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21630 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21631 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21632 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21633 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21634 + */
21635 +
21636 +
21637 +/******************************************************************************
21638 + @File tgec.c
21639 +
21640 + @Description FM 10G MAC ...
21641 +*//***************************************************************************/
21642 +
21643 +#include "std_ext.h"
21644 +#include "string_ext.h"
21645 +#include "error_ext.h"
21646 +#include "xx_ext.h"
21647 +#include "endian_ext.h"
21648 +#include "debug_ext.h"
21649 +#include "crc_mac_addr_ext.h"
21650 +
21651 +#include "fm_common.h"
21652 +#include "fsl_fman_tgec.h"
21653 +#include "tgec.h"
21654 +
21655 +
21656 +/*****************************************************************************/
21657 +/* Internal routines */
21658 +/*****************************************************************************/
21659 +
21660 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
21661 +{
21662 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
21663 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
21664 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
21665 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
21666 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
21667 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
21668 +
21669 + if (p_Tgec->addr == 0)
21670 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
21671 + if (!p_Tgec->f_Exception)
21672 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
21673 + if (!p_Tgec->f_Event)
21674 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
21675 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
21676 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
21677 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
21678 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
21679 + return E_OK;
21680 +}
21681 +
21682 +/* ......................................................................... */
21683 +
21684 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21685 +{
21686 + uint32_t crc;
21687 +
21688 + /* CRC calculation */
21689 + GET_MAC_ADDR_CRC(ethAddr, crc);
21690 +
21691 + crc = GetMirror32(crc);
21692 +
21693 + return crc;
21694 +}
21695 +
21696 +/* ......................................................................... */
21697 +
21698 +static void TgecErrException(t_Handle h_Tgec)
21699 +{
21700 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21701 + uint32_t event;
21702 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21703 +
21704 + /* do not handle MDIO events */
21705 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21706 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21707 +
21708 + fman_tgec_ack_event(p_TgecMemMap, event);
21709 +
21710 + if (event & TGEC_IMASK_REM_FAULT)
21711 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
21712 + if (event & TGEC_IMASK_LOC_FAULT)
21713 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
21714 + if (event & TGEC_IMASK_TX_ECC_ER)
21715 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
21716 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
21717 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
21718 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
21719 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
21720 + if (event & TGEC_IMASK_TX_ER)
21721 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
21722 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
21723 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
21724 + if (event & TGEC_IMASK_RX_ECC_ER)
21725 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
21726 + if (event & TGEC_IMASK_RX_JAB_FRM)
21727 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
21728 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
21729 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
21730 + if (event & TGEC_IMASK_RX_RUNT_FRM)
21731 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
21732 + if (event & TGEC_IMASK_RX_FRAG_FRM)
21733 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
21734 + if (event & TGEC_IMASK_RX_LEN_ER)
21735 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
21736 + if (event & TGEC_IMASK_RX_CRC_ER)
21737 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
21738 + if (event & TGEC_IMASK_RX_ALIGN_ER)
21739 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
21740 +}
21741 +
21742 +/* ......................................................................... */
21743 +
21744 +static void TgecException(t_Handle h_Tgec)
21745 +{
21746 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21747 + uint32_t event;
21748 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
21749 +
21750 + /* handle only MDIO events */
21751 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
21752 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
21753 +
21754 + fman_tgec_ack_event(p_TgecMemMap, event);
21755 +
21756 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
21757 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
21758 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
21759 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
21760 +}
21761 +
21762 +/* ......................................................................... */
21763 +
21764 +static void FreeInitResources(t_Tgec *p_Tgec)
21765 +{
21766 + if (p_Tgec->mdioIrq != NO_IRQ)
21767 + {
21768 + XX_DisableIntr(p_Tgec->mdioIrq);
21769 + XX_FreeIntr(p_Tgec->mdioIrq);
21770 + }
21771 +
21772 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
21773 +
21774 + /* release the driver's group hash table */
21775 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
21776 + p_Tgec->p_MulticastAddrHash = NULL;
21777 +
21778 + /* release the driver's individual hash table */
21779 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
21780 + p_Tgec->p_UnicastAddrHash = NULL;
21781 +}
21782 +
21783 +
21784 +/*****************************************************************************/
21785 +/* 10G MAC API routines */
21786 +/*****************************************************************************/
21787 +
21788 +/* ......................................................................... */
21789 +
21790 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
21791 +{
21792 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21793 +
21794 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21795 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21796 +
21797 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21798 +
21799 + return E_OK;
21800 +}
21801 +
21802 +/* ......................................................................... */
21803 +
21804 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
21805 +{
21806 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21807 +
21808 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21809 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21810 +
21811 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
21812 +
21813 + return E_OK;
21814 +}
21815 +
21816 +/* ......................................................................... */
21817 +
21818 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
21819 +{
21820 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21821 +
21822 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21823 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21824 +
21825 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
21826 +
21827 + return E_OK;
21828 +}
21829 +
21830 +
21831 +/*****************************************************************************/
21832 +/* Tgec Configs modification functions */
21833 +/*****************************************************************************/
21834 +
21835 +/* ......................................................................... */
21836 +
21837 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
21838 +{
21839 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21840 +
21841 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21842 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21843 +
21844 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
21845 +
21846 + return E_OK;
21847 +}
21848 +
21849 +/* ......................................................................... */
21850 +
21851 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
21852 +{
21853 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21854 +
21855 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21856 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21857 +
21858 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
21859 +
21860 + return E_OK;
21861 +}
21862 +
21863 +/* ......................................................................... */
21864 +
21865 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
21866 +{
21867 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21868 +
21869 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21870 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21871 +
21872 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
21873 +
21874 + return E_OK;
21875 +}
21876 +
21877 +/* ......................................................................... */
21878 +
21879 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
21880 +{
21881 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21882 +
21883 + UNUSED(newVal);
21884 +
21885 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21886 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21887 +
21888 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
21889 +
21890 + return E_OK;
21891 +}
21892 +
21893 +/* ......................................................................... */
21894 +
21895 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
21896 +{
21897 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21898 + uint32_t bitMask = 0;
21899 +
21900 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21901 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21902 +
21903 + GET_EXCEPTION_FLAG(bitMask, exception);
21904 + if (bitMask)
21905 + {
21906 + if (enable)
21907 + p_Tgec->exceptions |= bitMask;
21908 + else
21909 + p_Tgec->exceptions &= ~bitMask;
21910 + }
21911 + else
21912 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
21913 +
21914 + return E_OK;
21915 +}
21916 +
21917 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21918 +/* ......................................................................... */
21919 +
21920 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
21921 +{
21922 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21923 +
21924 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
21925 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21926 +
21927 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
21928 +
21929 + return E_OK;
21930 +}
21931 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21932 +
21933 +
21934 +/*****************************************************************************/
21935 +/* Tgec Run Time API functions */
21936 +/*****************************************************************************/
21937 +
21938 +/* ......................................................................... */
21939 +/* backward compatibility. will be removed in the future. */
21940 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
21941 +{
21942 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21943 +
21944 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21945 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21946 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21947 +
21948 +
21949 + return E_OK;
21950 +}
21951 +
21952 +/* ......................................................................... */
21953 +
21954 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
21955 + uint8_t priority,
21956 + uint16_t pauseTime,
21957 + uint16_t threshTime)
21958 +{
21959 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21960 +
21961 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21962 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21963 +
21964 + UNUSED(priority); UNUSED(threshTime);
21965 +
21966 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
21967 +
21968 + return E_OK;
21969 +}
21970 +
21971 +/* ......................................................................... */
21972 +
21973 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
21974 +{
21975 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21976 +
21977 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
21978 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21979 +
21980 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
21981 +
21982 + return E_OK;
21983 +}
21984 +
21985 +/* ......................................................................... */
21986 +
21987 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
21988 +{
21989 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
21990 + struct tgec_regs *p_TgecMemMap;
21991 +
21992 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
21993 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
21994 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
21995 +
21996 + p_TgecMemMap = p_Tgec->p_MemMap;
21997 +
21998 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
21999 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
22000 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
22001 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
22002 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
22003 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
22004 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
22005 +/* */
22006 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
22007 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
22008 +
22009 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
22010 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
22011 +
22012 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
22013 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
22014 +/* Pause */
22015 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
22016 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
22017 +
22018 +/* MIB II */
22019 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
22020 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
22021 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
22022 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
22023 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
22024 + + p_Statistics->ifInMcastPkts
22025 + + p_Statistics->ifInBcastPkts;
22026 + p_Statistics->ifInDiscards = 0;
22027 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
22028 +
22029 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
22030 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
22031 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
22032 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
22033 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
22034 + + p_Statistics->ifOutMcastPkts
22035 + + p_Statistics->ifOutBcastPkts;
22036 + p_Statistics->ifOutDiscards = 0;
22037 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
22038 +
22039 + return E_OK;
22040 +}
22041 +
22042 +/* ......................................................................... */
22043 +
22044 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
22045 +{
22046 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22047 + struct tgec_regs *p_TgecMemMap;
22048 +
22049 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22050 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22051 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
22052 +
22053 + p_TgecMemMap = p_Tgec->p_MemMap;
22054 +
22055 + switch (type)
22056 + {
22057 + case e_COMM_MODE_NONE:
22058 + break;
22059 +
22060 + case e_COMM_MODE_RX:
22061 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
22062 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
22063 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
22064 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
22065 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
22066 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
22067 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
22068 + break;
22069 +
22070 + case e_COMM_MODE_TX:
22071 + //Tx counters not supported
22072 + break;
22073 +
22074 + case e_COMM_MODE_RX_AND_TX:
22075 + //Tx counters not supported
22076 + break;
22077 + }
22078 +
22079 + return E_OK;
22080 +}
22081 +
22082 +
22083 +/* ......................................................................... */
22084 +
22085 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
22086 +{
22087 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22088 +
22089 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22090 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22091 +
22092 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
22093 +
22094 + return E_OK;
22095 +}
22096 +
22097 +/* ......................................................................... */
22098 +
22099 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
22100 +{
22101 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22102 +
22103 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22104 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22105 +
22106 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
22107 +
22108 + return E_OK;
22109 +}
22110 +
22111 +/* ......................................................................... */
22112 +
22113 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
22114 +{
22115 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22116 +
22117 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22118 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22119 +
22120 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
22121 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
22122 +
22123 + return E_OK;
22124 +}
22125 +
22126 +/* ......................................................................... */
22127 +
22128 +static t_Error TgecResetCounters (t_Handle h_Tgec)
22129 +{
22130 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22131 +
22132 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22133 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22134 +
22135 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22136 +
22137 + return E_OK;
22138 +}
22139 +
22140 +/* ......................................................................... */
22141 +
22142 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22143 +{
22144 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
22145 + uint64_t ethAddr;
22146 + uint8_t paddrNum;
22147 +
22148 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22149 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22150 +
22151 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22152 +
22153 + if (ethAddr & GROUP_ADDRESS)
22154 + /* Multicast address has no effect in PADDR */
22155 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
22156 +
22157 + /* Make sure no PADDR contains this address */
22158 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22159 + if (p_Tgec->indAddrRegUsed[paddrNum])
22160 + if (p_Tgec->paddr[paddrNum] == ethAddr)
22161 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
22162 +
22163 + /* Find first unused PADDR */
22164 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22165 + {
22166 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
22167 + {
22168 + /* mark this PADDR as used */
22169 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
22170 + /* store address */
22171 + p_Tgec->paddr[paddrNum] = ethAddr;
22172 +
22173 + /* put in hardware */
22174 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
22175 + p_Tgec->numOfIndAddrInRegs++;
22176 +
22177 + return E_OK;
22178 + }
22179 + }
22180 +
22181 + /* No free PADDR */
22182 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
22183 +}
22184 +
22185 +/* ......................................................................... */
22186 +
22187 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22188 +{
22189 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
22190 + uint64_t ethAddr;
22191 + uint8_t paddrNum;
22192 +
22193 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22194 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22195 +
22196 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22197 +
22198 + /* Find used PADDR containing this address */
22199 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
22200 + {
22201 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
22202 + (p_Tgec->paddr[paddrNum] == ethAddr))
22203 + {
22204 + /* mark this PADDR as not used */
22205 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
22206 + /* clear in hardware */
22207 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
22208 + p_Tgec->numOfIndAddrInRegs--;
22209 +
22210 + return E_OK;
22211 + }
22212 + }
22213 +
22214 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22215 +}
22216 +
22217 +/* ......................................................................... */
22218 +
22219 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22220 +{
22221 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22222 + t_EthHashEntry *p_HashEntry;
22223 + uint32_t crc;
22224 + uint32_t hash;
22225 + uint64_t ethAddr;
22226 +
22227 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22228 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22229 +
22230 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22231 +
22232 + if (!(ethAddr & GROUP_ADDRESS))
22233 + /* Unicast addresses not supported in hash */
22234 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22235 +
22236 + /* CRC calculation */
22237 + crc = GetMacAddrHashCode(ethAddr);
22238 +
22239 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22240 +
22241 + /* Create element to be added to the driver hash table */
22242 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22243 + p_HashEntry->addr = ethAddr;
22244 + INIT_LIST(&p_HashEntry->node);
22245 +
22246 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
22247 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
22248 +
22249 + return E_OK;
22250 +}
22251 +
22252 +/* ......................................................................... */
22253 +
22254 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
22255 +{
22256 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22257 + t_EthHashEntry *p_HashEntry = NULL;
22258 + t_List *p_Pos;
22259 + uint32_t crc;
22260 + uint32_t hash;
22261 + uint64_t ethAddr;
22262 +
22263 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
22264 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22265 +
22266 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
22267 +
22268 + /* CRC calculation */
22269 + crc = GetMacAddrHashCode(ethAddr);
22270 +
22271 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
22272 +
22273 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22274 + {
22275 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22276 + if (p_HashEntry->addr == ethAddr)
22277 + {
22278 + LIST_DelAndInit(&p_HashEntry->node);
22279 + XX_Free(p_HashEntry);
22280 + break;
22281 + }
22282 + }
22283 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
22284 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
22285 +
22286 + return E_OK;
22287 +}
22288 +
22289 +/* ......................................................................... */
22290 +
22291 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
22292 +{
22293 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22294 +
22295 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22296 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22297 +
22298 + UNUSED(p_Tgec);
22299 + UNUSED(macId);
22300 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
22301 +}
22302 +
22303 +/* ......................................................................... */
22304 +
22305 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
22306 +{
22307 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22308 +
22309 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22310 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22311 +
22312 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
22313 +
22314 + return E_OK;
22315 +}
22316 +
22317 +/* ......................................................................... */
22318 +
22319 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
22320 +{
22321 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22322 + uint32_t bitMask = 0;
22323 +
22324 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22325 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22326 +
22327 + GET_EXCEPTION_FLAG(bitMask, exception);
22328 + if (bitMask)
22329 + {
22330 + if (enable)
22331 + p_Tgec->exceptions |= bitMask;
22332 + else
22333 + p_Tgec->exceptions &= ~bitMask;
22334 + }
22335 + else
22336 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22337 +
22338 + if (enable)
22339 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
22340 + else
22341 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
22342 +
22343 + return E_OK;
22344 +}
22345 +
22346 +/* ......................................................................... */
22347 +
22348 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
22349 +{
22350 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22351 +
22352 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
22353 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
22354 +
22355 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
22356 +}
22357 +
22358 +/* ......................................................................... */
22359 +
22360 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22361 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
22362 +{
22363 + t_Error err;
22364 +
22365 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22366 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
22367 +#endif /* (DEBUG_ERRORS > 0) */
22368 + /* enable and set promiscuous */
22369 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
22370 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
22371 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
22372 + /* disable */
22373 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
22374 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
22375 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
22376 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
22377 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
22378 + if (err)
22379 + XX_Print("FAILED!\n");
22380 + else
22381 + XX_Print("done.\n");
22382 +#endif /* (DEBUG_ERRORS > 0) */
22383 +
22384 + return err;
22385 +}
22386 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22387 +
22388 +/*****************************************************************************/
22389 +/* FM Init & Free API */
22390 +/*****************************************************************************/
22391 +
22392 +/* ......................................................................... */
22393 +
22394 +static t_Error TgecInit(t_Handle h_Tgec)
22395 +{
22396 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22397 + struct tgec_cfg *p_TgecDriverParam;
22398 + t_EnetAddr ethAddr;
22399 + t_Error err;
22400 +
22401 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22402 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
22403 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22404 +
22405 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
22406 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
22407 +
22408 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
22409 +
22410 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
22411 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
22412 +
22413 + /* interrupts */
22414 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
22415 + {
22416 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
22417 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
22418 + }
22419 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
22420 +
22421 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22422 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
22423 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
22424 + {
22425 + FreeInitResources(p_Tgec);
22426 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
22427 + }
22428 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22429 +
22430 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
22431 + if (err)
22432 + {
22433 + FreeInitResources(p_Tgec);
22434 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
22435 + }
22436 +
22437 + /* Max Frame Length */
22438 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
22439 + e_FM_MAC_10G,
22440 + p_Tgec->fmMacControllerDriver.macId,
22441 + p_TgecDriverParam->max_frame_length);
22442 + if (err != E_OK)
22443 + {
22444 + FreeInitResources(p_Tgec);
22445 + RETURN_ERROR(MINOR, err, NO_MSG);
22446 + }
22447 +/* we consider having no IPC a non crasher... */
22448 +
22449 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
22450 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
22451 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
22452 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
22453 +
22454 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22455 + if (!p_Tgec->p_MulticastAddrHash)
22456 + {
22457 + FreeInitResources(p_Tgec);
22458 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22459 + }
22460 +
22461 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22462 + if (!p_Tgec->p_UnicastAddrHash)
22463 + {
22464 + FreeInitResources(p_Tgec);
22465 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22466 + }
22467 +
22468 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
22469 + e_FM_MOD_10G_MAC,
22470 + p_Tgec->macId,
22471 + e_FM_INTR_TYPE_ERR,
22472 + TgecErrException,
22473 + p_Tgec);
22474 + if (p_Tgec->mdioIrq != NO_IRQ)
22475 + {
22476 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
22477 + XX_EnableIntr(p_Tgec->mdioIrq);
22478 + }
22479 +
22480 + XX_Free(p_TgecDriverParam);
22481 + p_Tgec->p_TgecDriverParam = NULL;
22482 +
22483 + return E_OK;
22484 +}
22485 +
22486 +/* ......................................................................... */
22487 +
22488 +static t_Error TgecFree(t_Handle h_Tgec)
22489 +{
22490 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22491 +
22492 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22493 +
22494 + if (p_Tgec->p_TgecDriverParam)
22495 + {
22496 + /* Called after config */
22497 + XX_Free(p_Tgec->p_TgecDriverParam);
22498 + p_Tgec->p_TgecDriverParam = NULL;
22499 + }
22500 + else
22501 + /* Called after init */
22502 + FreeInitResources(p_Tgec);
22503 +
22504 + XX_Free(p_Tgec);
22505 +
22506 + return E_OK;
22507 +}
22508 +
22509 +/* ......................................................................... */
22510 +
22511 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22512 +{
22513 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
22514 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
22515 +
22516 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22517 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
22518 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
22519 +
22520 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
22521 +
22522 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
22523 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
22524 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
22525 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
22526 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
22527 +
22528 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
22529 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
22530 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
22531 +
22532 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
22533 +
22534 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
22535 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
22536 +
22537 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
22538 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
22539 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
22540 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22541 +
22542 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
22543 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
22544 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
22545 +
22546 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
22547 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
22548 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
22549 +
22550 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
22551 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
22552 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
22553 +
22554 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
22555 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
22556 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
22557 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
22558 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
22559 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
22560 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
22561 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
22562 +
22563 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
22564 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
22565 +}
22566 +
22567 +
22568 +/*****************************************************************************/
22569 +/* Tgec Config Main Entry */
22570 +/*****************************************************************************/
22571 +
22572 +/* ......................................................................... */
22573 +
22574 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
22575 +{
22576 + t_Tgec *p_Tgec;
22577 + struct tgec_cfg *p_TgecDriverParam;
22578 + uintptr_t baseAddr;
22579 +
22580 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22581 +
22582 + baseAddr = p_FmMacParam->baseAddr;
22583 + /* allocate memory for the UCC GETH data structure. */
22584 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
22585 + if (!p_Tgec)
22586 + {
22587 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
22588 + return NULL;
22589 + }
22590 + memset(p_Tgec, 0, sizeof(t_Tgec));
22591 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
22592 +
22593 + /* allocate memory for the 10G MAC driver parameters data structure. */
22594 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
22595 + if (!p_TgecDriverParam)
22596 + {
22597 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
22598 + XX_Free(p_Tgec);
22599 + return NULL;
22600 + }
22601 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
22602 +
22603 + /* Plant parameter structure pointer */
22604 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
22605 +
22606 + fman_tgec_defconfig(p_TgecDriverParam);
22607 +
22608 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
22609 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
22610 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22611 + p_Tgec->enetMode = p_FmMacParam->enetMode;
22612 + p_Tgec->macId = p_FmMacParam->macId;
22613 + p_Tgec->exceptions = DEFAULT_exceptions;
22614 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
22615 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
22616 + p_Tgec->f_Event = p_FmMacParam->f_Event;
22617 + p_Tgec->h_App = p_FmMacParam->h_App;
22618 +
22619 + return p_Tgec;
22620 +}
22621 --- /dev/null
22622 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
22623 @@ -0,0 +1,151 @@
22624 +/*
22625 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22626 + *
22627 + * Redistribution and use in source and binary forms, with or without
22628 + * modification, are permitted provided that the following conditions are met:
22629 + * * Redistributions of source code must retain the above copyright
22630 + * notice, this list of conditions and the following disclaimer.
22631 + * * Redistributions in binary form must reproduce the above copyright
22632 + * notice, this list of conditions and the following disclaimer in the
22633 + * documentation and/or other materials provided with the distribution.
22634 + * * Neither the name of Freescale Semiconductor nor the
22635 + * names of its contributors may be used to endorse or promote products
22636 + * derived from this software without specific prior written permission.
22637 + *
22638 + *
22639 + * ALTERNATIVELY, this software may be distributed under the terms of the
22640 + * GNU General Public License ("GPL") as published by the Free Software
22641 + * Foundation, either version 2 of that License or (at your option) any
22642 + * later version.
22643 + *
22644 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22645 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22646 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22647 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22648 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22649 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22650 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22651 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22652 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22653 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22654 + */
22655 +
22656 +
22657 +/******************************************************************************
22658 + @File tgec.h
22659 +
22660 + @Description FM 10G MAC ...
22661 +*//***************************************************************************/
22662 +#ifndef __TGEC_H
22663 +#define __TGEC_H
22664 +
22665 +#include "std_ext.h"
22666 +#include "error_ext.h"
22667 +#include "list_ext.h"
22668 +#include "enet_ext.h"
22669 +
22670 +#include "tgec_mii_acc.h"
22671 +#include "fm_mac.h"
22672 +
22673 +
22674 +#define DEFAULT_exceptions \
22675 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
22676 + TGEC_IMASK_REM_FAULT | \
22677 + TGEC_IMASK_LOC_FAULT | \
22678 + TGEC_IMASK_TX_ECC_ER | \
22679 + TGEC_IMASK_TX_FIFO_UNFL | \
22680 + TGEC_IMASK_TX_FIFO_OVFL | \
22681 + TGEC_IMASK_TX_ER | \
22682 + TGEC_IMASK_RX_FIFO_OVFL | \
22683 + TGEC_IMASK_RX_ECC_ER | \
22684 + TGEC_IMASK_RX_JAB_FRM | \
22685 + TGEC_IMASK_RX_OVRSZ_FRM | \
22686 + TGEC_IMASK_RX_RUNT_FRM | \
22687 + TGEC_IMASK_RX_FRAG_FRM | \
22688 + TGEC_IMASK_RX_CRC_ER | \
22689 + TGEC_IMASK_RX_ALIGN_ER))
22690 +
22691 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
22692 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
22693 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
22694 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
22695 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
22696 + case e_FM_MAC_EX_10G_REM_FAULT: \
22697 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
22698 + case e_FM_MAC_EX_10G_LOC_FAULT: \
22699 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
22700 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
22701 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
22702 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
22703 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
22704 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
22705 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
22706 + case e_FM_MAC_EX_10G_TX_ER: \
22707 + bitMask = TGEC_IMASK_TX_ER ; break; \
22708 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
22709 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
22710 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
22711 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
22712 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
22713 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
22714 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
22715 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
22716 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
22717 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
22718 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
22719 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
22720 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
22721 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
22722 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
22723 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
22724 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
22725 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
22726 + default: bitMask = 0;break;}
22727 +
22728 +#define MAX_PACKET_ALIGNMENT 31
22729 +#define MAX_INTER_PACKET_GAP 0x7f
22730 +#define MAX_INTER_PALTERNATE_BEB 0x0f
22731 +#define MAX_RETRANSMISSION 0x0f
22732 +#define MAX_COLLISION_WINDOW 0x03ff
22733 +
22734 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
22735 +
22736 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
22737 +
22738 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
22739 +
22740 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
22741 +
22742 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
22743 +#define TGEC_ID_ID 0xffff0000
22744 +#define TGEC_ID_MAC_VERSION 0x0000FF00
22745 +#define TGEC_ID_MAC_REV 0x000000ff
22746 +
22747 +
22748 +typedef struct {
22749 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
22750 + t_Handle h_App; /**< Handle to the upper layer application */
22751 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
22752 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
22753 + uint64_t addr; /**< MAC address of device; */
22754 + e_EnetMode enetMode; /**< Ethernet physical interface */
22755 + t_FmMacExceptionCallback *f_Exception;
22756 + int mdioIrq;
22757 + t_FmMacExceptionCallback *f_Event;
22758 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
22759 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
22760 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
22761 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
22762 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
22763 + bool debugMode;
22764 + uint8_t macId;
22765 + uint32_t exceptions;
22766 + struct tgec_cfg *p_TgecDriverParam;
22767 +} t_Tgec;
22768 +
22769 +
22770 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
22771 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
22772 +
22773 +
22774 +#endif /* __TGEC_H */
22775 --- /dev/null
22776 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
22777 @@ -0,0 +1,139 @@
22778 +/*
22779 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22780 + *
22781 + * Redistribution and use in source and binary forms, with or without
22782 + * modification, are permitted provided that the following conditions are met:
22783 + * * Redistributions of source code must retain the above copyright
22784 + * notice, this list of conditions and the following disclaimer.
22785 + * * Redistributions in binary form must reproduce the above copyright
22786 + * notice, this list of conditions and the following disclaimer in the
22787 + * documentation and/or other materials provided with the distribution.
22788 + * * Neither the name of Freescale Semiconductor nor the
22789 + * names of its contributors may be used to endorse or promote products
22790 + * derived from this software without specific prior written permission.
22791 + *
22792 + *
22793 + * ALTERNATIVELY, this software may be distributed under the terms of the
22794 + * GNU General Public License ("GPL") as published by the Free Software
22795 + * Foundation, either version 2 of that License or (at your option) any
22796 + * later version.
22797 + *
22798 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22799 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22800 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22801 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22802 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22803 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22804 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22805 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22806 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22807 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22808 + */
22809 +
22810 +
22811 +
22812 +#include "error_ext.h"
22813 +#include "std_ext.h"
22814 +#include "fm_mac.h"
22815 +#include "tgec.h"
22816 +#include "xx_ext.h"
22817 +
22818 +#include "fm_common.h"
22819 +
22820 +
22821 +/*****************************************************************************/
22822 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
22823 + uint8_t phyAddr,
22824 + uint8_t reg,
22825 + uint16_t data)
22826 +{
22827 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22828 + t_TgecMiiAccessMemMap *p_MiiAccess;
22829 + uint32_t cfgStatusReg;
22830 +
22831 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22832 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22833 +
22834 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22835 +
22836 + /* Configure MII */
22837 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22838 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22839 + /* (one half of fm clock => 2.5Mhz) */
22840 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22841 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22842 +
22843 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22844 + XX_UDelay (1);
22845 +
22846 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22847 +
22848 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22849 +
22850 + CORE_MemoryBarrier();
22851 +
22852 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22853 + XX_UDelay (1);
22854 +
22855 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
22856 +
22857 + CORE_MemoryBarrier();
22858 +
22859 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22860 + XX_UDelay (1);
22861 +
22862 + return E_OK;
22863 +}
22864 +
22865 +/*****************************************************************************/
22866 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
22867 + uint8_t phyAddr,
22868 + uint8_t reg,
22869 + uint16_t *p_Data)
22870 +{
22871 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
22872 + t_TgecMiiAccessMemMap *p_MiiAccess;
22873 + uint32_t cfgStatusReg;
22874 +
22875 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
22876 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
22877 +
22878 + p_MiiAccess = p_Tgec->p_MiiMemMap;
22879 +
22880 + /* Configure MII */
22881 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22882 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
22883 + /* (one half of fm clock => 2.5Mhz) */
22884 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
22885 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
22886 +
22887 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22888 + XX_UDelay (1);
22889 +
22890 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
22891 +
22892 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
22893 +
22894 + CORE_MemoryBarrier();
22895 +
22896 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
22897 + XX_UDelay (1);
22898 +
22899 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
22900 +
22901 + CORE_MemoryBarrier();
22902 +
22903 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
22904 + XX_UDelay (1);
22905 +
22906 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
22907 +
22908 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
22909 +
22910 + if (cfgStatusReg & MIIMIND_READ_ERROR)
22911 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
22912 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
22913 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
22914 +
22915 + return E_OK;
22916 +}
22917 --- /dev/null
22918 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
22919 @@ -0,0 +1,80 @@
22920 +/*
22921 + * Copyright 2008-2012 Freescale Semiconductor Inc.
22922 + *
22923 + * Redistribution and use in source and binary forms, with or without
22924 + * modification, are permitted provided that the following conditions are met:
22925 + * * Redistributions of source code must retain the above copyright
22926 + * notice, this list of conditions and the following disclaimer.
22927 + * * Redistributions in binary form must reproduce the above copyright
22928 + * notice, this list of conditions and the following disclaimer in the
22929 + * documentation and/or other materials provided with the distribution.
22930 + * * Neither the name of Freescale Semiconductor nor the
22931 + * names of its contributors may be used to endorse or promote products
22932 + * derived from this software without specific prior written permission.
22933 + *
22934 + *
22935 + * ALTERNATIVELY, this software may be distributed under the terms of the
22936 + * GNU General Public License ("GPL") as published by the Free Software
22937 + * Foundation, either version 2 of that License or (at your option) any
22938 + * later version.
22939 + *
22940 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22941 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22942 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22943 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
22944 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22945 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22946 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22947 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22948 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22949 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22950 + */
22951 +
22952 +
22953 +#ifndef __TGEC_MII_ACC_H
22954 +#define __TGEC_MII_ACC_H
22955 +
22956 +#include "std_ext.h"
22957 +
22958 +
22959 +/* MII Management Command Register */
22960 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
22961 +#define MIIMCOM_READ_CYCLE 0x00008000
22962 +#define MIIMCOM_SCAN_CYCLE 0x00000800
22963 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
22964 +
22965 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
22966 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
22967 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
22968 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
22969 +
22970 +#define MIIMCOM_DIV_MASK 0x0000ff00
22971 +#define MIIMCOM_DIV_SHIFT 8
22972 +
22973 +/* MII Management Indicator Register */
22974 +#define MIIMIND_BUSY 0x00000001
22975 +#define MIIMIND_READ_ERROR 0x00000002
22976 +
22977 +#define MIIDATA_BUSY 0x80000000
22978 +
22979 +#if defined(__MWERKS__) && !defined(__GNUC__)
22980 +#pragma pack(push,1)
22981 +#endif /* defined(__MWERKS__) && ... */
22982 +
22983 +/*----------------------------------------------------*/
22984 +/* MII Configuration Control Memory Map Registers */
22985 +/*----------------------------------------------------*/
22986 +typedef _Packed struct t_TgecMiiAccessMemMap
22987 +{
22988 + volatile uint32_t mdio_cfg_status; /* 0x030 */
22989 + volatile uint32_t mdio_command; /* 0x034 */
22990 + volatile uint32_t mdio_data; /* 0x038 */
22991 + volatile uint32_t mdio_regaddr; /* 0x03c */
22992 +} _PackedType t_TgecMiiAccessMemMap ;
22993 +
22994 +#if defined(__MWERKS__) && !defined(__GNUC__)
22995 +#pragma pack(pop)
22996 +#endif /* defined(__MWERKS__) && ... */
22997 +
22998 +
22999 +#endif /* __TGEC_MII_ACC_H */
23000 --- /dev/null
23001 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
23002 @@ -0,0 +1,15 @@
23003 +#
23004 +# Makefile for the Freescale Ethernet controllers
23005 +#
23006 +ccflags-y += -DVERSION=\"\"
23007 +#
23008 +#Include netcomm SW specific definitions
23009 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
23010 +
23011 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
23012 +
23013 +ccflags-y += -I$(NCSW_FM_INC)
23014 +
23015 +obj-y += fsl-ncsw-macsec.o
23016 +
23017 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
23018 --- /dev/null
23019 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
23020 @@ -0,0 +1,237 @@
23021 +/*
23022 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23023 + *
23024 + * Redistribution and use in source and binary forms, with or without
23025 + * modification, are permitted provided that the following conditions are met:
23026 + * * Redistributions of source code must retain the above copyright
23027 + * notice, this list of conditions and the following disclaimer.
23028 + * * Redistributions in binary form must reproduce the above copyright
23029 + * notice, this list of conditions and the following disclaimer in the
23030 + * documentation and/or other materials provided with the distribution.
23031 + * * Neither the name of Freescale Semiconductor nor the
23032 + * names of its contributors may be used to endorse or promote products
23033 + * derived from this software without specific prior written permission.
23034 + *
23035 + *
23036 + * ALTERNATIVELY, this software may be distributed under the terms of the
23037 + * GNU General Public License ("GPL") as published by the Free Software
23038 + * Foundation, either version 2 of that License or (at your option) any
23039 + * later version.
23040 + *
23041 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23042 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23043 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23044 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23045 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23046 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23047 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23048 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23049 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23050 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23051 + */
23052 +/******************************************************************************
23053 +
23054 + @File fm_macsec.c
23055 +
23056 + @Description FM MACSEC driver routines implementation.
23057 +*//***************************************************************************/
23058 +
23059 +#include "std_ext.h"
23060 +#include "error_ext.h"
23061 +#include "xx_ext.h"
23062 +#include "string_ext.h"
23063 +#include "sprint_ext.h"
23064 +#include "debug_ext.h"
23065 +
23066 +#include "fm_macsec.h"
23067 +
23068 +
23069 +/****************************************/
23070 +/* API Init unit functions */
23071 +/****************************************/
23072 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
23073 +{
23074 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
23075 +
23076 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
23077 +
23078 + if (p_FmMacsecParam->guestMode)
23079 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
23080 + else
23081 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
23082 +
23083 + if (!p_FmMacsecControllerDriver)
23084 + return NULL;
23085 +
23086 + return (t_Handle)p_FmMacsecControllerDriver;
23087 +}
23088 +
23089 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
23090 +{
23091 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23092 +
23093 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23094 +
23095 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
23096 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
23097 +
23098 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23099 +}
23100 +
23101 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
23102 +{
23103 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23104 +
23105 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23106 +
23107 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
23108 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
23109 +
23110 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23111 +}
23112 +
23113 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23114 +{
23115 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23116 +
23117 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23118 +
23119 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
23120 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
23121 +
23122 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23123 +}
23124 +
23125 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23126 +{
23127 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23128 +
23129 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23130 +
23131 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
23132 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
23133 +
23134 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23135 +}
23136 +
23137 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23138 +{
23139 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23140 +
23141 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23142 +
23143 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
23144 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
23145 +
23146 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23147 +}
23148 +
23149 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23150 +{
23151 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23152 +
23153 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23154 +
23155 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
23156 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
23157 +
23158 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23159 +}
23160 +
23161 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23162 +{
23163 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23164 +
23165 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23166 +
23167 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
23168 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
23169 +
23170 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23171 +}
23172 +
23173 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
23174 +{
23175 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23176 +
23177 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23178 +
23179 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
23180 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
23181 +
23182 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23183 +}
23184 +
23185 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23186 +{
23187 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23188 +
23189 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23190 +
23191 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
23192 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
23193 +
23194 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23195 +}
23196 +
23197 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23198 +{
23199 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23200 +
23201 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23202 +
23203 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
23204 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
23205 +
23206 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23207 +}
23208 +
23209 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23210 +{
23211 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23212 +
23213 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23214 +
23215 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
23216 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
23217 +
23218 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23219 +}
23220 +
23221 +
23222 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
23223 +{
23224 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23225 +
23226 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23227 +
23228 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
23229 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
23230 +
23231 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23232 +}
23233 +
23234 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
23235 +{
23236 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23237 +
23238 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23239 +
23240 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
23241 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
23242 +
23243 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23244 +}
23245 +
23246 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23247 +{
23248 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
23249 +
23250 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
23251 +
23252 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
23253 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
23254 +
23255 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
23256 +}
23257 +
23258 --- /dev/null
23259 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
23260 @@ -0,0 +1,203 @@
23261 +/*
23262 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23263 + *
23264 + * Redistribution and use in source and binary forms, with or without
23265 + * modification, are permitted provided that the following conditions are met:
23266 + * * Redistributions of source code must retain the above copyright
23267 + * notice, this list of conditions and the following disclaimer.
23268 + * * Redistributions in binary form must reproduce the above copyright
23269 + * notice, this list of conditions and the following disclaimer in the
23270 + * documentation and/or other materials provided with the distribution.
23271 + * * Neither the name of Freescale Semiconductor nor the
23272 + * names of its contributors may be used to endorse or promote products
23273 + * derived from this software without specific prior written permission.
23274 + *
23275 + *
23276 + * ALTERNATIVELY, this software may be distributed under the terms of the
23277 + * GNU General Public License ("GPL") as published by the Free Software
23278 + * Foundation, either version 2 of that License or (at your option) any
23279 + * later version.
23280 + *
23281 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23282 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23283 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23284 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23285 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23286 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23287 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23288 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23289 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23290 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23291 + */
23292 +
23293 +/******************************************************************************
23294 + @File fm_macsec.h
23295 +
23296 + @Description FM MACSEC internal structures and definitions.
23297 +*//***************************************************************************/
23298 +#ifndef __FM_MACSEC_H
23299 +#define __FM_MACSEC_H
23300 +
23301 +#include "error_ext.h"
23302 +#include "std_ext.h"
23303 +#include "fm_macsec_ext.h"
23304 +
23305 +#include "fm_common.h"
23306 +
23307 +
23308 +#define __ERR_MODULE__ MODULE_FM_MACSEC
23309 +
23310 +
23311 +typedef struct
23312 +{
23313 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
23314 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
23315 +
23316 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
23317 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23318 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
23319 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23320 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
23321 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
23322 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
23323 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
23324 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
23325 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23326 +
23327 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
23328 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
23329 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
23330 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
23331 +
23332 +} t_FmMacsecControllerDriver;
23333 +
23334 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
23335 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
23336 +
23337 +/***********************************************************************/
23338 +/* MACSEC internal routines */
23339 +/***********************************************************************/
23340 +
23341 +/**************************************************************************//**
23342 +
23343 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
23344 +
23345 + @Description FM MACSEC Inter Module functions -
23346 + These are not User API routines but routines that may be called
23347 + from other modules. This will be the case in a single core environment,
23348 + where instead of using the XX messaging mechanism, the routines may be
23349 + called from other modules. In a multicore environment, the other modules may
23350 + be run by other cores and therefore these routines may not be called directly.
23351 +
23352 + @{
23353 +*//***************************************************************************/
23354 +
23355 +#define MAX_NUM_OF_SA_PER_SC 4
23356 +
23357 +typedef enum
23358 +{
23359 + e_SC_RX = 0,
23360 + e_SC_TX
23361 +} e_ScType;
23362 +
23363 +typedef enum
23364 +{
23365 + e_SC_SA_A = 0,
23366 + e_SC_SA_B ,
23367 + e_SC_SA_C ,
23368 + e_SC_SA_D
23369 +} e_ScSaId;
23370 +
23371 +typedef struct
23372 +{
23373 + uint32_t scId;
23374 + macsecSCI_t sci;
23375 + bool replayProtect;
23376 + uint32_t replayWindow;
23377 + e_FmMacsecValidFrameBehavior validateFrames;
23378 + uint16_t confidentialityOffset;
23379 + e_FmMacsecSecYCipherSuite cipherSuite;
23380 +} t_RxScParams;
23381 +
23382 +typedef struct
23383 +{
23384 + uint32_t scId;
23385 + macsecSCI_t sci;
23386 + bool protectFrames;
23387 + e_FmMacsecSciInsertionMode sciInsertionMode;
23388 + bool confidentialityEnable;
23389 + uint16_t confidentialityOffset;
23390 + e_FmMacsecSecYCipherSuite cipherSuite;
23391 +} t_TxScParams;
23392 +
23393 +typedef enum e_FmMacsecGlobalExceptions {
23394 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
23395 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
23396 +} e_FmMacsecGlobalExceptions;
23397 +
23398 +typedef enum e_FmMacsecGlobalEvents {
23399 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
23400 +} e_FmMacsecGlobalEvents;
23401 +
23402 +/**************************************************************************//**
23403 + @Description Enum for inter-module interrupts registration
23404 +*//***************************************************************************/
23405 +typedef enum e_FmMacsecEventModules{
23406 + e_FM_MACSEC_MOD_SC_TX,
23407 + e_FM_MACSEC_MOD_DUMMY_LAST
23408 +} e_FmMacsecEventModules;
23409 +
23410 +typedef enum e_FmMacsecInterModuleEvent {
23411 + e_FM_MACSEC_EV_SC_TX,
23412 + e_FM_MACSEC_EV_ERR_SC_TX,
23413 + e_FM_MACSEC_EV_DUMMY_LAST
23414 +} e_FmMacsecInterModuleEvent;
23415 +
23416 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
23417 +
23418 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
23419 + switch(mod){ \
23420 + case e_FM_MACSEC_MOD_SC_TX: \
23421 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
23422 + e_FM_MACSEC_EV_ERR_SC_TX: \
23423 + e_FM_MACSEC_EV_SC_TX; \
23424 + event += (uint8_t)(2 * id);break; \
23425 + break; \
23426 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
23427 + break;}
23428 +
23429 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23430 + e_FmMacsecEventModules module,
23431 + uint8_t modId,
23432 + e_FmIntrType intrType,
23433 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23434 + t_Handle h_Arg);
23435 +
23436 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23437 + e_FmMacsecEventModules module,
23438 + uint8_t modId,
23439 + e_FmIntrType intrType);
23440 +
23441 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
23442 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
23443 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
23444 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
23445 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
23446 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
23447 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
23448 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
23449 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23450 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
23451 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
23452 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
23453 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
23454 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
23455 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
23456 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
23457 +
23458 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
23459 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
23460 +
23461 +
23462 +
23463 +#endif /* __FM_MACSEC_H */
23464 --- /dev/null
23465 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
23466 @@ -0,0 +1,59 @@
23467 +/*
23468 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23469 + *
23470 + * Redistribution and use in source and binary forms, with or without
23471 + * modification, are permitted provided that the following conditions are met:
23472 + * * Redistributions of source code must retain the above copyright
23473 + * notice, this list of conditions and the following disclaimer.
23474 + * * Redistributions in binary form must reproduce the above copyright
23475 + * notice, this list of conditions and the following disclaimer in the
23476 + * documentation and/or other materials provided with the distribution.
23477 + * * Neither the name of Freescale Semiconductor nor the
23478 + * names of its contributors may be used to endorse or promote products
23479 + * derived from this software without specific prior written permission.
23480 + *
23481 + *
23482 + * ALTERNATIVELY, this software may be distributed under the terms of the
23483 + * GNU General Public License ("GPL") as published by the Free Software
23484 + * Foundation, either version 2 of that License or (at your option) any
23485 + * later version.
23486 + *
23487 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23488 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23489 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23490 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23491 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23492 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23493 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23494 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23495 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23496 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23497 + */
23498 +
23499 +/******************************************************************************
23500 + @File fm_macsec.c
23501 +
23502 + @Description FM MACSEC driver routines implementation.
23503 +*//***************************************************************************/
23504 +
23505 +#include "std_ext.h"
23506 +#include "error_ext.h"
23507 +#include "xx_ext.h"
23508 +#include "string_ext.h"
23509 +#include "sprint_ext.h"
23510 +#include "debug_ext.h"
23511 +#include "fm_macsec.h"
23512 +
23513 +
23514 +/****************************************/
23515 +/* static functions */
23516 +/****************************************/
23517 +
23518 +/****************************************/
23519 +/* API Init unit functions */
23520 +/****************************************/
23521 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
23522 +{
23523 + UNUSED(p_FmMacsecParam);
23524 + return NULL;
23525 +}
23526 --- /dev/null
23527 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
23528 @@ -0,0 +1,1031 @@
23529 +/*
23530 + * Copyright 2008-2015 Freescale Semiconductor Inc.
23531 + *
23532 + * Redistribution and use in source and binary forms, with or without
23533 + * modification, are permitted provided that the following conditions are met:
23534 + * * Redistributions of source code must retain the above copyright
23535 + * notice, this list of conditions and the following disclaimer.
23536 + * * Redistributions in binary form must reproduce the above copyright
23537 + * notice, this list of conditions and the following disclaimer in the
23538 + * documentation and/or other materials provided with the distribution.
23539 + * * Neither the name of Freescale Semiconductor nor the
23540 + * names of its contributors may be used to endorse or promote products
23541 + * derived from this software without specific prior written permission.
23542 + *
23543 + *
23544 + * ALTERNATIVELY, this software may be distributed under the terms of the
23545 + * GNU General Public License ("GPL") as published by the Free Software
23546 + * Foundation, either version 2 of that License or (at your option) any
23547 + * later version.
23548 + *
23549 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23550 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23551 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23552 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23553 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23554 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23555 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23556 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23557 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23558 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23559 + */
23560 +
23561 +/******************************************************************************
23562 + @File fm_macsec.c
23563 +
23564 + @Description FM MACSEC driver routines implementation.
23565 +*//***************************************************************************/
23566 +
23567 +#include "std_ext.h"
23568 +#include "error_ext.h"
23569 +#include "xx_ext.h"
23570 +#include "string_ext.h"
23571 +#include "sprint_ext.h"
23572 +#include "fm_mac_ext.h"
23573 +
23574 +#include "fm_macsec_master.h"
23575 +
23576 +
23577 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
23578 +
23579 +
23580 +/****************************************/
23581 +/* static functions */
23582 +/****************************************/
23583 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
23584 +{
23585 + if (!p_FmMacsec->f_Exception)
23586 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
23587 +
23588 + return E_OK;
23589 +}
23590 +
23591 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
23592 +{
23593 + UNUSED(h_Arg); UNUSED(id);
23594 +
23595 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
23596 +}
23597 +
23598 +static void MacsecEventIsr(t_Handle h_FmMacsec)
23599 +{
23600 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23601 + uint32_t events,event,i;
23602 +
23603 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23604 +
23605 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
23606 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
23607 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
23608 +
23609 + for (i=0; i<NUM_OF_TX_SC; i++)
23610 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
23611 + {
23612 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
23613 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
23614 + }
23615 +}
23616 +
23617 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
23618 +{
23619 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23620 + uint32_t errors,error,i;
23621 +
23622 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23623 +
23624 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
23625 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
23626 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
23627 +
23628 + for (i=0; i<NUM_OF_TX_SC; i++)
23629 + if (errors & FM_MACSEC_EX_TX_SC(i))
23630 + {
23631 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
23632 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
23633 + }
23634 +
23635 + if (errors & FM_MACSEC_EX_ECC)
23636 + {
23637 + uint8_t eccType;
23638 + uint32_t tmpReg;
23639 +
23640 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
23641 + ASSERT_COND(tmpReg & MECC_CAP);
23642 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
23643 +
23644 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
23645 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
23646 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
23647 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
23648 + else
23649 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
23650 + }
23651 +}
23652 +
23653 +static t_Error MacsecInit(t_Handle h_FmMacsec)
23654 +{
23655 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23656 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
23657 + uint32_t tmpReg,i,macId;
23658 +
23659 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23660 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23661 +
23662 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
23663 +
23664 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
23665 +
23666 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
23667 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
23668 +
23669 + tmpReg = 0;
23670 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
23671 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
23672 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
23673 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
23674 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
23675 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
23676 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
23677 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
23678 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
23679 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
23680 +
23681 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
23682 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
23683 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
23684 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
23685 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
23686 +
23687 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
23688 +
23689 + if (!p_FmMacsec->userExceptions)
23690 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23691 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23692 +
23693 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
23694 + if (p_FmMacsecDriverParam->reservedSc0)
23695 + p_FmMacsec->numRxScAvailable --;
23696 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
23697 +
23698 + XX_Free(p_FmMacsecDriverParam);
23699 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
23700 +
23701 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23702 + FmRegisterIntr(p_FmMacsec->h_Fm,
23703 + e_FM_MOD_MACSEC,
23704 + (uint8_t)macId,
23705 + e_FM_INTR_TYPE_NORMAL,
23706 + MacsecEventIsr,
23707 + p_FmMacsec);
23708 +
23709 + FmRegisterIntr(p_FmMacsec->h_Fm,
23710 + e_FM_MOD_MACSEC,
23711 + 0,
23712 + e_FM_INTR_TYPE_ERR,
23713 + MacsecErrorIsr,
23714 + p_FmMacsec);
23715 +
23716 + return E_OK;
23717 +}
23718 +
23719 +static t_Error MacsecFree(t_Handle h_FmMacsec)
23720 +{
23721 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23722 + uint32_t macId;
23723 +
23724 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23725 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23726 +
23727 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
23728 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23729 + e_FM_MOD_MACSEC,
23730 + (uint8_t)macId,
23731 + e_FM_INTR_TYPE_NORMAL);
23732 +
23733 + FmUnregisterIntr(p_FmMacsec->h_Fm,
23734 + e_FM_MOD_MACSEC,
23735 + 0,
23736 + e_FM_INTR_TYPE_ERR);
23737 +
23738 + if (p_FmMacsec->rxScSpinLock)
23739 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
23740 + if (p_FmMacsec->txScSpinLock)
23741 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
23742 +
23743 + XX_Free(p_FmMacsec);
23744 +
23745 + return E_OK;
23746 +}
23747 +
23748 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
23749 +{
23750 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23751 +
23752 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23753 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23754 +
23755 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
23756 +
23757 + return E_OK;
23758 +}
23759 +
23760 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23761 +{
23762 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23763 +
23764 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23765 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23766 +
23767 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
23768 +
23769 + return E_OK;
23770 +}
23771 +
23772 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23773 +{
23774 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23775 +
23776 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23777 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23778 +
23779 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
23780 +
23781 + return E_OK;
23782 +}
23783 +
23784 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
23785 +{
23786 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23787 +
23788 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23789 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23790 +
23791 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
23792 +
23793 + return E_OK;
23794 +}
23795 +
23796 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
23797 +{
23798 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23799 +
23800 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23801 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23802 +
23803 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
23804 +
23805 + return E_OK;
23806 +}
23807 +
23808 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
23809 +{
23810 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23811 +
23812 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23813 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23814 +
23815 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
23816 +
23817 + return E_OK;
23818 +}
23819 +
23820 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
23821 +{
23822 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23823 +
23824 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23825 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23826 +
23827 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
23828 +
23829 + return E_OK;
23830 +}
23831 +
23832 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
23833 +{
23834 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23835 +
23836 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23837 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23838 +
23839 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
23840 +
23841 + return E_OK;
23842 +}
23843 +
23844 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
23845 +{
23846 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23847 +
23848 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23849 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23850 +
23851 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
23852 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
23853 +
23854 + return E_OK;
23855 +}
23856 +
23857 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23858 +{
23859 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23860 + uint32_t bitMask = 0;
23861 +
23862 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23863 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23864 +
23865 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23866 + if (bitMask)
23867 + {
23868 + if (enable)
23869 + p_FmMacsec->userExceptions |= bitMask;
23870 + else
23871 + p_FmMacsec->userExceptions &= ~bitMask;
23872 + }
23873 + else
23874 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23875 +
23876 + return E_OK;
23877 +}
23878 +
23879 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
23880 +{
23881 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23882 +
23883 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23884 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23885 +
23886 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
23887 +
23888 + return E_OK;
23889 +}
23890 +
23891 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
23892 +{
23893 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23894 + uint32_t tmpReg;
23895 +
23896 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23897 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23898 +
23899 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23900 + tmpReg |= CFG_BYPN;
23901 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23902 +
23903 + return E_OK;
23904 +}
23905 +
23906 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
23907 +{
23908 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23909 + uint32_t tmpReg;
23910 +
23911 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23912 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23913 +
23914 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
23915 + tmpReg &= ~CFG_BYPN;
23916 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
23917 +
23918 + return E_OK;
23919 +}
23920 +
23921 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
23922 +{
23923 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23924 + uint32_t bitMask;
23925 +
23926 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
23927 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
23928 +
23929 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
23930 + if (bitMask)
23931 + {
23932 + if (enable)
23933 + p_FmMacsec->userExceptions |= bitMask;
23934 + else
23935 + p_FmMacsec->userExceptions &= ~bitMask;
23936 + }
23937 + else
23938 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23939 +
23940 + if (!p_FmMacsec->userExceptions)
23941 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
23942 + else
23943 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
23944 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
23945 +
23946 + return E_OK;
23947 +}
23948 +
23949 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
23950 +{
23951 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
23952 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
23953 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
23954 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
23955 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
23956 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
23957 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
23958 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
23959 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
23960 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
23961 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
23962 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
23963 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
23964 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
23965 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
23966 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
23967 +}
23968 +
23969 +/****************************************/
23970 +/* Inter-Module functions */
23971 +/****************************************/
23972 +
23973 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
23974 + e_FmMacsecEventModules module,
23975 + uint8_t modId,
23976 + e_FmIntrType intrType,
23977 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
23978 + t_Handle h_Arg)
23979 +{
23980 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23981 + uint8_t event= 0;
23982 +
23983 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
23984 +
23985 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
23986 +
23987 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
23988 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
23989 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
23990 +}
23991 +
23992 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
23993 + e_FmMacsecEventModules module,
23994 + uint8_t modId,
23995 + e_FmIntrType intrType)
23996 +{
23997 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
23998 + uint8_t event= 0;
23999 +
24000 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
24001 +
24002 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
24003 +
24004 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
24005 + p_FmMacsec->intrMng[event].f_Isr = NULL;
24006 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
24007 +}
24008 +
24009 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
24010 +{
24011 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24012 + t_Error err = E_OK;
24013 + bool *p_ScTable;
24014 + uint32_t *p_ScAvailable,i;
24015 +
24016 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24017 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
24018 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
24019 +
24020 + if (type == e_SC_RX)
24021 + {
24022 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
24023 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
24024 + i = (NUM_OF_RX_SC - 1);
24025 + }
24026 + else
24027 + {
24028 + p_ScTable = (bool *)p_FmMacsec->txScTable;
24029 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
24030 + i = (NUM_OF_TX_SC - 1);
24031 +
24032 + }
24033 + if (*p_ScAvailable < numOfScs)
24034 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
24035 +
24036 + if (isPtp)
24037 + {
24038 + i = 0;
24039 + if (p_ScTable[i])
24040 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
24041 + }
24042 +
24043 + for (;numOfScs;i--)
24044 + {
24045 + if (p_ScTable[i])
24046 + continue;
24047 + numOfScs --;
24048 + (*p_ScAvailable)--;
24049 + p_ScIds[numOfScs] = i;
24050 + p_ScTable[i] = TRUE;
24051 + }
24052 +
24053 + return err;
24054 +}
24055 +
24056 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
24057 +{
24058 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24059 + t_Error err = E_OK;
24060 + bool *p_ScTable;
24061 + uint32_t *p_ScAvailable,maxNumOfSc,i;
24062 +
24063 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24064 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
24065 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
24066 +
24067 + if (type == e_SC_RX)
24068 + {
24069 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
24070 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
24071 + maxNumOfSc = NUM_OF_RX_SC;
24072 + }
24073 + else
24074 + {
24075 + p_ScTable = (bool *)p_FmMacsec->txScTable;
24076 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
24077 + maxNumOfSc = NUM_OF_TX_SC;
24078 + }
24079 +
24080 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
24081 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
24082 +
24083 + for (i=0;i<numOfScs;i++)
24084 + {
24085 + p_ScTable[p_ScIds[i]] = FALSE;
24086 + (*p_ScAvailable)++;
24087 + }
24088 +
24089 + return err;
24090 +
24091 +}
24092 +
24093 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
24094 +{
24095 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24096 + uint32_t tmpReg = 0;
24097 +
24098 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24099 +
24100 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
24101 + if (enable && (tmpReg & CFG_S0I))
24102 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
24103 +
24104 + if (enable)
24105 + tmpReg |= CFG_S0I;
24106 + else
24107 + tmpReg &= ~CFG_S0I;
24108 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
24109 +
24110 + return E_OK;
24111 +}
24112 +
24113 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
24114 +{
24115 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24116 + t_Error err = E_OK;
24117 + uint32_t tmpReg = 0, intFlags;
24118 +
24119 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24120 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
24121 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24122 +
24123 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24124 +
24125 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
24126 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
24127 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
24128 + {
24129 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24130 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
24131 + }
24132 +
24133 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
24134 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
24135 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
24136 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
24137 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
24138 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
24139 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
24140 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
24141 +
24142 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
24143 +
24144 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24145 +
24146 + return err;
24147 +}
24148 +
24149 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
24150 +{
24151 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24152 + t_Error err = E_OK;
24153 + uint32_t tmpReg = 0, intFlags;
24154 +
24155 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24156 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24157 +
24158 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24159 +
24160 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
24161 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24162 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
24163 +
24164 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24165 +
24166 + return err;
24167 +}
24168 +
24169 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
24170 +{
24171 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24172 + t_Error err = E_OK;
24173 + uint32_t tmpReg = 0, intFlags;
24174 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
24175 +
24176 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24177 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
24178 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24179 +
24180 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24181 +
24182 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
24183 +
24184 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24185 + if (tmpReg & TX_SCCFG_SCE_MASK)
24186 + {
24187 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24188 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
24189 + }
24190 +
24191 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
24192 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
24193 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
24194 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
24195 +
24196 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
24197 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
24198 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
24199 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
24200 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
24201 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
24202 + tmpReg |= TX_SCCFG_SCE_MASK;
24203 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
24204 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24205 +
24206 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24207 +
24208 + return err;
24209 +}
24210 +
24211 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
24212 +{
24213 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24214 + t_Error err = E_OK;
24215 + uint32_t tmpReg = 0, intFlags;
24216 +
24217 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24218 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
24219 +
24220 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24221 +
24222 + tmpReg &= ~TX_SCCFG_SCE_MASK;
24223 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24224 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24225 +
24226 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24227 +
24228 + return err;
24229 +}
24230 +
24231 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
24232 +{
24233 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24234 + t_Error err = E_OK;
24235 + uint32_t tmpReg = 0, intFlags;
24236 +
24237 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24238 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24239 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24240 +
24241 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24242 +
24243 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24244 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
24245 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
24246 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
24247 +
24248 + tmpReg |= RX_SACFG_ACTIVE;
24249 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
24250 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24251 +
24252 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24253 +
24254 + return err;
24255 +}
24256 +
24257 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
24258 +{
24259 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24260 + t_Error err = E_OK;
24261 + uint32_t tmpReg = 0, intFlags;
24262 +
24263 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24264 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24265 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24266 +
24267 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24268 +
24269 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24270 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
24271 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
24272 +
24273 + tmpReg |= TX_SACFG_ACTIVE;
24274 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24275 +
24276 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24277 +
24278 + return err;
24279 +}
24280 +
24281 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24282 +{
24283 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24284 + t_Error err = E_OK;
24285 + uint32_t tmpReg = 0, i, intFlags;
24286 +
24287 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24288 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24289 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24290 +
24291 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24292 +
24293 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24294 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
24295 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
24296 + for (i=0; i<4; i++)
24297 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
24298 +
24299 + tmpReg |= RX_SACFG_ACTIVE;
24300 + tmpReg &= ~RX_SACFG_EN_MASK;
24301 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24302 +
24303 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24304 +
24305 + return err;
24306 +}
24307 +
24308 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
24309 +{
24310 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24311 + t_Error err = E_OK;
24312 + uint32_t tmpReg = 0, i, intFlags;
24313 +
24314 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24315 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24316 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24317 +
24318 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24319 +
24320 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24321 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
24322 + for (i=0; i<4; i++)
24323 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
24324 +
24325 + tmpReg |= TX_SACFG_ACTIVE;
24326 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
24327 +
24328 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24329 +
24330 + return err;
24331 +}
24332 +
24333 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
24334 +{
24335 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24336 + t_Error err = E_OK;
24337 + uint32_t tmpReg = 0, intFlags;
24338 +
24339 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24340 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24341 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24342 +
24343 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24344 +
24345 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24346 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
24347 + if (enableReceive)
24348 + tmpReg |= RX_SACFG_EN_MASK;
24349 + else
24350 + tmpReg &= ~RX_SACFG_EN_MASK;
24351 +
24352 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
24353 +
24354 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24355 +
24356 + return err;
24357 +}
24358 +
24359 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
24360 +{
24361 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24362 + t_Error err = E_OK;
24363 + uint32_t intFlags;
24364 +
24365 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24366 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24367 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24368 +
24369 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24370 +
24371 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24372 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
24373 +
24374 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24375 +
24376 + return err;
24377 +}
24378 +
24379 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
24380 +{
24381 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24382 + t_Error err = E_OK;
24383 + uint32_t intFlags;
24384 +
24385 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24386 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24387 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
24388 +
24389 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
24390 +
24391 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
24392 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
24393 +
24394 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
24395 +
24396 + return err;
24397 +}
24398 +
24399 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
24400 +{
24401 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24402 + t_Error err = E_OK;
24403 + uint32_t tmpReg = 0, intFlags;
24404 +
24405 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24406 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24407 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
24408 +
24409 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24410 +
24411 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24412 +
24413 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24414 +
24415 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
24416 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
24417 +
24418 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
24419 +
24420 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24421 +
24422 + return err;
24423 +}
24424 +
24425 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
24426 +{
24427 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24428 + t_Error err = E_OK;
24429 + uint32_t tmpReg = 0, intFlags;
24430 +
24431 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24432 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
24433 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
24434 +
24435 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
24436 +
24437 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
24438 +
24439 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
24440 +
24441 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
24442 +
24443 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
24444 +
24445 + return err;
24446 +}
24447 +
24448 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
24449 +{
24450 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24451 + uint32_t bitMask;
24452 +
24453 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24454 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24455 +
24456 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
24457 + if (bitMask)
24458 + {
24459 + if (enable)
24460 + p_FmMacsec->exceptions |= bitMask;
24461 + else
24462 + p_FmMacsec->exceptions &= ~bitMask;
24463 + }
24464 + else
24465 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24466 +
24467 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
24468 +
24469 + return E_OK;
24470 +}
24471 +
24472 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
24473 +{
24474 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
24475 + uint32_t bitMask;
24476 +
24477 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
24478 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
24479 +
24480 + GET_EVENT_FLAG(bitMask, event, scId);
24481 + if (bitMask)
24482 + {
24483 + if (enable)
24484 + p_FmMacsec->events |= bitMask;
24485 + else
24486 + p_FmMacsec->events &= ~bitMask;
24487 + }
24488 + else
24489 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
24490 +
24491 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
24492 +
24493 + return E_OK;
24494 +}
24495 +
24496 +/****************************************/
24497 +/* API Init unit functions */
24498 +/****************************************/
24499 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
24500 +{
24501 + t_FmMacsec *p_FmMacsec;
24502 + uint32_t macId;
24503 +
24504 + /* Allocate FM MACSEC structure */
24505 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
24506 + if (!p_FmMacsec)
24507 + {
24508 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
24509 + return NULL;
24510 + }
24511 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
24512 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
24513 +
24514 + /* Allocate the FM MACSEC driver's parameters structure */
24515 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
24516 + if (!p_FmMacsec->p_FmMacsecDriverParam)
24517 + {
24518 + XX_Free(p_FmMacsec);
24519 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
24520 + return NULL;
24521 + }
24522 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
24523 +
24524 + /* Initialize FM MACSEC parameters which will be kept by the driver */
24525 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
24526 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
24527 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
24528 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
24529 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
24530 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
24531 + p_FmMacsec->exceptions = DEFAULT_exceptions;
24532 + p_FmMacsec->events = DEFAULT_events;
24533 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
24534 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
24535 +
24536 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
24537 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
24538 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
24539 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
24540 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
24541 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
24542 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
24543 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
24544 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
24545 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
24546 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
24547 + /* build the FM MACSEC master IPC address */
24548 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
24549 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
24550 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
24551 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
24552 + {
24553 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
24554 + XX_Free(p_FmMacsec);
24555 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
24556 + return NULL;
24557 + }
24558 + return p_FmMacsec;
24559 +}
24560 --- /dev/null
24561 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
24562 @@ -0,0 +1,479 @@
24563 +/*
24564 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24565 + *
24566 + * Redistribution and use in source and binary forms, with or without
24567 + * modification, are permitted provided that the following conditions are met:
24568 + * * Redistributions of source code must retain the above copyright
24569 + * notice, this list of conditions and the following disclaimer.
24570 + * * Redistributions in binary form must reproduce the above copyright
24571 + * notice, this list of conditions and the following disclaimer in the
24572 + * documentation and/or other materials provided with the distribution.
24573 + * * Neither the name of Freescale Semiconductor nor the
24574 + * names of its contributors may be used to endorse or promote products
24575 + * derived from this software without specific prior written permission.
24576 + *
24577 + *
24578 + * ALTERNATIVELY, this software may be distributed under the terms of the
24579 + * GNU General Public License ("GPL") as published by the Free Software
24580 + * Foundation, either version 2 of that License or (at your option) any
24581 + * later version.
24582 + *
24583 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24584 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24585 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24586 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24587 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24588 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24589 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24590 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24591 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24592 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24593 + */
24594 +
24595 +/******************************************************************************
24596 + @File fm_macsec_master.h
24597 +
24598 + @Description FM MACSEC internal structures and definitions.
24599 +*//***************************************************************************/
24600 +#ifndef __FM_MACSEC_MASTER_H
24601 +#define __FM_MACSEC_MASTER_H
24602 +
24603 +#include "error_ext.h"
24604 +#include "std_ext.h"
24605 +
24606 +#include "fm_macsec.h"
24607 +
24608 +
24609 +#define MACSEC_ICV_SIZE 16
24610 +#define MACSEC_SECTAG_SIZE 16
24611 +#define MACSEC_SCI_SIZE 8
24612 +#define MACSEC_FCS_SIZE 4
24613 +
24614 +/**************************************************************************//**
24615 + @Description Exceptions
24616 +*//***************************************************************************/
24617 +
24618 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
24619 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
24620 +#define FM_MACSEC_EX_ECC 0x00000001
24621 +
24622 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
24623 + case e_FM_MACSEC_EX_TX_SC: \
24624 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
24625 + case e_FM_MACSEC_EX_ECC: \
24626 + bitMask = FM_MACSEC_EX_ECC; break; \
24627 + default: bitMask = 0;break;}
24628 +
24629 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
24630 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
24631 +
24632 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24633 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
24634 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
24635 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
24636 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
24637 + default: bitMask = 0;break;}
24638 +
24639 +/**************************************************************************//**
24640 + @Description Events
24641 +*//***************************************************************************/
24642 +
24643 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
24644 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
24645 +
24646 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
24647 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
24648 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
24649 + default: bitMask = 0;break;}
24650 +
24651 +/**************************************************************************//**
24652 + @Description Defaults
24653 +*//***************************************************************************/
24654 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
24655 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
24656 +
24657 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
24658 + FM_MACSEC_EX_TX_SC(1) |\
24659 + FM_MACSEC_EX_TX_SC(2) |\
24660 + FM_MACSEC_EX_TX_SC(3) |\
24661 + FM_MACSEC_EX_TX_SC(4) |\
24662 + FM_MACSEC_EX_TX_SC(5) |\
24663 + FM_MACSEC_EX_TX_SC(6) |\
24664 + FM_MACSEC_EX_TX_SC(7) |\
24665 + FM_MACSEC_EX_TX_SC(8) |\
24666 + FM_MACSEC_EX_TX_SC(9) |\
24667 + FM_MACSEC_EX_TX_SC(10) |\
24668 + FM_MACSEC_EX_TX_SC(11) |\
24669 + FM_MACSEC_EX_TX_SC(12) |\
24670 + FM_MACSEC_EX_TX_SC(13) |\
24671 + FM_MACSEC_EX_TX_SC(14) |\
24672 + FM_MACSEC_EX_TX_SC(15) |\
24673 + FM_MACSEC_EX_ECC )
24674 +
24675 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
24676 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
24677 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
24678 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
24679 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
24680 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
24681 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
24682 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
24683 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
24684 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
24685 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
24686 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
24687 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
24688 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
24689 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
24690 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
24691 +
24692 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
24693 +#define DEFAULT_invalidTagsFrameTreatment FALSE
24694 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
24695 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
24696 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
24697 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
24698 +#define DEFAULT_keysUnreadable FALSE
24699 +#define DEFAULT_normalMode TRUE
24700 +#define DEFAULT_sc0ReservedForPTP FALSE
24701 +#define DEFAULT_initNextPn 1
24702 +#define DEFAULT_pnExhThr 0xffffffff
24703 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
24704 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
24705 +
24706 +
24707 +/**************************************************************************//**
24708 + @Description Memory Mapped Registers
24709 +*//***************************************************************************/
24710 +
24711 +#if defined(__MWERKS__) && !defined(__GNUC__)
24712 +#pragma pack(push,1)
24713 +#endif /* defined(__MWERKS__) && ... */
24714 +
24715 +typedef _Packed struct
24716 +{
24717 + /* MACsec configuration */
24718 + volatile uint32_t cfg; /**< MACsec configuration */
24719 + volatile uint32_t et; /**< MACsec EtherType */
24720 + volatile uint8_t res1[56]; /**< reserved */
24721 + volatile uint32_t mfl; /**< Maximum Frame Length */
24722 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
24723 + volatile uint8_t res2[56]; /**< reserved */
24724 + volatile uint32_t rxsca; /**< RX SC access select */
24725 + volatile uint8_t res3[60]; /**< reserved */
24726 + volatile uint32_t txsca; /**< TX SC access select */
24727 + volatile uint8_t res4[60]; /**< reserved */
24728 +
24729 + /* RX configuration, status and statistic */
24730 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
24731 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
24732 + volatile uint8_t res5[8]; /**< reserved */
24733 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
24734 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
24735 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
24736 + volatile uint8_t res6[4]; /**< reserved */
24737 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
24738 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
24739 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
24740 + volatile uint32_t rpw; /**< replayWindow */
24741 + volatile uint8_t res7[16]; /**< reserved */
24742 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
24743 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
24744 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
24745 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
24746 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
24747 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
24748 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
24749 + volatile uint8_t res8[4]; /**< reserved */
24750 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
24751 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
24752 + _Packed struct
24753 + {
24754 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
24755 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
24756 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
24757 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
24758 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
24759 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
24760 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
24761 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
24762 + volatile uint8_t res9[8]; /**< reserved */
24763 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
24764 +
24765 + /* TX configuration, status and statistic */
24766 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
24767 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
24768 + volatile uint8_t res10[8]; /**< reserved */
24769 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
24770 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
24771 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
24772 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
24773 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
24774 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
24775 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
24776 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
24777 + volatile uint8_t res11[16]; /**< reserved */
24778 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
24779 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
24780 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
24781 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
24782 + volatile uint8_t res12[48]; /**< reserved */
24783 + _Packed struct
24784 + {
24785 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
24786 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
24787 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
24788 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
24789 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
24790 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
24791 + volatile uint8_t res13[16]; /**< reserved */
24792 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
24793 + volatile uint8_t res14[248]; /**< reserved */
24794 +
24795 + /* Global configuration and status */
24796 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
24797 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
24798 + volatile uint32_t evr; /**< MACsec Event Register */
24799 + volatile uint32_t ever; /**< MACsec Event Enable Register */
24800 + volatile uint32_t evfr; /**< MACsec Event Force Register */
24801 + volatile uint32_t err; /**< MACsec Error Register */
24802 + volatile uint32_t erer; /**< MACsec Error Enable Register */
24803 + volatile uint32_t erfr; /**< MACsec Error Force Register */
24804 + volatile uint8_t res15[40]; /**< reserved */
24805 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
24806 + volatile uint32_t idle; /**< MACsec Idle status Register */
24807 + volatile uint8_t res16[184]; /**< reserved */
24808 + /* DEBUG */
24809 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
24810 + volatile uint8_t res17[28]; /**< reserved */
24811 + volatile uint32_t txec; /**< MACsec TX error capture Register */
24812 + volatile uint8_t res18[220]; /**< reserved */
24813 +
24814 + /* Macsec Rx global statistic */
24815 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
24816 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
24817 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
24818 + volatile uint8_t res19[4]; /**< reserved */
24819 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
24820 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
24821 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
24822 + volatile uint8_t res20[4]; /**< reserved */
24823 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
24824 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
24825 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
24826 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
24827 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
24828 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
24829 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
24830 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
24831 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
24832 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
24833 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
24834 + volatile uint8_t res21[52]; /**< reserved */
24835 +
24836 + /* Macsec Tx global statistic */
24837 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
24838 +#if (DPAA_VERSION >= 11)
24839 + volatile uint8_t res22[124]; /**< reserved */
24840 + _Packed struct
24841 + {
24842 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
24843 + volatile uint8_t res23[32]; /**< reserved */
24844 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
24845 + _Packed struct
24846 + {
24847 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
24848 + volatile uint8_t res24[32]; /**< reserved */
24849 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
24850 +#endif /* (DPAA_VERSION >= 11) */
24851 +} _PackedType t_FmMacsecRegs;
24852 +
24853 +#if defined(__MWERKS__) && !defined(__GNUC__)
24854 +#pragma pack(pop)
24855 +#endif /* defined(__MWERKS__) && ... */
24856 +
24857 +
24858 +/**************************************************************************//**
24859 + @Description General defines
24860 +*//***************************************************************************/
24861 +
24862 +#define SCI_HIGH_MASK 0xffffffff00000000LL
24863 +#define SCI_LOW_MASK 0x00000000ffffffffLL
24864 +
24865 +#define LONG_SHIFT 32
24866 +
24867 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
24868 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
24869 +
24870 +/**************************************************************************//**
24871 + @Description Configuration defines
24872 +*//***************************************************************************/
24873 +
24874 +/* masks */
24875 +#define CFG_UECT 0x00000800
24876 +#define CFG_ESCBT 0x00000400
24877 +#define CFG_USFT 0x00000300
24878 +#define CFG_ITT 0x00000080
24879 +#define CFG_KFT 0x00000040
24880 +#define CFG_UFT 0x00000030
24881 +#define CFG_KSS 0x00000004
24882 +#define CFG_BYPN 0x00000002
24883 +#define CFG_S0I 0x00000001
24884 +
24885 +#define ET_TYPE 0x0000ffff
24886 +
24887 +#define MFL_MAX_LEN 0x0000ffff
24888 +
24889 +#define RXSCA_SC_SEL 0x0000000f
24890 +
24891 +#define TXSCA_SC_SEL 0x0000000f
24892 +
24893 +#define IP_REV_1_IP_ID 0xffff0000
24894 +#define IP_REV_1_IP_MJ 0x0000ff00
24895 +#define IP_REV_1_IP_MM 0x000000ff
24896 +
24897 +#define IP_REV_2_IP_INT 0x00ff0000
24898 +#define IP_REV_2_IP_ERR 0x0000ff00
24899 +#define IP_REV_2_IP_CFG 0x000000ff
24900 +
24901 +#define MECC_CAP 0x80000000
24902 +#define MECC_CET 0x40000000
24903 +#define MECC_SERCNT 0x00ff0000
24904 +#define MECC_MEMADDR 0x000001ff
24905 +
24906 +/* shifts */
24907 +#define CFG_UECT_SHIFT (31-20)
24908 +#define CFG_ESCBT_SHIFT (31-21)
24909 +#define CFG_USFT_SHIFT (31-23)
24910 +#define CFG_ITT_SHIFT (31-24)
24911 +#define CFG_KFT_SHIFT (31-25)
24912 +#define CFG_UFT_SHIFT (31-27)
24913 +#define CFG_KSS_SHIFT (31-29)
24914 +#define CFG_BYPN_SHIFT (31-30)
24915 +#define CFG_S0I_SHIFT (31-31)
24916 +
24917 +#define IP_REV_1_IP_ID_SHIFT (31-15)
24918 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
24919 +#define IP_REV_1_IP_MM_SHIFT (31-31)
24920 +
24921 +#define IP_REV_2_IP_INT_SHIFT (31-15)
24922 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
24923 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
24924 +
24925 +#define MECC_CAP_SHIFT (31-0)
24926 +#define MECC_CET_SHIFT (31-1)
24927 +#define MECC_SERCNT_SHIFT (31-15)
24928 +#define MECC_MEMADDR_SHIFT (31-31)
24929 +
24930 +/**************************************************************************//**
24931 + @Description RX SC defines
24932 +*//***************************************************************************/
24933 +
24934 +/* masks */
24935 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
24936 +#define RX_SCCFG_RP_MASK 0x00000400
24937 +#define RX_SCCFG_VF_MASK 0x00000300
24938 +#define RX_SCCFG_CO_MASK 0x0000003f
24939 +
24940 +/* shifts */
24941 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
24942 +#define RX_SCCFG_RP_SHIFT (31-21)
24943 +#define RX_SCCFG_VF_SHIFT (31-23)
24944 +#define RX_SCCFG_CO_SHIFT (31-31)
24945 +#define RX_SCCFG_CS_SHIFT (31-7)
24946 +
24947 +/**************************************************************************//**
24948 + @Description RX SA defines
24949 +*//***************************************************************************/
24950 +
24951 +/* masks */
24952 +#define RX_SACFG_ACTIVE 0x80000000
24953 +#define RX_SACFG_AN_MASK 0x00000006
24954 +#define RX_SACFG_EN_MASK 0x00000001
24955 +
24956 +/* shifts */
24957 +#define RX_SACFG_AN_SHIFT (31-30)
24958 +#define RX_SACFG_EN_SHIFT (31-31)
24959 +
24960 +/**************************************************************************//**
24961 + @Description TX SC defines
24962 +*//***************************************************************************/
24963 +
24964 +/* masks */
24965 +#define TX_SCCFG_AN_MASK 0x000c0000
24966 +#define TX_SCCFG_ASA_MASK 0x00020000
24967 +#define TX_SCCFG_SCE_MASK 0x00010000
24968 +#define TX_SCCFG_CO_MASK 0x00003f00
24969 +#define TX_SCCFG_CE_MASK 0x00000010
24970 +#define TX_SCCFG_PF_MASK 0x00000008
24971 +#define TX_SCCFG_AIS_MASK 0x00000004
24972 +#define TX_SCCFG_UES_MASK 0x00000002
24973 +#define TX_SCCFG_USCB_MASK 0x00000001
24974 +
24975 +/* shifts */
24976 +#define TX_SCCFG_AN_SHIFT (31-13)
24977 +#define TX_SCCFG_ASA_SHIFT (31-14)
24978 +#define TX_SCCFG_SCE_SHIFT (31-15)
24979 +#define TX_SCCFG_CO_SHIFT (31-23)
24980 +#define TX_SCCFG_CE_SHIFT (31-27)
24981 +#define TX_SCCFG_PF_SHIFT (31-28)
24982 +#define TX_SCCFG_AIS_SHIFT (31-29)
24983 +#define TX_SCCFG_UES_SHIFT (31-30)
24984 +#define TX_SCCFG_USCB_SHIFT (31-31)
24985 +#define TX_SCCFG_CS_SHIFT (31-7)
24986 +
24987 +/**************************************************************************//**
24988 + @Description TX SA defines
24989 +*//***************************************************************************/
24990 +
24991 +/* masks */
24992 +#define TX_SACFG_ACTIVE 0x80000000
24993 +
24994 +
24995 +typedef struct
24996 +{
24997 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
24998 + t_Handle h_SrcHandle;
24999 +} t_FmMacsecIntrSrc;
25000 +
25001 +typedef struct
25002 +{
25003 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
25004 + bool invalidTagsDeliverUncontrolled;
25005 + bool changedTextWithNoEncryptDeliverUncontrolled;
25006 + bool onlyScbIsSetDeliverUncontrolled;
25007 + bool encryptWithNoChangedTextDiscardUncontrolled;
25008 + e_FmMacsecUntagFrameTreatment untagTreatMode;
25009 + uint32_t pnExhThr;
25010 + bool keysUnreadable;
25011 + bool byPassMode;
25012 + bool reservedSc0;
25013 + uint32_t sectagOverhead;
25014 + uint32_t mflSubtract;
25015 +} t_FmMacsecDriverParam;
25016 +
25017 +typedef struct
25018 +{
25019 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
25020 + t_Handle h_Fm;
25021 + t_FmMacsecRegs *p_FmMacsecRegs;
25022 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
25023 + char fmMacsecModuleName[MODULE_NAME_SIZE];
25024 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
25025 + uint32_t events;
25026 + uint32_t exceptions;
25027 + uint32_t userExceptions;
25028 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
25029 + t_Handle h_App; /**< A handle to an application layer object; This handle will
25030 + be passed by the driver upon calling the above callbacks */
25031 + bool rxScTable[NUM_OF_RX_SC];
25032 + uint32_t numRxScAvailable;
25033 + bool txScTable[NUM_OF_TX_SC];
25034 + uint32_t numTxScAvailable;
25035 + t_Handle rxScSpinLock;
25036 + t_Handle txScSpinLock;
25037 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
25038 +} t_FmMacsec;
25039 +
25040 +
25041 +#endif /* __FM_MACSEC_MASTER_H */
25042 --- /dev/null
25043 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
25044 @@ -0,0 +1,883 @@
25045 +/*
25046 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25047 + *
25048 + * Redistribution and use in source and binary forms, with or without
25049 + * modification, are permitted provided that the following conditions are met:
25050 + * * Redistributions of source code must retain the above copyright
25051 + * notice, this list of conditions and the following disclaimer.
25052 + * * Redistributions in binary form must reproduce the above copyright
25053 + * notice, this list of conditions and the following disclaimer in the
25054 + * documentation and/or other materials provided with the distribution.
25055 + * * Neither the name of Freescale Semiconductor nor the
25056 + * names of its contributors may be used to endorse or promote products
25057 + * derived from this software without specific prior written permission.
25058 + *
25059 + *
25060 + * ALTERNATIVELY, this software may be distributed under the terms of the
25061 + * GNU General Public License ("GPL") as published by the Free Software
25062 + * Foundation, either version 2 of that License or (at your option) any
25063 + * later version.
25064 + *
25065 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25066 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25067 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25068 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25069 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25070 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25071 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25072 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25073 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25074 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25075 + */
25076 +
25077 +/******************************************************************************
25078 + @File fm_macsec_secy.c
25079 +
25080 + @Description FM MACSEC SECY driver routines implementation.
25081 +*//***************************************************************************/
25082 +
25083 +#include "std_ext.h"
25084 +#include "error_ext.h"
25085 +#include "xx_ext.h"
25086 +#include "string_ext.h"
25087 +#include "sprint_ext.h"
25088 +
25089 +#include "fm_macsec_secy.h"
25090 +
25091 +
25092 +/****************************************/
25093 +/* static functions */
25094 +/****************************************/
25095 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
25096 +{
25097 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25098 +
25099 + UNUSED(id);
25100 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
25101 +
25102 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25103 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
25104 +}
25105 +
25106 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
25107 +{
25108 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25109 +
25110 + UNUSED(id);
25111 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
25112 +
25113 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25114 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
25115 +}
25116 +
25117 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
25118 +{
25119 + if (!p_FmMacsecSecY->f_Exception)
25120 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
25121 +
25122 + if (!p_FmMacsecSecY->f_Event)
25123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
25124 +
25125 + if (!p_FmMacsecSecY->numOfRxSc)
25126 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
25127 +
25128 +
25129 + return E_OK;
25130 +}
25131 +
25132 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
25133 + macsecSCI_t sci,
25134 + e_FmMacsecSecYCipherSuite cipherSuite,
25135 + e_ScType type)
25136 +{
25137 + t_SecYSc *p_ScTable;
25138 + void *p_Params;
25139 + uint32_t numOfSc,i;
25140 + t_Error err = E_OK;
25141 + t_RxScParams rxScParams;
25142 + t_TxScParams txScParams;
25143 +
25144 + ASSERT_COND(p_FmMacsecSecY);
25145 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25146 +
25147 + if (type == e_SC_RX)
25148 + {
25149 + memset(&rxScParams, 0, sizeof(rxScParams));
25150 + i = (NUM_OF_RX_SC - 1);
25151 + p_ScTable = p_FmMacsecSecY->p_RxSc;
25152 + numOfSc = p_FmMacsecSecY->numOfRxSc;
25153 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
25154 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
25155 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
25156 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
25157 + rxScParams.cipherSuite = cipherSuite;
25158 + p_Params = &rxScParams;
25159 + }
25160 + else
25161 + {
25162 + memset(&txScParams, 0, sizeof(txScParams));
25163 + i = (NUM_OF_TX_SC - 1);
25164 + p_ScTable = p_FmMacsecSecY->p_TxSc;
25165 + numOfSc = p_FmMacsecSecY->numOfTxSc;
25166 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
25167 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
25168 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
25169 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
25170 + txScParams.cipherSuite = cipherSuite;
25171 + p_Params = &txScParams;
25172 + }
25173 +
25174 + for (i=0;i<numOfSc;i++)
25175 + if (!p_ScTable[i].inUse)
25176 + break;
25177 + if (i == numOfSc)
25178 + {
25179 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
25180 + return NULL;
25181 + }
25182 +
25183 + if (type == e_SC_RX)
25184 + {
25185 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
25186 + ((t_RxScParams *)p_Params)->sci = sci;
25187 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
25188 + {
25189 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25190 + return NULL;
25191 + }
25192 + }
25193 + else
25194 + {
25195 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
25196 + ((t_TxScParams *)p_Params)->sci = sci;
25197 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
25198 + {
25199 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25200 + return NULL;
25201 + }
25202 + }
25203 +
25204 + p_ScTable[i].inUse = TRUE;
25205 + return &p_ScTable[i];
25206 +}
25207 +
25208 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
25209 +{
25210 + t_Error err = E_OK;
25211 +
25212 + ASSERT_COND(p_FmMacsecSecY);
25213 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
25214 + ASSERT_COND(p_FmSecYSc);
25215 +
25216 + if (type == e_SC_RX)
25217 + {
25218 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25219 + RETURN_ERROR(MINOR, err, NO_MSG);
25220 + }
25221 + else
25222 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
25223 + RETURN_ERROR(MINOR, err, NO_MSG);
25224 +
25225 + p_FmSecYSc->inUse = FALSE;
25226 +
25227 + return err;
25228 +}
25229 +
25230 +/****************************************/
25231 +/* API Init unit functions */
25232 +/****************************************/
25233 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
25234 +{
25235 + t_FmMacsecSecY *p_FmMacsecSecY;
25236 +
25237 + /* Allocate FM MACSEC structure */
25238 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
25239 + if (!p_FmMacsecSecY)
25240 + {
25241 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
25242 + return NULL;
25243 + }
25244 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
25245 +
25246 + /* Allocate the FM MACSEC driver's parameters structure */
25247 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
25248 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
25249 + {
25250 + XX_Free(p_FmMacsecSecY);
25251 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
25252 + return NULL;
25253 + }
25254 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
25255 +
25256 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
25257 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
25258 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
25259 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
25260 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
25261 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
25262 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
25263 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
25264 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
25265 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
25266 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
25267 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
25268 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
25269 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
25270 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
25271 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
25272 + p_FmMacsecSecY->events = DEFAULT_events;
25273 +
25274 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
25275 + &p_FmMacsecSecYParam->txScParams,
25276 + sizeof(t_FmMacsecSecYSCParams));
25277 + return p_FmMacsecSecY;
25278 +}
25279 +
25280 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
25281 +{
25282 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25283 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
25284 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
25285 + t_Error err;
25286 +
25287 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25288 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
25289 +
25290 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
25291 +
25292 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
25293 +
25294 + if ((p_FmMacsecSecY->isPointToPoint) &&
25295 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
25296 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
25297 +
25298 + /* Rx Sc Allocation */
25299 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25300 + if (!p_FmMacsecSecY->p_RxSc)
25301 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
25302 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
25303 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25304 + {
25305 + if (p_FmMacsecSecY->p_TxSc)
25306 + XX_Free(p_FmMacsecSecY->p_TxSc);
25307 + if (p_FmMacsecSecY->p_RxSc)
25308 + XX_Free(p_FmMacsecSecY->p_RxSc);
25309 + return ERROR_CODE(err);
25310 + }
25311 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25312 + {
25313 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
25314 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
25315 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25316 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25317 + }
25318 +
25319 + /* Tx Sc Allocation */
25320 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25321 + if (!p_FmMacsecSecY->p_TxSc)
25322 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
25323 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
25324 +
25325 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25326 + {
25327 + if (p_FmMacsecSecY->p_TxSc)
25328 + XX_Free(p_FmMacsecSecY->p_TxSc);
25329 + if (p_FmMacsecSecY->p_RxSc)
25330 + XX_Free(p_FmMacsecSecY->p_RxSc);
25331 + return ERROR_CODE(err);
25332 + }
25333 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
25334 + {
25335 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
25336 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
25337 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
25338 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25339 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25340 + e_FM_MACSEC_MOD_SC_TX,
25341 + (uint8_t)txScIds[i],
25342 + e_FM_INTR_TYPE_ERR,
25343 + FmMacsecSecYExceptionsIsr,
25344 + p_FmMacsecSecY);
25345 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
25346 + e_FM_MACSEC_MOD_SC_TX,
25347 + (uint8_t)txScIds[i],
25348 + e_FM_INTR_TYPE_NORMAL,
25349 + FmMacsecSecYEventsIsr,
25350 + p_FmMacsecSecY);
25351 +
25352 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25353 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
25354 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25355 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
25356 + }
25357 +
25358 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
25359 + p_FmMacsecSecYDriverParam->txScParams.sci,
25360 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
25361 + e_SC_TX);
25362 + XX_Free(p_FmMacsecSecYDriverParam);
25363 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
25364 +
25365 + return E_OK;
25366 +}
25367 +
25368 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
25369 +{
25370 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25371 + t_Error err = E_OK;
25372 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
25373 +
25374 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25375 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25376 +
25377 + if (p_FmMacsecSecY->isPointToPoint)
25378 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
25379 + if (p_FmMacsecSecY->p_RxSc)
25380 + {
25381 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
25382 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
25383 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
25384 + return ERROR_CODE(err);
25385 + XX_Free(p_FmMacsecSecY->p_RxSc);
25386 + }
25387 + if (p_FmMacsecSecY->p_TxSc)
25388 + {
25389 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
25390 +
25391 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
25392 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
25393 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25394 + e_FM_MACSEC_MOD_SC_TX,
25395 + (uint8_t)txScIds[i],
25396 + e_FM_INTR_TYPE_ERR);
25397 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
25398 + e_FM_MACSEC_MOD_SC_TX,
25399 + (uint8_t)txScIds[i],
25400 + e_FM_INTR_TYPE_NORMAL);
25401 +
25402 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
25403 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
25404 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
25405 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
25406 + }
25407 +
25408 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
25409 + return ERROR_CODE(err);
25410 + XX_Free(p_FmMacsecSecY->p_TxSc);
25411 + }
25412 +
25413 + XX_Free(p_FmMacsecSecY);
25414 +
25415 + return err;
25416 +}
25417 +
25418 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
25419 +{
25420 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25421 +
25422 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25423 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25424 +
25425 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
25426 +
25427 + return E_OK;
25428 +}
25429 +
25430 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
25431 +{
25432 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25433 +
25434 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25435 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25436 +
25437 + p_FmMacsecSecY->protectFrames = protectFrames;
25438 +
25439 + return E_OK;
25440 +}
25441 +
25442 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
25443 +{
25444 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25445 +
25446 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25447 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25448 +
25449 + p_FmMacsecSecY->replayProtect = replayProtect;
25450 + p_FmMacsecSecY->replayWindow = replayWindow;
25451 +
25452 + return E_OK;
25453 +}
25454 +
25455 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
25456 +{
25457 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25458 +
25459 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25460 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25461 +
25462 + p_FmMacsecSecY->validateFrames = validateFrames;
25463 +
25464 + return E_OK;
25465 +}
25466 +
25467 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
25468 +{
25469 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25470 +
25471 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25472 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25473 +
25474 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
25475 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
25476 +
25477 + return E_OK;
25478 +}
25479 +
25480 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
25481 +{
25482 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25483 +
25484 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25485 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25486 +
25487 + p_FmMacsecSecY->numOfRxSc = 1;
25488 + p_FmMacsecSecY->isPointToPoint = TRUE;
25489 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
25490 +
25491 + return E_OK;
25492 +}
25493 +
25494 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
25495 +{
25496 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25497 + uint32_t bitMask = 0;
25498 +
25499 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25500 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25501 +
25502 + GET_EXCEPTION_FLAG(bitMask, exception);
25503 + if (bitMask)
25504 + {
25505 + if (enable)
25506 + p_FmMacsecSecY->exceptions |= bitMask;
25507 + else
25508 + p_FmMacsecSecY->exceptions &= ~bitMask;
25509 + }
25510 + else
25511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25512 +
25513 + return E_OK;
25514 +}
25515 +
25516 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25517 +{
25518 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25519 + uint32_t bitMask = 0;
25520 +
25521 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25522 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25523 +
25524 + GET_EVENT_FLAG(bitMask, event);
25525 + if (bitMask)
25526 + {
25527 + if (enable)
25528 + p_FmMacsecSecY->events |= bitMask;
25529 + else
25530 + p_FmMacsecSecY->events &= ~bitMask;
25531 + }
25532 + else
25533 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
25534 +
25535 + return E_OK;
25536 +}
25537 +
25538 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
25539 +{
25540 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25541 +
25542 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
25543 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
25544 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
25545 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
25546 +
25547 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
25548 +}
25549 +
25550 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
25551 +{
25552 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25553 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25554 +
25555 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25556 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25557 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25558 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25559 +
25560 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
25561 +}
25562 +
25563 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25564 +{
25565 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25566 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25567 + t_Error err = E_OK;
25568 +
25569 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25570 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25571 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25572 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25573 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25574 +
25575 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25576 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
25577 +
25578 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
25579 + RETURN_ERROR(MINOR, err, NO_MSG);
25580 +
25581 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25582 + return err;
25583 +}
25584 +
25585 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25586 +{
25587 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25588 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25589 + t_Error err = E_OK;
25590 +
25591 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25592 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25593 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25594 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25595 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25596 +
25597 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25598 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25599 +
25600 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25601 + RETURN_ERROR(MINOR, err, NO_MSG);
25602 +
25603 + p_FmSecYSc->numOfSa--;
25604 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25605 + /* TODO - check if statistics need to be read*/
25606 + return err;
25607 +}
25608 +
25609 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25610 +{
25611 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25612 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25613 + t_Error err = E_OK;
25614 +
25615 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25616 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25617 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25618 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25619 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25620 +
25621 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25622 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25623 +
25624 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25625 + RETURN_ERROR(MINOR, err, NO_MSG);
25626 +
25627 + p_FmSecYSc->sa[an].active = TRUE;
25628 + return err;
25629 +}
25630 +
25631 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
25632 +{
25633 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25634 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25635 + t_Error err = E_OK;
25636 +
25637 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25638 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25639 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25640 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25641 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25642 +
25643 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25644 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25645 +
25646 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25647 + RETURN_ERROR(MINOR, err, NO_MSG);
25648 +
25649 + p_FmSecYSc->sa[an].active = FALSE;
25650 + return err;
25651 +}
25652 +
25653 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
25654 +{
25655 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25656 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25657 + t_Error err = E_OK;
25658 +
25659 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25660 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25661 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25662 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25663 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25664 +
25665 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25666 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25667 +
25668 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
25669 + RETURN_ERROR(MINOR, err, NO_MSG);
25670 +
25671 + return err;
25672 +}
25673 +
25674 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
25675 +{
25676 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25677 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25678 + t_Error err = E_OK;
25679 +
25680 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25681 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25682 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25683 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25684 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25685 +
25686 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25687 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25688 +
25689 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
25690 + RETURN_ERROR(MINOR, err, NO_MSG);
25691 +
25692 + return err;
25693 +}
25694 +
25695 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
25696 +{
25697 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25698 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25699 + t_Error err = E_OK;
25700 +
25701 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25702 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25703 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25704 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25705 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25706 +
25707 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25708 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25709 +
25710 + if (p_FmSecYSc->sa[an].active)
25711 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
25712 + RETURN_ERROR(MINOR, err, NO_MSG);
25713 +
25714 + /* TODO - statistics should be read */
25715 +
25716 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
25717 + RETURN_ERROR(MINOR, err, NO_MSG);
25718 +
25719 + if (p_FmSecYSc->sa[an].active)
25720 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
25721 + RETURN_ERROR(MINOR, err, NO_MSG);
25722 + return err;
25723 +}
25724 +
25725 +
25726 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
25727 +{
25728 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25729 + t_SecYSc *p_FmSecYSc;
25730 + t_Error err = E_OK;
25731 +
25732 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25733 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25734 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25735 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25736 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25737 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25738 +
25739 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
25740 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
25741 +
25742 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
25743 + RETURN_ERROR(MINOR, err, NO_MSG);
25744 +
25745 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
25746 + return err;
25747 +}
25748 +
25749 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
25750 +{
25751 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25752 + t_SecYSc *p_FmSecYSc;
25753 + t_Error err = E_OK;
25754 +
25755 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25756 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25757 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25758 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25759 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25760 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25761 +
25762 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25763 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
25764 +
25765 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
25766 + RETURN_ERROR(MINOR, err, NO_MSG);
25767 +
25768 + p_FmSecYSc->numOfSa--;
25769 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
25770 + /* TODO - check if statistics need to be read*/
25771 + return err;
25772 +}
25773 +
25774 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
25775 +{
25776 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25777 + t_SecYSc *p_FmSecYSc;
25778 + macsecAN_t currentAn;
25779 + t_Error err = E_OK;
25780 +
25781 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25782 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25783 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25784 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25785 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25786 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25787 +
25788 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25789 + p_FmSecYSc->scId,
25790 + &currentAn)) != E_OK)
25791 + RETURN_ERROR(MINOR, err, NO_MSG);
25792 +
25793 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25794 + p_FmSecYSc->scId,
25795 + p_FmSecYSc->sa[nextActiveAn].saId,
25796 + nextActiveAn)) != E_OK)
25797 + RETURN_ERROR(MINOR, err, NO_MSG);
25798 +
25799 + /* TODO - statistics should be read */
25800 +
25801 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
25802 + RETURN_ERROR(MINOR, err, NO_MSG);
25803 +
25804 + return err;
25805 +}
25806 +
25807 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
25808 +{
25809 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25810 + t_SecYSc *p_FmSecYSc;
25811 + t_Error err = E_OK;
25812 +
25813 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25814 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25815 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25816 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25817 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25818 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
25819 +
25820 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
25821 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
25822 +
25823 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
25824 + p_FmSecYSc->scId,
25825 + p_FmSecYSc->sa[an].saId,
25826 + an)) != E_OK)
25827 + RETURN_ERROR(MINOR, err, NO_MSG);
25828 +
25829 + return err;
25830 +}
25831 +
25832 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
25833 +{
25834 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25835 + t_SecYSc *p_FmSecYSc;
25836 + t_Error err = E_OK;
25837 +
25838 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25839 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25840 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25841 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25842 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25843 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
25844 +
25845 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
25846 + p_FmSecYSc->scId,
25847 + p_An)) != E_OK)
25848 + RETURN_ERROR(MINOR, err, NO_MSG);
25849 +
25850 + return err;
25851 +}
25852 +
25853 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
25854 +{
25855 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
25856 + t_Error err = E_OK;
25857 +
25858 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
25859 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
25860 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25861 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25862 +#ifdef DISABLE_SANITY_CHECKS
25863 + UNUSED(h_FmMacsecSecY);
25864 +#endif /* DISABLE_SANITY_CHECKS */
25865 +
25866 + *p_ScPhysId = p_FmSecYSc->scId;
25867 + return err;
25868 +}
25869 +
25870 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
25871 +{
25872 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
25873 + t_SecYSc *p_FmSecYSc;
25874 + t_Error err = E_OK;
25875 +
25876 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
25877 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
25878 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
25879 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
25880 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
25881 +
25882 + *p_ScPhysId = p_FmSecYSc->scId;
25883 + return err;
25884 +}
25885 +
25886 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
25887 +{
25888 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
25889 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25890 +}
25891 +
25892 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
25893 +{
25894 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
25895 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25896 +}
25897 +
25898 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
25899 +{
25900 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25901 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25902 +}
25903 +
25904 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
25905 +{
25906 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
25907 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25908 +}
25909 +
25910 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
25911 +{
25912 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
25913 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25914 +}
25915 +
25916 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
25917 +{
25918 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
25919 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25920 +}
25921 +
25922 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
25923 +{
25924 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
25925 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
25926 +}
25927 +
25928 --- /dev/null
25929 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
25930 @@ -0,0 +1,144 @@
25931 +/*
25932 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25933 + *
25934 + * Redistribution and use in source and binary forms, with or without
25935 + * modification, are permitted provided that the following conditions are met:
25936 + * * Redistributions of source code must retain the above copyright
25937 + * notice, this list of conditions and the following disclaimer.
25938 + * * Redistributions in binary form must reproduce the above copyright
25939 + * notice, this list of conditions and the following disclaimer in the
25940 + * documentation and/or other materials provided with the distribution.
25941 + * * Neither the name of Freescale Semiconductor nor the
25942 + * names of its contributors may be used to endorse or promote products
25943 + * derived from this software without specific prior written permission.
25944 + *
25945 + *
25946 + * ALTERNATIVELY, this software may be distributed under the terms of the
25947 + * GNU General Public License ("GPL") as published by the Free Software
25948 + * Foundation, either version 2 of that License or (at your option) any
25949 + * later version.
25950 + *
25951 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25952 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25953 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25954 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25955 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25956 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25957 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25958 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25959 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25960 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25961 + */
25962 +
25963 +/******************************************************************************
25964 + @File fm_macsec_secy.h
25965 +
25966 + @Description FM MACSEC SecY internal structures and definitions.
25967 +*//***************************************************************************/
25968 +#ifndef __FM_MACSEC_SECY_H
25969 +#define __FM_MACSEC_SECY_H
25970 +
25971 +#include "error_ext.h"
25972 +#include "std_ext.h"
25973 +
25974 +#include "fm_macsec.h"
25975 +
25976 +
25977 +/**************************************************************************//**
25978 + @Description Exceptions
25979 +*//***************************************************************************/
25980 +
25981 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
25982 +
25983 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
25984 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
25985 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
25986 + default: bitMask = 0;break;}
25987 +
25988 +/**************************************************************************//**
25989 + @Description Events
25990 +*//***************************************************************************/
25991 +
25992 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
25993 +
25994 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
25995 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
25996 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
25997 + default: bitMask = 0;break;}
25998 +
25999 +/**************************************************************************//**
26000 + @Description Defaults
26001 +*//***************************************************************************/
26002 +
26003 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
26004 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
26005 +#define DEFAULT_numOfTxSc 1
26006 +#define DEFAULT_confidentialityEnable FALSE
26007 +#define DEFAULT_confidentialityOffset 0
26008 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
26009 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
26010 +#define DEFAULT_replayEnable FALSE
26011 +#define DEFAULT_replayWindow 0
26012 +#define DEFAULT_protectFrames TRUE
26013 +#define DEFAULT_ptp FALSE
26014 +
26015 +/**************************************************************************//**
26016 + @Description General defines
26017 +*//***************************************************************************/
26018 +
26019 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
26020 +
26021 +
26022 +typedef struct {
26023 + e_ScSaId saId;
26024 + bool active;
26025 + union {
26026 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
26027 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
26028 + };
26029 +} t_SecYSa;
26030 +
26031 +typedef struct {
26032 + bool inUse;
26033 + uint32_t scId;
26034 + e_ScType type;
26035 + uint8_t numOfSa;
26036 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
26037 + union {
26038 + t_FmMacsecSecYRxScStatistics rxScStatistics;
26039 + t_FmMacsecSecYTxScStatistics txScStatistics;
26040 + };
26041 +} t_SecYSc;
26042 +
26043 +typedef struct {
26044 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
26045 +} t_FmMacsecSecYDriverParam;
26046 +
26047 +typedef struct {
26048 + t_Handle h_FmMacsec;
26049 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
26050 + FALSE - no confidentiality protection, only integrity protection*/
26051 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
26052 + common values are 0, 30, and 50 */
26053 + bool replayProtect; /**< replay protection function mode */
26054 + uint32_t replayWindow; /**< the size of the replay window */
26055 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
26056 + e_FmMacsecSciInsertionMode sciInsertionMode;
26057 + bool protectFrames;
26058 + bool isPointToPoint;
26059 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
26060 + uint32_t numOfRxSc; /**< Number of receive channels */
26061 + uint32_t numOfTxSc; /**< Number of transmit channels */
26062 + t_SecYSc *p_RxSc;
26063 + t_SecYSc *p_TxSc;
26064 + uint32_t events;
26065 + uint32_t exceptions;
26066 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
26067 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
26068 + t_Handle h_App;
26069 + t_FmMacsecSecYStatistics statistics;
26070 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
26071 +} t_FmMacsecSecY;
26072 +
26073 +
26074 +#endif /* __FM_MACSEC_SECY_H */
26075 --- /dev/null
26076 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
26077 @@ -0,0 +1,23 @@
26078 +#
26079 +# Makefile for the Freescale Ethernet controllers
26080 +#
26081 +ccflags-y += -DVERSION=\"\"
26082 +#
26083 +#Include netcomm SW specific definitions
26084 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
26085 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
26086 +
26087 +ccflags-y += -I$(NCSW_FM_INC)
26088 +
26089 +
26090 +obj-y += fsl-ncsw-PFM1.o
26091 +
26092 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
26093 +
26094 +obj-y += MAC/
26095 +obj-y += Pcd/
26096 +obj-y += SP/
26097 +obj-y += Port/
26098 +obj-y += HC/
26099 +obj-y += Rtc/
26100 +obj-y += MACSEC/
26101 --- /dev/null
26102 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
26103 @@ -0,0 +1,26 @@
26104 +#
26105 +# Makefile for the Freescale Ethernet controllers
26106 +#
26107 +ccflags-y += -DVERSION=\"\"
26108 +#
26109 +#Include netcomm SW specific definitions
26110 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
26111 +
26112 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
26113 +
26114 +ccflags-y += -I$(NCSW_FM_INC)
26115 +
26116 +obj-y += fsl-ncsw-Pcd.o
26117 +
26118 +fsl-ncsw-Pcd-objs := fman_kg.o fman_prs.o fm_cc.o fm_kg.o fm_pcd.o fm_plcr.o fm_prs.o fm_manip.o
26119 +
26120 +ifeq ($(CONFIG_FMAN_V3H),y)
26121 +fsl-ncsw-Pcd-objs += fm_replic.o
26122 +endif
26123 +ifeq ($(CONFIG_FMAN_V3L),y)
26124 +fsl-ncsw-Pcd-objs += fm_replic.o
26125 +endif
26126 +ifeq ($(CONFIG_FMAN_ARM),y)
26127 +fsl-ncsw-Pcd-objs += fm_replic.o
26128 +endif
26129 +
26130 --- /dev/null
26131 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
26132 @@ -0,0 +1,360 @@
26133 +/*
26134 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26135 + *
26136 + * Redistribution and use in source and binary forms, with or without
26137 + * modification, are permitted provided that the following conditions are met:
26138 + * * Redistributions of source code must retain the above copyright
26139 + * notice, this list of conditions and the following disclaimer.
26140 + * * Redistributions in binary form must reproduce the above copyright
26141 + * notice, this list of conditions and the following disclaimer in the
26142 + * documentation and/or other materials provided with the distribution.
26143 + * * Neither the name of Freescale Semiconductor nor the
26144 + * names of its contributors may be used to endorse or promote products
26145 + * derived from this software without specific prior written permission.
26146 + *
26147 + *
26148 + * ALTERNATIVELY, this software may be distributed under the terms of the
26149 + * GNU General Public License ("GPL") as published by the Free Software
26150 + * Foundation, either version 2 of that License or (at your option) any
26151 + * later version.
26152 + *
26153 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26154 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26155 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26156 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26157 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26158 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26159 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26160 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26161 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26162 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26163 + */
26164 +
26165 +
26166 + /**************************************************************************//**
26167 + @File crc64.h
26168 +
26169 + @Description brief This file contains the CRC64 Table, and __inline__
26170 + functions used for calculating crc.
26171 +*//***************************************************************************/
26172 +#ifndef __CRC64_H
26173 +#define __CRC64_H
26174 +
26175 +#include "std_ext.h"
26176 +
26177 +
26178 +#define BITS_PER_BYTE 8
26179 +
26180 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
26181 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
26182 +
26183 +#define CRC64_BYTE_MASK 0xFF
26184 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
26185 +#define CRC64_ODD_MASK 1
26186 +
26187 +
26188 +/**
26189 + \brief '64 bit crc' Table
26190 + */
26191 +struct crc64_t {
26192 + uint64_t initial; /**< Initial seed */
26193 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
26194 +};
26195 +
26196 +
26197 +static struct crc64_t CRC64_ECMA_182 = {
26198 + CRC64_DEFAULT_INITVAL,
26199 + {
26200 + 0x0000000000000000ULL,
26201 + 0xb32e4cbe03a75f6fULL,
26202 + 0xf4843657a840a05bULL,
26203 + 0x47aa7ae9abe7ff34ULL,
26204 + 0x7bd0c384ff8f5e33ULL,
26205 + 0xc8fe8f3afc28015cULL,
26206 + 0x8f54f5d357cffe68ULL,
26207 + 0x3c7ab96d5468a107ULL,
26208 + 0xf7a18709ff1ebc66ULL,
26209 + 0x448fcbb7fcb9e309ULL,
26210 + 0x0325b15e575e1c3dULL,
26211 + 0xb00bfde054f94352ULL,
26212 + 0x8c71448d0091e255ULL,
26213 + 0x3f5f08330336bd3aULL,
26214 + 0x78f572daa8d1420eULL,
26215 + 0xcbdb3e64ab761d61ULL,
26216 + 0x7d9ba13851336649ULL,
26217 + 0xceb5ed8652943926ULL,
26218 + 0x891f976ff973c612ULL,
26219 + 0x3a31dbd1fad4997dULL,
26220 + 0x064b62bcaebc387aULL,
26221 + 0xb5652e02ad1b6715ULL,
26222 + 0xf2cf54eb06fc9821ULL,
26223 + 0x41e11855055bc74eULL,
26224 + 0x8a3a2631ae2dda2fULL,
26225 + 0x39146a8fad8a8540ULL,
26226 + 0x7ebe1066066d7a74ULL,
26227 + 0xcd905cd805ca251bULL,
26228 + 0xf1eae5b551a2841cULL,
26229 + 0x42c4a90b5205db73ULL,
26230 + 0x056ed3e2f9e22447ULL,
26231 + 0xb6409f5cfa457b28ULL,
26232 + 0xfb374270a266cc92ULL,
26233 + 0x48190ecea1c193fdULL,
26234 + 0x0fb374270a266cc9ULL,
26235 + 0xbc9d3899098133a6ULL,
26236 + 0x80e781f45de992a1ULL,
26237 + 0x33c9cd4a5e4ecdceULL,
26238 + 0x7463b7a3f5a932faULL,
26239 + 0xc74dfb1df60e6d95ULL,
26240 + 0x0c96c5795d7870f4ULL,
26241 + 0xbfb889c75edf2f9bULL,
26242 + 0xf812f32ef538d0afULL,
26243 + 0x4b3cbf90f69f8fc0ULL,
26244 + 0x774606fda2f72ec7ULL,
26245 + 0xc4684a43a15071a8ULL,
26246 + 0x83c230aa0ab78e9cULL,
26247 + 0x30ec7c140910d1f3ULL,
26248 + 0x86ace348f355aadbULL,
26249 + 0x3582aff6f0f2f5b4ULL,
26250 + 0x7228d51f5b150a80ULL,
26251 + 0xc10699a158b255efULL,
26252 + 0xfd7c20cc0cdaf4e8ULL,
26253 + 0x4e526c720f7dab87ULL,
26254 + 0x09f8169ba49a54b3ULL,
26255 + 0xbad65a25a73d0bdcULL,
26256 + 0x710d64410c4b16bdULL,
26257 + 0xc22328ff0fec49d2ULL,
26258 + 0x85895216a40bb6e6ULL,
26259 + 0x36a71ea8a7ace989ULL,
26260 + 0x0adda7c5f3c4488eULL,
26261 + 0xb9f3eb7bf06317e1ULL,
26262 + 0xfe5991925b84e8d5ULL,
26263 + 0x4d77dd2c5823b7baULL,
26264 + 0x64b62bcaebc387a1ULL,
26265 + 0xd7986774e864d8ceULL,
26266 + 0x90321d9d438327faULL,
26267 + 0x231c512340247895ULL,
26268 + 0x1f66e84e144cd992ULL,
26269 + 0xac48a4f017eb86fdULL,
26270 + 0xebe2de19bc0c79c9ULL,
26271 + 0x58cc92a7bfab26a6ULL,
26272 + 0x9317acc314dd3bc7ULL,
26273 + 0x2039e07d177a64a8ULL,
26274 + 0x67939a94bc9d9b9cULL,
26275 + 0xd4bdd62abf3ac4f3ULL,
26276 + 0xe8c76f47eb5265f4ULL,
26277 + 0x5be923f9e8f53a9bULL,
26278 + 0x1c4359104312c5afULL,
26279 + 0xaf6d15ae40b59ac0ULL,
26280 + 0x192d8af2baf0e1e8ULL,
26281 + 0xaa03c64cb957be87ULL,
26282 + 0xeda9bca512b041b3ULL,
26283 + 0x5e87f01b11171edcULL,
26284 + 0x62fd4976457fbfdbULL,
26285 + 0xd1d305c846d8e0b4ULL,
26286 + 0x96797f21ed3f1f80ULL,
26287 + 0x2557339fee9840efULL,
26288 + 0xee8c0dfb45ee5d8eULL,
26289 + 0x5da24145464902e1ULL,
26290 + 0x1a083bacedaefdd5ULL,
26291 + 0xa9267712ee09a2baULL,
26292 + 0x955cce7fba6103bdULL,
26293 + 0x267282c1b9c65cd2ULL,
26294 + 0x61d8f8281221a3e6ULL,
26295 + 0xd2f6b4961186fc89ULL,
26296 + 0x9f8169ba49a54b33ULL,
26297 + 0x2caf25044a02145cULL,
26298 + 0x6b055fede1e5eb68ULL,
26299 + 0xd82b1353e242b407ULL,
26300 + 0xe451aa3eb62a1500ULL,
26301 + 0x577fe680b58d4a6fULL,
26302 + 0x10d59c691e6ab55bULL,
26303 + 0xa3fbd0d71dcdea34ULL,
26304 + 0x6820eeb3b6bbf755ULL,
26305 + 0xdb0ea20db51ca83aULL,
26306 + 0x9ca4d8e41efb570eULL,
26307 + 0x2f8a945a1d5c0861ULL,
26308 + 0x13f02d374934a966ULL,
26309 + 0xa0de61894a93f609ULL,
26310 + 0xe7741b60e174093dULL,
26311 + 0x545a57dee2d35652ULL,
26312 + 0xe21ac88218962d7aULL,
26313 + 0x5134843c1b317215ULL,
26314 + 0x169efed5b0d68d21ULL,
26315 + 0xa5b0b26bb371d24eULL,
26316 + 0x99ca0b06e7197349ULL,
26317 + 0x2ae447b8e4be2c26ULL,
26318 + 0x6d4e3d514f59d312ULL,
26319 + 0xde6071ef4cfe8c7dULL,
26320 + 0x15bb4f8be788911cULL,
26321 + 0xa6950335e42fce73ULL,
26322 + 0xe13f79dc4fc83147ULL,
26323 + 0x521135624c6f6e28ULL,
26324 + 0x6e6b8c0f1807cf2fULL,
26325 + 0xdd45c0b11ba09040ULL,
26326 + 0x9aefba58b0476f74ULL,
26327 + 0x29c1f6e6b3e0301bULL,
26328 + 0xc96c5795d7870f42ULL,
26329 + 0x7a421b2bd420502dULL,
26330 + 0x3de861c27fc7af19ULL,
26331 + 0x8ec62d7c7c60f076ULL,
26332 + 0xb2bc941128085171ULL,
26333 + 0x0192d8af2baf0e1eULL,
26334 + 0x4638a2468048f12aULL,
26335 + 0xf516eef883efae45ULL,
26336 + 0x3ecdd09c2899b324ULL,
26337 + 0x8de39c222b3eec4bULL,
26338 + 0xca49e6cb80d9137fULL,
26339 + 0x7967aa75837e4c10ULL,
26340 + 0x451d1318d716ed17ULL,
26341 + 0xf6335fa6d4b1b278ULL,
26342 + 0xb199254f7f564d4cULL,
26343 + 0x02b769f17cf11223ULL,
26344 + 0xb4f7f6ad86b4690bULL,
26345 + 0x07d9ba1385133664ULL,
26346 + 0x4073c0fa2ef4c950ULL,
26347 + 0xf35d8c442d53963fULL,
26348 + 0xcf273529793b3738ULL,
26349 + 0x7c0979977a9c6857ULL,
26350 + 0x3ba3037ed17b9763ULL,
26351 + 0x888d4fc0d2dcc80cULL,
26352 + 0x435671a479aad56dULL,
26353 + 0xf0783d1a7a0d8a02ULL,
26354 + 0xb7d247f3d1ea7536ULL,
26355 + 0x04fc0b4dd24d2a59ULL,
26356 + 0x3886b22086258b5eULL,
26357 + 0x8ba8fe9e8582d431ULL,
26358 + 0xcc0284772e652b05ULL,
26359 + 0x7f2cc8c92dc2746aULL,
26360 + 0x325b15e575e1c3d0ULL,
26361 + 0x8175595b76469cbfULL,
26362 + 0xc6df23b2dda1638bULL,
26363 + 0x75f16f0cde063ce4ULL,
26364 + 0x498bd6618a6e9de3ULL,
26365 + 0xfaa59adf89c9c28cULL,
26366 + 0xbd0fe036222e3db8ULL,
26367 + 0x0e21ac88218962d7ULL,
26368 + 0xc5fa92ec8aff7fb6ULL,
26369 + 0x76d4de52895820d9ULL,
26370 + 0x317ea4bb22bfdfedULL,
26371 + 0x8250e80521188082ULL,
26372 + 0xbe2a516875702185ULL,
26373 + 0x0d041dd676d77eeaULL,
26374 + 0x4aae673fdd3081deULL,
26375 + 0xf9802b81de97deb1ULL,
26376 + 0x4fc0b4dd24d2a599ULL,
26377 + 0xfceef8632775faf6ULL,
26378 + 0xbb44828a8c9205c2ULL,
26379 + 0x086ace348f355aadULL,
26380 + 0x34107759db5dfbaaULL,
26381 + 0x873e3be7d8faa4c5ULL,
26382 + 0xc094410e731d5bf1ULL,
26383 + 0x73ba0db070ba049eULL,
26384 + 0xb86133d4dbcc19ffULL,
26385 + 0x0b4f7f6ad86b4690ULL,
26386 + 0x4ce50583738cb9a4ULL,
26387 + 0xffcb493d702be6cbULL,
26388 + 0xc3b1f050244347ccULL,
26389 + 0x709fbcee27e418a3ULL,
26390 + 0x3735c6078c03e797ULL,
26391 + 0x841b8ab98fa4b8f8ULL,
26392 + 0xadda7c5f3c4488e3ULL,
26393 + 0x1ef430e13fe3d78cULL,
26394 + 0x595e4a08940428b8ULL,
26395 + 0xea7006b697a377d7ULL,
26396 + 0xd60abfdbc3cbd6d0ULL,
26397 + 0x6524f365c06c89bfULL,
26398 + 0x228e898c6b8b768bULL,
26399 + 0x91a0c532682c29e4ULL,
26400 + 0x5a7bfb56c35a3485ULL,
26401 + 0xe955b7e8c0fd6beaULL,
26402 + 0xaeffcd016b1a94deULL,
26403 + 0x1dd181bf68bdcbb1ULL,
26404 + 0x21ab38d23cd56ab6ULL,
26405 + 0x9285746c3f7235d9ULL,
26406 + 0xd52f0e859495caedULL,
26407 + 0x6601423b97329582ULL,
26408 + 0xd041dd676d77eeaaULL,
26409 + 0x636f91d96ed0b1c5ULL,
26410 + 0x24c5eb30c5374ef1ULL,
26411 + 0x97eba78ec690119eULL,
26412 + 0xab911ee392f8b099ULL,
26413 + 0x18bf525d915feff6ULL,
26414 + 0x5f1528b43ab810c2ULL,
26415 + 0xec3b640a391f4fadULL,
26416 + 0x27e05a6e926952ccULL,
26417 + 0x94ce16d091ce0da3ULL,
26418 + 0xd3646c393a29f297ULL,
26419 + 0x604a2087398eadf8ULL,
26420 + 0x5c3099ea6de60cffULL,
26421 + 0xef1ed5546e415390ULL,
26422 + 0xa8b4afbdc5a6aca4ULL,
26423 + 0x1b9ae303c601f3cbULL,
26424 + 0x56ed3e2f9e224471ULL,
26425 + 0xe5c372919d851b1eULL,
26426 + 0xa26908783662e42aULL,
26427 + 0x114744c635c5bb45ULL,
26428 + 0x2d3dfdab61ad1a42ULL,
26429 + 0x9e13b115620a452dULL,
26430 + 0xd9b9cbfcc9edba19ULL,
26431 + 0x6a978742ca4ae576ULL,
26432 + 0xa14cb926613cf817ULL,
26433 + 0x1262f598629ba778ULL,
26434 + 0x55c88f71c97c584cULL,
26435 + 0xe6e6c3cfcadb0723ULL,
26436 + 0xda9c7aa29eb3a624ULL,
26437 + 0x69b2361c9d14f94bULL,
26438 + 0x2e184cf536f3067fULL,
26439 + 0x9d36004b35545910ULL,
26440 + 0x2b769f17cf112238ULL,
26441 + 0x9858d3a9ccb67d57ULL,
26442 + 0xdff2a94067518263ULL,
26443 + 0x6cdce5fe64f6dd0cULL,
26444 + 0x50a65c93309e7c0bULL,
26445 + 0xe388102d33392364ULL,
26446 + 0xa4226ac498dedc50ULL,
26447 + 0x170c267a9b79833fULL,
26448 + 0xdcd7181e300f9e5eULL,
26449 + 0x6ff954a033a8c131ULL,
26450 + 0x28532e49984f3e05ULL,
26451 + 0x9b7d62f79be8616aULL,
26452 + 0xa707db9acf80c06dULL,
26453 + 0x14299724cc279f02ULL,
26454 + 0x5383edcd67c06036ULL,
26455 + 0xe0ada17364673f59ULL
26456 + }
26457 +};
26458 +
26459 +
26460 +/**
26461 + \brief Initializes the crc seed
26462 + */
26463 +static __inline__ uint64_t crc64_init(void)
26464 +{
26465 + return CRC64_ECMA_182.initial;
26466 +}
26467 +
26468 +/**
26469 + \brief Computes 64 bit the crc
26470 + \param[in] data Pointer to the Data in the frame
26471 + \param[in] len Length of the Data
26472 + \param[in] crc seed
26473 + \return calculated crc
26474 + */
26475 +static __inline__ uint64_t crc64_compute(void const *data,
26476 + uint32_t len,
26477 + uint64_t seed)
26478 +{
26479 + uint32_t i;
26480 + uint64_t crc = seed;
26481 + uint8_t *bdata = (uint8_t *) data;
26482 +
26483 + for (i = 0; i < len; i++)
26484 + crc =
26485 + CRC64_ECMA_182.
26486 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
26487 +
26488 + return crc;
26489 +}
26490 +
26491 +
26492 +#endif /* __CRC64_H */
26493 --- /dev/null
26494 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
26495 @@ -0,0 +1,7582 @@
26496 +/*
26497 + * Copyright 2008-2012 Freescale Semiconductor Inc.
26498 + *
26499 + * Redistribution and use in source and binary forms, with or without
26500 + * modification, are permitted provided that the following conditions are met:
26501 + * * Redistributions of source code must retain the above copyright
26502 + * notice, this list of conditions and the following disclaimer.
26503 + * * Redistributions in binary form must reproduce the above copyright
26504 + * notice, this list of conditions and the following disclaimer in the
26505 + * documentation and/or other materials provided with the distribution.
26506 + * * Neither the name of Freescale Semiconductor nor the
26507 + * names of its contributors may be used to endorse or promote products
26508 + * derived from this software without specific prior written permission.
26509 + *
26510 + *
26511 + * ALTERNATIVELY, this software may be distributed under the terms of the
26512 + * GNU General Public License ("GPL") as published by the Free Software
26513 + * Foundation, either version 2 of that License or (at your option) any
26514 + * later version.
26515 + *
26516 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26517 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26518 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26519 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26520 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26521 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26522 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26523 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26524 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26525 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26526 + */
26527 +
26528 +
26529 +/******************************************************************************
26530 + @File fm_cc.c
26531 +
26532 + @Description FM Coarse Classifier implementation
26533 + *//***************************************************************************/
26534 +#include <linux/math64.h>
26535 +#include "std_ext.h"
26536 +#include "error_ext.h"
26537 +#include "string_ext.h"
26538 +#include "debug_ext.h"
26539 +#include "fm_pcd_ext.h"
26540 +#include "fm_muram_ext.h"
26541 +
26542 +#include "fm_common.h"
26543 +#include "fm_pcd.h"
26544 +#include "fm_hc.h"
26545 +#include "fm_cc.h"
26546 +#include "crc64.h"
26547 +
26548 +/****************************************/
26549 +/* static functions */
26550 +/****************************************/
26551 +
26552 +
26553 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
26554 +{
26555 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26556 +
26557 + ASSERT_COND(h_FmPcdCcTree);
26558 +
26559 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
26560 + return E_OK;
26561 +
26562 + return ERROR_CODE(E_BUSY);
26563 +}
26564 +
26565 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
26566 +{
26567 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
26568 +
26569 + ASSERT_COND(h_FmPcdCcTree);
26570 +
26571 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
26572 +}
26573 +
26574 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
26575 +{
26576 + uint32_t intFlags;
26577 +
26578 + ASSERT_COND(p_CcNode);
26579 +
26580 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26581 +
26582 + if (add)
26583 + p_CcNode->owners++;
26584 + else
26585 + {
26586 + ASSERT_COND(p_CcNode->owners);
26587 + p_CcNode->owners--;
26588 + }
26589 +
26590 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26591 +}
26592 +
26593 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
26594 +{
26595 + t_FmPcdStatsObj *p_StatsObj = NULL;
26596 + t_List *p_Next;
26597 +
26598 + if (!LIST_IsEmpty(p_List))
26599 + {
26600 + p_Next = LIST_FIRST(p_List);
26601 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
26602 + ASSERT_COND(p_StatsObj);
26603 + LIST_DelAndInit(p_Next);
26604 + }
26605 +
26606 + return p_StatsObj;
26607 +}
26608 +
26609 +static __inline__ void EnqueueStatsObj(t_List *p_List,
26610 + t_FmPcdStatsObj *p_StatsObj)
26611 +{
26612 + LIST_AddToTail(&p_StatsObj->node, p_List);
26613 +}
26614 +
26615 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
26616 +{
26617 + t_FmPcdStatsObj *p_StatsObj;
26618 +
26619 + while (!LIST_IsEmpty(p_List))
26620 + {
26621 + p_StatsObj = DequeueStatsObj(p_List);
26622 + ASSERT_COND(p_StatsObj);
26623 +
26624 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26625 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26626 +
26627 + XX_Free(p_StatsObj);
26628 + }
26629 +}
26630 +
26631 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
26632 +{
26633 + t_FmPcdStatsObj* p_StatsObj;
26634 + t_Handle h_FmMuram;
26635 +
26636 + ASSERT_COND(p_CcNode);
26637 +
26638 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26639 + upon node initialization */
26640 + if (p_CcNode->maxNumOfKeys)
26641 + {
26642 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
26643 +
26644 + /* Clean statistics counters & ADs */
26645 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26646 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26647 + }
26648 + else
26649 + {
26650 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26651 + ASSERT_COND(h_FmMuram);
26652 +
26653 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
26654 + if (!p_StatsObj)
26655 + {
26656 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
26657 + return NULL;
26658 + }
26659 +
26660 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
26661 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26662 + if (!p_StatsObj->h_StatsAd)
26663 + {
26664 + XX_Free(p_StatsObj);
26665 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
26666 + return NULL;
26667 + }
26668 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26669 +
26670 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
26671 + h_FmMuram, p_CcNode->countersArraySize,
26672 + FM_PCD_CC_AD_TABLE_ALIGN);
26673 + if (!p_StatsObj->h_StatsCounters)
26674 + {
26675 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26676 + XX_Free(p_StatsObj);
26677 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
26678 + return NULL;
26679 + }
26680 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26681 + }
26682 +
26683 + return p_StatsObj;
26684 +}
26685 +
26686 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
26687 +{
26688 + t_Handle h_FmMuram;
26689 +
26690 + ASSERT_COND(p_CcNode);
26691 + ASSERT_COND(p_StatsObj);
26692 +
26693 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
26694 + upon node initialization and now will be enqueued back to the list */
26695 + if (p_CcNode->maxNumOfKeys)
26696 + {
26697 + /* Clean statistics counters */
26698 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
26699 +
26700 + /* Clean statistics ADs */
26701 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26702 +
26703 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
26704 + }
26705 + else
26706 + {
26707 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
26708 + ASSERT_COND(h_FmMuram);
26709 +
26710 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
26711 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
26712 +
26713 + XX_Free(p_StatsObj);
26714 + }
26715 +}
26716 +
26717 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
26718 + uint32_t statsCountersAddr)
26719 +{
26720 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
26721 +
26722 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
26723 +}
26724 +
26725 +
26726 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26727 + t_Handle h_Ad, uint64_t physicalMuramBase)
26728 +{
26729 + t_AdOfTypeStats *p_StatsAd;
26730 + uint32_t statsCountersAddr, nextActionAddr, tmp;
26731 +#if (DPAA_VERSION >= 11)
26732 + uint32_t frameLengthRangesAddr;
26733 +#endif /* (DPAA_VERSION >= 11) */
26734 +
26735 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
26736 +
26737 + tmp = FM_PCD_AD_STATS_TYPE;
26738 +
26739 +#if (DPAA_VERSION >= 11)
26740 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26741 + {
26742 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
26743 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
26744 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
26745 + }
26746 +#endif /* (DPAA_VERSION >= 11) */
26747 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
26748 +
26749 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
26750 + tmp = 0;
26751 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
26752 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
26753 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
26754 +
26755 +#if (DPAA_VERSION >= 11)
26756 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
26757 + tmp |= FM_PCD_AD_STATS_FLR_EN;
26758 +#endif /* (DPAA_VERSION >= 11) */
26759 +
26760 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
26761 +
26762 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
26763 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
26764 + SetStatsCounters(p_StatsAd, statsCountersAddr);
26765 +}
26766 +
26767 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
26768 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
26769 + t_Handle h_FmPcd, t_Handle p_CcNode,
26770 + t_Handle h_Manip, t_Handle h_FrmReplic)
26771 +{
26772 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
26773 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
26774 + t_Handle h_TmpAd;
26775 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
26776 + uint32_t tmpReg32;
26777 + t_Handle p_AdNewPtr = NULL;
26778 +
26779 + UNUSED(h_Manip);
26780 + UNUSED(h_FrmReplic);
26781 +
26782 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
26783 + * Case 1: No Manip. The action descriptor is built within the match table.
26784 + * p_AdResult = p_AdNewPtr;
26785 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
26786 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
26787 + * initialized and returned here.
26788 + * p_AdResult (within the match table) will be initialized after
26789 + * this routine returns and point to the existing AD.
26790 + * Case 3: Manip exists. The action descriptor is built within the match table.
26791 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
26792 + */
26793 +
26794 + /* As default, the "new" ptr is the current one. i.e. the content of the result
26795 + * AD will be written into the match table itself (case (1))*/
26796 + p_AdNewPtr = p_AdContLookup;
26797 +
26798 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
26799 + if (p_FmPcdCcStatsParams)
26800 + {
26801 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
26802 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
26803 +
26804 + /* Swapping addresses between statistics Ad and the current lookup AD */
26805 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
26806 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
26807 + h_Ad = h_TmpAd;
26808 +
26809 + p_AdNewPtr = h_Ad;
26810 + p_AdContLookup = h_Ad;
26811 +
26812 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
26813 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
26814 + }
26815 +
26816 +#if DPAA_VERSION >= 11
26817 + if (h_Manip && h_FrmReplic)
26818 + FmPcdManipUpdateAdContLookupForCc(
26819 + h_Manip,
26820 + h_Ad,
26821 + &p_AdNewPtr,
26822 + (uint32_t)((XX_VirtToPhys(
26823 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
26824 + - p_FmPcd->physicalMuramBase)));
26825 + else
26826 + if (h_FrmReplic)
26827 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
26828 + else
26829 +#endif /* (DPAA_VERSION >= 11) */
26830 + if (h_Manip)
26831 + FmPcdManipUpdateAdContLookupForCc(
26832 + h_Manip,
26833 + h_Ad,
26834 + &p_AdNewPtr,
26835 +
26836 +#ifdef FM_CAPWAP_SUPPORT
26837 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
26838 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
26839 +#else /* not FM_CAPWAP_SUPPORT */
26840 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
26841 + - p_FmPcd->physicalMuramBase))
26842 +#endif /* not FM_CAPWAP_SUPPORT */
26843 + );
26844 +
26845 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
26846 + if (p_AdNewPtr)
26847 + {
26848 + /* cases (1) & (2) */
26849 + tmpReg32 = 0;
26850 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
26851 + tmpReg32 |=
26852 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
26853 + 0;
26854 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
26855 + - p_FmPcd->physicalMuramBase);
26856 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
26857 +
26858 + tmpReg32 = 0;
26859 + tmpReg32 |= p_Node->numOfKeys << 24;
26860 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
26861 + tmpReg32 |=
26862 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
26863 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
26864 + 0;
26865 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
26866 +
26867 + tmpReg32 = 0;
26868 + tmpReg32 |= p_Node->prsArrayOffset << 24;
26869 + tmpReg32 |= p_Node->offset << 16;
26870 + tmpReg32 |= p_Node->parseCode;
26871 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
26872 +
26873 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
26874 + CC_GLBL_MASK_SIZE);
26875 + }
26876 +}
26877 +
26878 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
26879 +{
26880 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
26881 + uint32_t intFlags;
26882 +
26883 + ASSERT_COND(p_CcNode);
26884 +
26885 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
26886 +
26887 + if (!p_CcNode->h_Ad)
26888 + {
26889 + if (p_CcNode->maxNumOfKeys)
26890 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
26891 + else
26892 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
26893 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
26894 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
26895 +
26896 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26897 +
26898 + if (!p_CcNode->h_Ad)
26899 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
26900 + ("MURAM allocation for CC action descriptor"));
26901 +
26902 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
26903 +
26904 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
26905 + p_CcNode, NULL, NULL);
26906 + }
26907 + else
26908 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
26909 +
26910 + return E_OK;
26911 +}
26912 +
26913 +static t_Error SetRequiredAction1(
26914 + t_Handle h_FmPcd, uint32_t requiredAction,
26915 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
26916 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
26917 +{
26918 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
26919 + uint32_t tmpReg32;
26920 + t_Error err;
26921 + t_FmPcdCcNode *p_CcNode;
26922 + int i = 0;
26923 + uint16_t tmp = 0;
26924 + uint16_t profileId;
26925 + uint8_t relativeSchemeId, physicalSchemeId;
26926 + t_CcNodeInformation ccNodeInfo;
26927 +
26928 + for (i = 0; i < numOfEntries; i++)
26929 + {
26930 + if (i == 0)
26931 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
26932 + else
26933 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
26934 +
26935 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
26936 + {
26937 + case (e_FM_PCD_CC):
26938 + if (requiredAction)
26939 + {
26940 + p_CcNode =
26941 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
26942 + ASSERT_COND(p_CcNode);
26943 + if (p_CcNode->shadowAction == requiredAction)
26944 + break;
26945 + if ((requiredAction & UPDATE_CC_WITH_TREE)
26946 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
26947 + {
26948 +
26949 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
26950 + ccNodeInfo.h_CcNode = h_Tree;
26951 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
26952 + &ccNodeInfo, NULL);
26953 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26954 + UPDATE_CC_WITH_TREE;
26955 + }
26956 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
26957 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
26958 + {
26959 +
26960 + p_CcNode->shadowAction = 0;
26961 + }
26962 +
26963 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
26964 + && !(p_CcNode->shadowAction
26965 + & UPDATE_CC_WITH_DELETE_TREE))
26966 + {
26967 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
26968 + h_Tree, NULL);
26969 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
26970 + UPDATE_CC_WITH_DELETE_TREE;
26971 + }
26972 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
26973 + != e_FM_PCD_INVALID)
26974 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
26975 + else
26976 + tmp = p_CcNode->numOfKeys;
26977 + err = SetRequiredAction1(h_FmPcd, requiredAction,
26978 + p_CcNode->keyAndNextEngineParams,
26979 + p_CcNode->h_AdTable, tmp, h_Tree);
26980 + if (err != E_OK)
26981 + return err;
26982 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
26983 + p_CcNode->shadowAction |= requiredAction;
26984 + }
26985 + break;
26986 +
26987 + case (e_FM_PCD_KG):
26988 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
26989 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
26990 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
26991 + {
26992 + physicalSchemeId =
26993 + FmPcdKgGetSchemeId(
26994 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
26995 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
26996 + h_FmPcd, physicalSchemeId);
26997 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
26998 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
26999 + if (!FmPcdKgIsSchemeValidSw(
27000 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
27001 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
27002 + ("Invalid direct scheme."));
27003 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
27004 + RETURN_ERROR(
27005 + MAJOR, E_INVALID_STATE,
27006 + ("For this action scheme has to be direct."));
27007 + err =
27008 + FmPcdKgCcGetSetParams(
27009 + h_FmPcd,
27010 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
27011 + requiredAction, 0);
27012 + if (err != E_OK)
27013 + RETURN_ERROR(MAJOR, err, NO_MSG);
27014 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
27015 + requiredAction;
27016 + }
27017 + break;
27018 +
27019 + case (e_FM_PCD_PLCR):
27020 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
27021 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
27022 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
27023 + {
27024 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
27025 + RETURN_ERROR(
27026 + MAJOR,
27027 + E_NOT_SUPPORTED,
27028 + ("In this initialization only overrideFqid can be initialized"));
27029 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
27030 + RETURN_ERROR(
27031 + MAJOR,
27032 + E_NOT_SUPPORTED,
27033 + ("In this initialization only overrideFqid can be initialized"));
27034 + err =
27035 + FmPcdPlcrGetAbsoluteIdByProfileParams(
27036 + h_FmPcd,
27037 + e_FM_PCD_PLCR_SHARED,
27038 + NULL,
27039 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
27040 + &profileId);
27041 + if (err != E_OK)
27042 + RETURN_ERROR(MAJOR, err, NO_MSG);
27043 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
27044 + requiredAction);
27045 + if (err != E_OK)
27046 + RETURN_ERROR(MAJOR, err, NO_MSG);
27047 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
27048 + requiredAction;
27049 + }
27050 + break;
27051 +
27052 + case (e_FM_PCD_DONE):
27053 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
27054 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
27055 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
27056 + {
27057 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
27058 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
27059 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
27060 + RETURN_ERROR(
27061 + MAJOR,
27062 + E_INVALID_STATE,
27063 + ("Next engine was previously assigned not as PCD_DONE"));
27064 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
27065 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
27066 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
27067 + requiredAction;
27068 + }
27069 + break;
27070 +
27071 + default:
27072 + break;
27073 + }
27074 + }
27075 +
27076 + return E_OK;
27077 +}
27078 +
27079 +static t_Error SetRequiredAction(
27080 + t_Handle h_FmPcd, uint32_t requiredAction,
27081 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
27082 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
27083 +{
27084 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
27085 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
27086 + numOfEntries, h_Tree);
27087 + if (err != E_OK)
27088 + return err;
27089 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
27090 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
27091 + numOfEntries, h_Tree);
27092 +}
27093 +
27094 +static t_Error ReleaseModifiedDataStructure(
27095 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
27096 + t_List *h_FmPcdNewPointersLst,
27097 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27098 + bool useShadowStructs)
27099 +{
27100 + t_List *p_Pos;
27101 + t_Error err = E_OK;
27102 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
27103 + t_Handle h_Muram;
27104 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
27105 + t_List *p_UpdateLst;
27106 + uint32_t intFlags;
27107 +
27108 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
27109 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
27110 + E_INVALID_HANDLE);
27111 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
27112 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
27113 +
27114 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
27115 + if (p_AdditionalParams->h_NodeForAdd)
27116 + {
27117 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
27118 +
27119 + if (!p_AdditionalParams->tree)
27120 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
27121 + else
27122 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27123 +
27124 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27125 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27126 + p_FmPcdCcNextNode->h_Spinlock);
27127 +
27128 + if (p_CcNodeInformation)
27129 + p_CcNodeInformation->index++;
27130 + else
27131 + {
27132 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
27133 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
27134 + ccNodeInfo.index = 1;
27135 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
27136 + p_FmPcdCcNextNode->h_Spinlock);
27137 + }
27138 + if (p_AdditionalParams->h_ManipForAdd)
27139 + {
27140 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27141 + FmPcdManipGetNodeLstPointedOnThisManip(
27142 + p_AdditionalParams->h_ManipForAdd),
27143 + p_AdditionalParams->h_CurrentNode,
27144 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
27145 +
27146 + if (p_CcNodeInformation)
27147 + p_CcNodeInformation->index++;
27148 + else
27149 + {
27150 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
27151 + ccNodeInfo.h_CcNode =
27152 + (t_Handle)p_AdditionalParams->h_CurrentNode;
27153 + ccNodeInfo.index = 1;
27154 + EnqueueNodeInfoToRelevantLst(
27155 + FmPcdManipGetNodeLstPointedOnThisManip(
27156 + p_AdditionalParams->h_ManipForAdd),
27157 + &ccNodeInfo,
27158 + FmPcdManipGetSpinlock(
27159 + p_AdditionalParams->h_ManipForAdd));
27160 + }
27161 + }
27162 + }
27163 +
27164 + if (p_AdditionalParams->h_NodeForRmv)
27165 + {
27166 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
27167 +
27168 + if (!p_AdditionalParams->tree)
27169 + {
27170 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
27171 + p_FmPcdCcWorkingOnNode =
27172 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27173 +
27174 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
27175 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
27176 + LIST_NEXT(p_Pos))
27177 + {
27178 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27179 +
27180 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27181 +
27182 + err =
27183 + SetRequiredAction(
27184 + h_FmPcd,
27185 + UPDATE_CC_WITH_DELETE_TREE,
27186 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27187 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27188 + 1, p_CcNodeInformation->h_CcNode);
27189 + }
27190 + }
27191 + else
27192 + {
27193 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
27194 +
27195 + err =
27196 + SetRequiredAction(
27197 + h_FmPcd,
27198 + UPDATE_CC_WITH_DELETE_TREE,
27199 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
27200 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
27201 + 1, p_AdditionalParams->h_CurrentNode);
27202 + }
27203 + if (err)
27204 + return err;
27205 +
27206 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
27207 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
27208 + Update of the node owner */
27209 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27210 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
27211 + p_FmPcdCcNextNode->h_Spinlock);
27212 +
27213 + ASSERT_COND(p_CcNodeInformation);
27214 + ASSERT_COND(p_CcNodeInformation->index);
27215 +
27216 + p_CcNodeInformation->index--;
27217 +
27218 + if (p_CcNodeInformation->index == 0)
27219 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
27220 + p_AdditionalParams->h_CurrentNode,
27221 + p_FmPcdCcNextNode->h_Spinlock);
27222 +
27223 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
27224 +
27225 + if (p_AdditionalParams->h_ManipForRmv)
27226 + {
27227 + p_CcNodeInformation = FindNodeInfoInReleventLst(
27228 + FmPcdManipGetNodeLstPointedOnThisManip(
27229 + p_AdditionalParams->h_ManipForRmv),
27230 + p_AdditionalParams->h_CurrentNode,
27231 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
27232 +
27233 + ASSERT_COND(p_CcNodeInformation);
27234 + ASSERT_COND(p_CcNodeInformation->index);
27235 +
27236 + p_CcNodeInformation->index--;
27237 +
27238 + if (p_CcNodeInformation->index == 0)
27239 + DequeueNodeInfoFromRelevantLst(
27240 + FmPcdManipGetNodeLstPointedOnThisManip(
27241 + p_AdditionalParams->h_ManipForRmv),
27242 + p_AdditionalParams->h_CurrentNode,
27243 + FmPcdManipGetSpinlock(
27244 + p_AdditionalParams->h_ManipForRmv));
27245 + }
27246 + }
27247 +
27248 + if (p_AdditionalParams->h_ManipForRmv)
27249 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
27250 +
27251 + if (p_AdditionalParams->p_StatsObjForRmv)
27252 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
27253 + p_AdditionalParams->p_StatsObjForRmv);
27254 +
27255 +#if (DPAA_VERSION >= 11)
27256 + if (p_AdditionalParams->h_FrmReplicForRmv)
27257 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
27258 + FALSE/* remove */);
27259 +#endif /* (DPAA_VERSION >= 11) */
27260 +
27261 + if (!useShadowStructs)
27262 + {
27263 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
27264 + ASSERT_COND(h_Muram);
27265 +
27266 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
27267 + || (!p_AdditionalParams->tree
27268 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
27269 + {
27270 + /* We release new AD which was allocated and updated for copy from to actual AD */
27271 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
27272 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
27273 + {
27274 +
27275 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
27276 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
27277 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
27278 + }
27279 + }
27280 +
27281 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
27282 + if (p_AdditionalParams->p_AdTableOld)
27283 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
27284 +
27285 + if (p_AdditionalParams->p_KeysMatchTableOld)
27286 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
27287 + }
27288 +
27289 + /* Update current modified node with changed fields if it's required*/
27290 + if (!p_AdditionalParams->tree)
27291 + {
27292 + if (p_AdditionalParams->p_AdTableNew)
27293 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
27294 + p_AdditionalParams->p_AdTableNew;
27295 +
27296 + if (p_AdditionalParams->p_KeysMatchTableNew)
27297 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
27298 + p_AdditionalParams->p_KeysMatchTableNew;
27299 +
27300 + /* Locking node's spinlock before updating 'keys and next engine' structure,
27301 + as it maybe used to retrieve keys statistics */
27302 + intFlags =
27303 + XX_LockIntrSpinlock(
27304 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
27305 +
27306 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
27307 + p_AdditionalParams->numOfKeys;
27308 +
27309 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27310 + &p_AdditionalParams->keyAndNextEngineParams,
27311 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
27312 +
27313 + XX_UnlockIntrSpinlock(
27314 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
27315 + intFlags);
27316 + }
27317 + else
27318 + {
27319 + uint8_t numEntries =
27320 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
27321 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
27322 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
27323 + &p_AdditionalParams->keyAndNextEngineParams,
27324 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
27325 + }
27326 +
27327 + ReleaseLst(h_FmPcdOldPointersLst);
27328 + ReleaseLst(h_FmPcdNewPointersLst);
27329 +
27330 + XX_Free(p_AdditionalParams);
27331 +
27332 + return E_OK;
27333 +}
27334 +
27335 +static t_Handle BuildNewAd(
27336 + t_Handle h_Ad,
27337 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
27338 + t_FmPcdCcNode *p_CcNode,
27339 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
27340 +{
27341 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
27342 + t_Handle h_OrigAd = NULL;
27343 +
27344 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
27345 + if (!p_FmPcdCcNodeTmp)
27346 + {
27347 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
27348 + return NULL;
27349 + }
27350 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
27351 +
27352 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
27353 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
27354 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
27355 + p_FmPcdCcNodeTmp->h_AdTable =
27356 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
27357 +
27358 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
27359 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
27360 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
27361 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
27362 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
27363 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
27364 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
27365 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
27366 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
27367 +
27368 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
27369 + {
27370 + if (p_FmPcdCcNextEngineParams->h_Manip)
27371 + {
27372 + h_OrigAd = p_CcNode->h_Ad;
27373 + if (AllocAndFillAdForContLookupManip(
27374 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
27375 + != E_OK)
27376 + {
27377 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
27378 + XX_Free(p_FmPcdCcNodeTmp);
27379 + return NULL;
27380 + }
27381 + }
27382 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27383 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
27384 + }
27385 +
27386 +#if (DPAA_VERSION >= 11)
27387 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
27388 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
27389 + {
27390 + FillAdOfTypeContLookup(
27391 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
27392 + p_FmPcdCcNextEngineParams->h_Manip,
27393 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
27394 + }
27395 +#endif /* (DPAA_VERSION >= 11) */
27396 +
27397 + XX_Free(p_FmPcdCcNodeTmp);
27398 +
27399 + return E_OK;
27400 +}
27401 +
27402 +static t_Error DynamicChangeHc(
27403 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27404 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27405 + bool useShadowStructs)
27406 +{
27407 + t_List *p_PosOld, *p_PosNew;
27408 + uint32_t oldAdAddrOffset, newAdAddrOffset;
27409 + uint16_t i = 0;
27410 + t_Error err = E_OK;
27411 + uint8_t numOfModifiedPtr;
27412 +
27413 + ASSERT_COND(h_FmPcd);
27414 + ASSERT_COND(h_OldPointersLst);
27415 + ASSERT_COND(h_NewPointersLst);
27416 +
27417 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27418 +
27419 + if (numOfModifiedPtr)
27420 + {
27421 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27422 + p_PosOld = LIST_FIRST(h_OldPointersLst);
27423 +
27424 + /* Retrieve address of new AD */
27425 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27426 + p_PosNew);
27427 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27428 + {
27429 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27430 + h_NewPointersLst,
27431 + p_AdditionalParams, useShadowStructs);
27432 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
27433 + }
27434 +
27435 + for (i = 0; i < numOfModifiedPtr; i++)
27436 + {
27437 + /* Retrieve address of current AD */
27438 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
27439 + p_PosOld);
27440 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
27441 + {
27442 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27443 + h_NewPointersLst,
27444 + p_AdditionalParams,
27445 + useShadowStructs);
27446 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
27447 + }
27448 +
27449 + /* Invoke host command to copy from new AD to old AD */
27450 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
27451 + oldAdAddrOffset, newAdAddrOffset);
27452 + if (err)
27453 + {
27454 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27455 + h_NewPointersLst,
27456 + p_AdditionalParams,
27457 + useShadowStructs);
27458 + RETURN_ERROR(
27459 + MAJOR,
27460 + err,
27461 + ("For part of nodes changes are done - situation is danger"));
27462 + }
27463 +
27464 + p_PosOld = LIST_NEXT(p_PosOld);
27465 + }
27466 + }
27467 + return E_OK;
27468 +}
27469 +
27470 +static t_Error DoDynamicChange(
27471 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
27472 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
27473 + bool useShadowStructs)
27474 +{
27475 + t_FmPcdCcNode *p_CcNode =
27476 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
27477 + t_List *p_PosNew;
27478 + t_CcNodeInformation *p_CcNodeInfo;
27479 + t_FmPcdCcNextEngineParams nextEngineParams;
27480 + t_Handle h_Ad;
27481 + uint32_t keySize;
27482 + t_Error err = E_OK;
27483 + uint8_t numOfModifiedPtr;
27484 +
27485 + ASSERT_COND(h_FmPcd);
27486 +
27487 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
27488 +
27489 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
27490 +
27491 + if (numOfModifiedPtr)
27492 + {
27493 +
27494 + p_PosNew = LIST_FIRST(h_NewPointersLst);
27495 +
27496 + /* Invoke host-command to copy from the new Ad to existing Ads */
27497 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27498 + p_AdditionalParams, useShadowStructs);
27499 + if (err)
27500 + RETURN_ERROR(MAJOR, err, NO_MSG);
27501 +
27502 + if (useShadowStructs)
27503 + {
27504 + /* When the host-command above has ended, the old structures are 'free'and we can update
27505 + them by copying from the new shadow structures. */
27506 + if (p_CcNode->lclMask)
27507 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
27508 + else
27509 + keySize = p_CcNode->ccKeySizeAccExtraction;
27510 +
27511 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
27512 + p_AdditionalParams->p_KeysMatchTableNew,
27513 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
27514 +
27515 + MemCpy8(
27516 + p_AdditionalParams->p_AdTableOld,
27517 + p_AdditionalParams->p_AdTableNew,
27518 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
27519 + * FM_PCD_CC_AD_ENTRY_SIZE));
27520 +
27521 + /* Retrieve the address of the allocated Ad */
27522 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
27523 + h_Ad = p_CcNodeInfo->h_CcNode;
27524 +
27525 + /* Build a new Ad that holds the old (now updated) structures */
27526 + p_AdditionalParams->p_KeysMatchTableNew =
27527 + p_AdditionalParams->p_KeysMatchTableOld;
27528 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
27529 +
27530 + nextEngineParams.nextEngine = e_FM_PCD_CC;
27531 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
27532 +
27533 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
27534 +
27535 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
27536 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
27537 + p_AdditionalParams, useShadowStructs);
27538 + if (err)
27539 + RETURN_ERROR(MAJOR, err, NO_MSG);
27540 + }
27541 + }
27542 +
27543 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
27544 + h_NewPointersLst,
27545 + p_AdditionalParams, useShadowStructs);
27546 + if (err)
27547 + RETURN_ERROR(MAJOR, err, NO_MSG);
27548 +
27549 + return E_OK;
27550 +}
27551 +
27552 +#ifdef FM_CAPWAP_SUPPORT
27553 +static bool IsCapwapApplSpecific(t_Handle h_Node)
27554 +{
27555 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
27556 + bool isManipForCapwapApplSpecificBuild = FALSE;
27557 + int i = 0;
27558 +
27559 + ASSERT_COND(h_Node);
27560 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
27561 + for (i = 0; i < p_CcNode->numOfKeys; i++)
27562 + {
27563 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
27564 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
27565 + {
27566 + isManipForCapwapApplSpecificBuild = TRUE;
27567 + break;
27568 + }
27569 + }
27570 + return isManipForCapwapApplSpecificBuild;
27571 +
27572 +}
27573 +#endif /* FM_CAPWAP_SUPPORT */
27574 +
27575 +static t_Error CcUpdateParam(
27576 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
27577 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
27578 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
27579 + t_Handle h_FmTree, bool modify)
27580 +{
27581 + t_FmPcdCcNode *p_CcNode;
27582 + t_Error err;
27583 + uint16_t tmp = 0;
27584 + int i = 0;
27585 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
27586 +
27587 + level++;
27588 +
27589 + if (p_CcTree->h_IpReassemblyManip)
27590 + {
27591 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27592 + p_CcTree->h_IpReassemblyManip, NULL, validate,
27593 + level, h_FmTree, modify);
27594 + if (err)
27595 + RETURN_ERROR(MAJOR, err, NO_MSG);
27596 + }
27597 +
27598 + if (p_CcTree->h_CapwapReassemblyManip)
27599 + {
27600 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
27601 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
27602 + level, h_FmTree, modify);
27603 + if (err)
27604 + RETURN_ERROR(MAJOR, err, NO_MSG);
27605 + }
27606 +
27607 + if (numOfEntries)
27608 + {
27609 + for (i = 0; i < numOfEntries; i++)
27610 + {
27611 + if (i == 0)
27612 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
27613 + else
27614 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
27615 +
27616 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
27617 + == e_FM_PCD_CC)
27618 + {
27619 + p_CcNode =
27620 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
27621 + ASSERT_COND(p_CcNode);
27622 +
27623 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27624 + {
27625 + err =
27626 + FmPcdManipUpdate(
27627 + h_FmPcd,
27628 + NULL,
27629 + h_FmPort,
27630 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27631 + h_Ad, validate, level, h_FmTree, modify);
27632 + if (err)
27633 + RETURN_ERROR(MAJOR, err, NO_MSG);
27634 + }
27635 +
27636 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
27637 + != e_FM_PCD_INVALID)
27638 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
27639 + else
27640 + tmp = p_CcNode->numOfKeys;
27641 +
27642 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
27643 + p_CcNode->keyAndNextEngineParams, tmp,
27644 + p_CcNode->h_AdTable, validate, level,
27645 + h_FmTree, modify);
27646 + if (err)
27647 + RETURN_ERROR(MAJOR, err, NO_MSG);
27648 + }
27649 + else
27650 + {
27651 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
27652 + {
27653 + err =
27654 + FmPcdManipUpdate(
27655 + h_FmPcd,
27656 + NULL,
27657 + h_FmPort,
27658 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
27659 + h_Ad, validate, level, h_FmTree, modify);
27660 + if (err)
27661 + RETURN_ERROR(MAJOR, err, NO_MSG);
27662 + }
27663 + }
27664 + }
27665 + }
27666 +
27667 + return E_OK;
27668 +}
27669 +
27670 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
27671 +{
27672 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
27673 + {
27674 + case (e_FM_PCD_ACTION_EXACT_MATCH):
27675 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27676 + {
27677 + case (e_FM_PCD_EXTRACT_FROM_KEY):
27678 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
27679 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27680 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
27681 + default:
27682 + return CC_PRIVATE_INFO_NONE;
27683 + }
27684 +
27685 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
27686 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
27687 + {
27688 + case (e_FM_PCD_EXTRACT_FROM_HASH):
27689 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
27690 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
27691 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
27692 + default:
27693 + return CC_PRIVATE_INFO_NONE;
27694 + }
27695 +
27696 + default:
27697 + break;
27698 + }
27699 +
27700 + return CC_PRIVATE_INFO_NONE;
27701 +}
27702 +
27703 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
27704 + t_List *p_List)
27705 +{
27706 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27707 +
27708 + if (!LIST_IsEmpty(p_List))
27709 + {
27710 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
27711 + LIST_DelAndInit(&p_CcNodeInfo->node);
27712 + }
27713 +
27714 + return p_CcNodeInfo;
27715 +}
27716 +
27717 +void ReleaseLst(t_List *p_List)
27718 +{
27719 + t_CcNodeInformation *p_CcNodeInfo = NULL;
27720 +
27721 + if (!LIST_IsEmpty(p_List))
27722 + {
27723 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27724 + while (p_CcNodeInfo)
27725 + {
27726 + XX_Free(p_CcNodeInfo);
27727 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
27728 + }
27729 + }
27730 +
27731 + LIST_Del(p_List);
27732 +}
27733 +
27734 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
27735 +{
27736 + uint32_t i;
27737 +
27738 + if (!p_CcNode)
27739 + return;
27740 +
27741 + if (p_CcNode->p_GlblMask)
27742 + {
27743 + XX_Free(p_CcNode->p_GlblMask);
27744 + p_CcNode->p_GlblMask = NULL;
27745 + }
27746 +
27747 + if (p_CcNode->h_KeysMatchTable)
27748 + {
27749 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27750 + p_CcNode->h_KeysMatchTable);
27751 + p_CcNode->h_KeysMatchTable = NULL;
27752 + }
27753 +
27754 + if (p_CcNode->h_AdTable)
27755 + {
27756 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27757 + p_CcNode->h_AdTable);
27758 + p_CcNode->h_AdTable = NULL;
27759 + }
27760 +
27761 + if (p_CcNode->h_Ad)
27762 + {
27763 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27764 + p_CcNode->h_Ad);
27765 + p_CcNode->h_Ad = NULL;
27766 + p_CcNode->h_TmpAd = NULL;
27767 + }
27768 +
27769 + if (p_CcNode->h_StatsFLRs)
27770 + {
27771 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
27772 + p_CcNode->h_StatsFLRs);
27773 + p_CcNode->h_StatsFLRs = NULL;
27774 + }
27775 +
27776 + if (p_CcNode->h_Spinlock)
27777 + {
27778 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
27779 + p_CcNode->h_Spinlock = NULL;
27780 + }
27781 +
27782 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
27783 + if (p_CcNode->isHashBucket
27784 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
27785 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
27786 + p_CcNode->h_PrivMissStatsCounters;
27787 +
27788 + /* Releasing all currently used statistics objects, including 'miss' entry */
27789 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
27790 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
27791 + PutStatsObj(p_CcNode,
27792 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
27793 +
27794 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
27795 + {
27796 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
27797 + ASSERT_COND(h_FmMuram);
27798 +
27799 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
27800 + }
27801 +
27802 + LIST_Del(&p_CcNode->availableStatsLst);
27803 +
27804 + ReleaseLst(&p_CcNode->availableStatsLst);
27805 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
27806 + ReleaseLst(&p_CcNode->ccTreeIdLst);
27807 + ReleaseLst(&p_CcNode->ccTreesLst);
27808 +
27809 + XX_Free(p_CcNode);
27810 +}
27811 +
27812 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
27813 +{
27814 + if (p_FmPcdTree)
27815 + {
27816 + if (p_FmPcdTree->ccTreeBaseAddr)
27817 + {
27818 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
27819 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
27820 + p_FmPcdTree->ccTreeBaseAddr = 0;
27821 + }
27822 +
27823 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
27824 +
27825 + XX_Free(p_FmPcdTree);
27826 + }
27827 +}
27828 +
27829 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
27830 + uint8_t *parseCodeCcSize)
27831 +{
27832 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
27833 + *parseCodeCcSize = 1;
27834 + else
27835 + if (parseCodeRealSize == 2)
27836 + *parseCodeCcSize = 2;
27837 + else
27838 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
27839 + *parseCodeCcSize = 4;
27840 + else
27841 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
27842 + *parseCodeCcSize = 8;
27843 + else
27844 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
27845 + *parseCodeCcSize = 16;
27846 + else
27847 + if ((parseCodeRealSize > 16)
27848 + && (parseCodeRealSize <= 24))
27849 + *parseCodeCcSize = 24;
27850 + else
27851 + if ((parseCodeRealSize > 24)
27852 + && (parseCodeRealSize <= 32))
27853 + *parseCodeCcSize = 32;
27854 + else
27855 + if ((parseCodeRealSize > 32)
27856 + && (parseCodeRealSize <= 40))
27857 + *parseCodeCcSize = 40;
27858 + else
27859 + if ((parseCodeRealSize > 40)
27860 + && (parseCodeRealSize <= 48))
27861 + *parseCodeCcSize = 48;
27862 + else
27863 + if ((parseCodeRealSize > 48)
27864 + && (parseCodeRealSize <= 56))
27865 + *parseCodeCcSize = 56;
27866 + else
27867 + *parseCodeCcSize = 0;
27868 +}
27869 +
27870 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
27871 + uint8_t *parseCodeRealSize)
27872 +{
27873 + switch (hdr)
27874 + {
27875 + case (HEADER_TYPE_ETH):
27876 + switch (field.eth)
27877 + {
27878 + case (NET_HEADER_FIELD_ETH_DA):
27879 + *parseCodeRealSize = 6;
27880 + break;
27881 +
27882 + case (NET_HEADER_FIELD_ETH_SA):
27883 + *parseCodeRealSize = 6;
27884 + break;
27885 +
27886 + case (NET_HEADER_FIELD_ETH_TYPE):
27887 + *parseCodeRealSize = 2;
27888 + break;
27889 +
27890 + default:
27891 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27892 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27893 + break;
27894 + }
27895 + break;
27896 +
27897 + case (HEADER_TYPE_PPPoE):
27898 + switch (field.pppoe)
27899 + {
27900 + case (NET_HEADER_FIELD_PPPoE_PID):
27901 + *parseCodeRealSize = 2;
27902 + break;
27903 +
27904 + default:
27905 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
27906 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27907 + break;
27908 + }
27909 + break;
27910 +
27911 + case (HEADER_TYPE_VLAN):
27912 + switch (field.vlan)
27913 + {
27914 + case (NET_HEADER_FIELD_VLAN_TCI):
27915 + *parseCodeRealSize = 2;
27916 + break;
27917 +
27918 + default:
27919 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
27920 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27921 + break;
27922 + }
27923 + break;
27924 +
27925 + case (HEADER_TYPE_MPLS):
27926 + switch (field.mpls)
27927 + {
27928 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
27929 + *parseCodeRealSize = 4;
27930 + break;
27931 +
27932 + default:
27933 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
27934 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27935 + break;
27936 + }
27937 + break;
27938 +
27939 + case (HEADER_TYPE_IPv4):
27940 + switch (field.ipv4)
27941 + {
27942 + case (NET_HEADER_FIELD_IPv4_DST_IP):
27943 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
27944 + *parseCodeRealSize = 4;
27945 + break;
27946 +
27947 + case (NET_HEADER_FIELD_IPv4_TOS):
27948 + case (NET_HEADER_FIELD_IPv4_PROTO):
27949 + *parseCodeRealSize = 1;
27950 + break;
27951 +
27952 + case (NET_HEADER_FIELD_IPv4_DST_IP
27953 + | NET_HEADER_FIELD_IPv4_SRC_IP):
27954 + *parseCodeRealSize = 8;
27955 + break;
27956 +
27957 + case (NET_HEADER_FIELD_IPv4_TTL):
27958 + *parseCodeRealSize = 1;
27959 + break;
27960 +
27961 + default:
27962 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
27963 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27964 + break;
27965 + }
27966 + break;
27967 +
27968 + case (HEADER_TYPE_IPv6):
27969 + switch (field.ipv6)
27970 + {
27971 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
27972 + | NET_HEADER_FIELD_IPv6_TC):
27973 + *parseCodeRealSize = 4;
27974 + break;
27975 +
27976 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
27977 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
27978 + *parseCodeRealSize = 1;
27979 + break;
27980 +
27981 + case (NET_HEADER_FIELD_IPv6_DST_IP):
27982 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
27983 + *parseCodeRealSize = 16;
27984 + break;
27985 +
27986 + default:
27987 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
27988 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
27989 + break;
27990 + }
27991 + break;
27992 +
27993 + case (HEADER_TYPE_IP):
27994 + switch (field.ip)
27995 + {
27996 + case (NET_HEADER_FIELD_IP_DSCP):
27997 + case (NET_HEADER_FIELD_IP_PROTO):
27998 + *parseCodeRealSize = 1;
27999 + break;
28000 +
28001 + default:
28002 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
28003 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28004 + break;
28005 + }
28006 + break;
28007 +
28008 + case (HEADER_TYPE_GRE):
28009 + switch (field.gre)
28010 + {
28011 + case (NET_HEADER_FIELD_GRE_TYPE):
28012 + *parseCodeRealSize = 2;
28013 + break;
28014 +
28015 + default:
28016 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
28017 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28018 + break;
28019 + }
28020 + break;
28021 +
28022 + case (HEADER_TYPE_MINENCAP):
28023 + switch (field.minencap)
28024 + {
28025 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28026 + *parseCodeRealSize = 1;
28027 + break;
28028 +
28029 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28030 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28031 + *parseCodeRealSize = 4;
28032 + break;
28033 +
28034 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28035 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28036 + *parseCodeRealSize = 8;
28037 + break;
28038 +
28039 + default:
28040 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
28041 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28042 + break;
28043 + }
28044 + break;
28045 +
28046 + case (HEADER_TYPE_TCP):
28047 + switch (field.tcp)
28048 + {
28049 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28050 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28051 + *parseCodeRealSize = 2;
28052 + break;
28053 +
28054 + case (NET_HEADER_FIELD_TCP_PORT_SRC
28055 + | NET_HEADER_FIELD_TCP_PORT_DST):
28056 + *parseCodeRealSize = 4;
28057 + break;
28058 +
28059 + default:
28060 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
28061 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28062 + break;
28063 + }
28064 + break;
28065 +
28066 + case (HEADER_TYPE_UDP):
28067 + switch (field.udp)
28068 + {
28069 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28070 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28071 + *parseCodeRealSize = 2;
28072 + break;
28073 +
28074 + case (NET_HEADER_FIELD_UDP_PORT_SRC
28075 + | NET_HEADER_FIELD_UDP_PORT_DST):
28076 + *parseCodeRealSize = 4;
28077 + break;
28078 +
28079 + default:
28080 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
28081 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28082 + break;
28083 + }
28084 + break;
28085 +
28086 + default:
28087 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
28088 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
28089 + break;
28090 + }
28091 +}
28092 +
28093 +t_Error ValidateNextEngineParams(
28094 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
28095 + e_FmPcdCcStatsMode statsMode)
28096 +{
28097 + uint16_t absoluteProfileId;
28098 + t_Error err = E_OK;
28099 + uint8_t relativeSchemeId;
28100 +
28101 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
28102 + && (p_FmPcdCcNextEngineParams->statisticsEn))
28103 + RETURN_ERROR(
28104 + MAJOR,
28105 + E_CONFLICT,
28106 + ("Statistics are requested for a key, but statistics mode was set"
28107 + "to 'NONE' upon initialization"));
28108 +
28109 + switch (p_FmPcdCcNextEngineParams->nextEngine)
28110 + {
28111 + case (e_FM_PCD_INVALID):
28112 + err = E_NOT_SUPPORTED;
28113 + break;
28114 +
28115 + case (e_FM_PCD_DONE):
28116 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
28117 + == e_FM_PCD_ENQ_FRAME)
28118 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
28119 + {
28120 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
28121 + RETURN_ERROR(
28122 + MAJOR,
28123 + E_CONFLICT,
28124 + ("When overrideFqid is set, newFqid must not be zero"));
28125 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
28126 + & ~0x00FFFFFF)
28127 + RETURN_ERROR(
28128 + MAJOR, E_INVALID_VALUE,
28129 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
28130 + }
28131 + break;
28132 +
28133 + case (e_FM_PCD_KG):
28134 + relativeSchemeId =
28135 + FmPcdKgGetRelativeSchemeId(
28136 + h_FmPcd,
28137 + FmPcdKgGetSchemeId(
28138 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
28139 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
28140 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
28141 + if (!FmPcdKgIsSchemeValidSw(
28142 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
28143 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28144 + ("not valid schemeIndex in KG next engine param"));
28145 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
28146 + RETURN_ERROR(
28147 + MAJOR,
28148 + E_INVALID_STATE,
28149 + ("CC Node may point only to a scheme that is always direct."));
28150 + break;
28151 +
28152 + case (e_FM_PCD_PLCR):
28153 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
28154 + {
28155 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28156 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
28157 + {
28158 + err =
28159 + FmPcdPlcrGetAbsoluteIdByProfileParams(
28160 + h_FmPcd,
28161 + e_FM_PCD_PLCR_SHARED,
28162 + NULL,
28163 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
28164 + &absoluteProfileId);
28165 + if (err)
28166 + RETURN_ERROR(MAJOR, err,
28167 + ("Shared profile offset is out of range"));
28168 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
28169 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28170 + ("Invalid profile"));
28171 + }
28172 + }
28173 + break;
28174 +
28175 + case (e_FM_PCD_HASH):
28176 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
28177 + case (e_FM_PCD_CC):
28178 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
28179 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
28180 + ("handler to next Node is NULL"));
28181 + break;
28182 +
28183 +#if (DPAA_VERSION >= 11)
28184 + case (e_FM_PCD_FR):
28185 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
28186 + err = E_NOT_SUPPORTED;
28187 + break;
28188 +#endif /* (DPAA_VERSION >= 11) */
28189 +
28190 + default:
28191 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28192 + ("Next engine is not correct"));
28193 + }
28194 +
28195 +
28196 + return err;
28197 +}
28198 +
28199 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
28200 + uint32_t offset, bool glblMask,
28201 + uint8_t *parseArrayOffset, bool fromIc,
28202 + ccPrivateInfo_t icCode)
28203 +{
28204 + if (!fromIc)
28205 + {
28206 + switch (src)
28207 + {
28208 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
28209 + if (glblMask)
28210 + return CC_PC_GENERIC_WITH_MASK;
28211 + else
28212 + return CC_PC_GENERIC_WITHOUT_MASK;
28213 +
28214 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
28215 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
28216 + if (offset)
28217 + return CC_PR_OFFSET;
28218 + else
28219 + return CC_PR_WITHOUT_OFFSET;
28220 +
28221 + default:
28222 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28223 + return CC_PC_ILLEGAL;
28224 + }
28225 + }
28226 + else
28227 + {
28228 + switch (icCode)
28229 + {
28230 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
28231 + *parseArrayOffset = 0x50;
28232 + return CC_PC_GENERIC_IC_GMASK;
28233 +
28234 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
28235 + *parseArrayOffset = 0x48;
28236 + return CC_PC_GENERIC_IC_GMASK;
28237 +
28238 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
28239 + *parseArrayOffset = 0x48;
28240 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28241 +
28242 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
28243 + *parseArrayOffset = 0x16;
28244 + return CC_PC_GENERIC_IC_HASH_INDEXED;
28245 +
28246 + default:
28247 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
28248 + break;
28249 + }
28250 + }
28251 +
28252 + return CC_PC_ILLEGAL;
28253 +}
28254 +
28255 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
28256 + t_FmPcdFields field)
28257 +{
28258 + switch (hdr)
28259 + {
28260 + case (HEADER_TYPE_NONE):
28261 + ASSERT_COND(FALSE);
28262 + return CC_PC_ILLEGAL;
28263 +
28264 + case (HEADER_TYPE_ETH):
28265 + switch (field.eth)
28266 + {
28267 + case (NET_HEADER_FIELD_ETH_DA):
28268 + return CC_PC_FF_MACDST;
28269 + case (NET_HEADER_FIELD_ETH_SA):
28270 + return CC_PC_FF_MACSRC;
28271 + case (NET_HEADER_FIELD_ETH_TYPE):
28272 + return CC_PC_FF_ETYPE;
28273 + default:
28274 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28275 + return CC_PC_ILLEGAL;
28276 + }
28277 +
28278 + case (HEADER_TYPE_VLAN):
28279 + switch (field.vlan)
28280 + {
28281 + case (NET_HEADER_FIELD_VLAN_TCI):
28282 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28283 + || (index == e_FM_PCD_HDR_INDEX_1))
28284 + return CC_PC_FF_TCI1;
28285 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28286 + return CC_PC_FF_TCI2;
28287 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28288 + return CC_PC_ILLEGAL;
28289 + default:
28290 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28291 + return CC_PC_ILLEGAL;
28292 + }
28293 +
28294 + case (HEADER_TYPE_MPLS):
28295 + switch (field.mpls)
28296 + {
28297 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
28298 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28299 + || (index == e_FM_PCD_HDR_INDEX_1))
28300 + return CC_PC_FF_MPLS1;
28301 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28302 + return CC_PC_FF_MPLS_LAST;
28303 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
28304 + return CC_PC_ILLEGAL;
28305 + default:
28306 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28307 + return CC_PC_ILLEGAL;
28308 + }
28309 +
28310 + case (HEADER_TYPE_IPv4):
28311 + switch (field.ipv4)
28312 + {
28313 + case (NET_HEADER_FIELD_IPv4_DST_IP):
28314 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28315 + || (index == e_FM_PCD_HDR_INDEX_1))
28316 + return CC_PC_FF_IPV4DST1;
28317 + if (index == e_FM_PCD_HDR_INDEX_2)
28318 + return CC_PC_FF_IPV4DST2;
28319 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28320 + return CC_PC_ILLEGAL;
28321 + case (NET_HEADER_FIELD_IPv4_TOS):
28322 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28323 + || (index == e_FM_PCD_HDR_INDEX_1))
28324 + return CC_PC_FF_IPV4IPTOS_TC1;
28325 + if (index == e_FM_PCD_HDR_INDEX_2)
28326 + return CC_PC_FF_IPV4IPTOS_TC2;
28327 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28328 + return CC_PC_ILLEGAL;
28329 + case (NET_HEADER_FIELD_IPv4_PROTO):
28330 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28331 + || (index == e_FM_PCD_HDR_INDEX_1))
28332 + return CC_PC_FF_IPV4PTYPE1;
28333 + if (index == e_FM_PCD_HDR_INDEX_2)
28334 + return CC_PC_FF_IPV4PTYPE2;
28335 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28336 + return CC_PC_ILLEGAL;
28337 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
28338 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28339 + || (index == e_FM_PCD_HDR_INDEX_1))
28340 + return CC_PC_FF_IPV4SRC1;
28341 + if (index == e_FM_PCD_HDR_INDEX_2)
28342 + return CC_PC_FF_IPV4SRC2;
28343 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28344 + return CC_PC_ILLEGAL;
28345 + case (NET_HEADER_FIELD_IPv4_SRC_IP
28346 + | NET_HEADER_FIELD_IPv4_DST_IP):
28347 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28348 + || (index == e_FM_PCD_HDR_INDEX_1))
28349 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
28350 + if (index == e_FM_PCD_HDR_INDEX_2)
28351 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
28352 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
28353 + return CC_PC_ILLEGAL;
28354 + case (NET_HEADER_FIELD_IPv4_TTL):
28355 + return CC_PC_FF_IPV4TTL;
28356 + default:
28357 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28358 + return CC_PC_ILLEGAL;
28359 + }
28360 +
28361 + case (HEADER_TYPE_IPv6):
28362 + switch (field.ipv6)
28363 + {
28364 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
28365 + | NET_HEADER_FIELD_IPv6_TC):
28366 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28367 + || (index == e_FM_PCD_HDR_INDEX_1))
28368 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
28369 + if (index == e_FM_PCD_HDR_INDEX_2)
28370 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
28371 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28372 + return CC_PC_ILLEGAL;
28373 +
28374 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
28375 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28376 + || (index == e_FM_PCD_HDR_INDEX_1))
28377 + return CC_PC_FF_IPV6PTYPE1;
28378 + if (index == e_FM_PCD_HDR_INDEX_2)
28379 + return CC_PC_FF_IPV6PTYPE2;
28380 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28381 + return CC_PC_FF_IPPID;
28382 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28383 + return CC_PC_ILLEGAL;
28384 +
28385 + case (NET_HEADER_FIELD_IPv6_DST_IP):
28386 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28387 + || (index == e_FM_PCD_HDR_INDEX_1))
28388 + return CC_PC_FF_IPV6DST1;
28389 + if (index == e_FM_PCD_HDR_INDEX_2)
28390 + return CC_PC_FF_IPV6DST2;
28391 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28392 + return CC_PC_ILLEGAL;
28393 +
28394 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
28395 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28396 + || (index == e_FM_PCD_HDR_INDEX_1))
28397 + return CC_PC_FF_IPV6SRC1;
28398 + if (index == e_FM_PCD_HDR_INDEX_2)
28399 + return CC_PC_FF_IPV6SRC2;
28400 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
28401 + return CC_PC_ILLEGAL;
28402 +
28403 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
28404 + return CC_PC_FF_IPV6HOP_LIMIT;
28405 +
28406 + default:
28407 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28408 + return CC_PC_ILLEGAL;
28409 + }
28410 +
28411 + case (HEADER_TYPE_IP):
28412 + switch (field.ip)
28413 + {
28414 + case (NET_HEADER_FIELD_IP_DSCP):
28415 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
28416 + || (index == e_FM_PCD_HDR_INDEX_1))
28417 + return CC_PC_FF_IPDSCP;
28418 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28419 + return CC_PC_ILLEGAL;
28420 +
28421 + case (NET_HEADER_FIELD_IP_PROTO):
28422 + if (index == e_FM_PCD_HDR_INDEX_LAST)
28423 + return CC_PC_FF_IPPID;
28424 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
28425 + return CC_PC_ILLEGAL;
28426 +
28427 + default:
28428 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28429 + return CC_PC_ILLEGAL;
28430 + }
28431 +
28432 + case (HEADER_TYPE_GRE):
28433 + switch (field.gre)
28434 + {
28435 + case (NET_HEADER_FIELD_GRE_TYPE):
28436 + return CC_PC_FF_GREPTYPE;
28437 +
28438 + default:
28439 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28440 + return CC_PC_ILLEGAL;
28441 + }
28442 +
28443 + case (HEADER_TYPE_MINENCAP):
28444 + switch (field.minencap)
28445 + {
28446 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
28447 + return CC_PC_FF_MINENCAP_PTYPE;
28448 +
28449 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
28450 + return CC_PC_FF_MINENCAP_IPDST;
28451 +
28452 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
28453 + return CC_PC_FF_MINENCAP_IPSRC;
28454 +
28455 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
28456 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
28457 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
28458 +
28459 + default:
28460 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28461 + return CC_PC_ILLEGAL;
28462 + }
28463 +
28464 + case (HEADER_TYPE_TCP):
28465 + switch (field.tcp)
28466 + {
28467 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
28468 + return CC_PC_FF_L4PSRC;
28469 +
28470 + case (NET_HEADER_FIELD_TCP_PORT_DST):
28471 + return CC_PC_FF_L4PDST;
28472 +
28473 + case (NET_HEADER_FIELD_TCP_PORT_DST
28474 + | NET_HEADER_FIELD_TCP_PORT_SRC):
28475 + return CC_PC_FF_L4PSRC_L4PDST;
28476 +
28477 + default:
28478 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28479 + return CC_PC_ILLEGAL;
28480 + }
28481 +
28482 + case (HEADER_TYPE_PPPoE):
28483 + switch (field.pppoe)
28484 + {
28485 + case (NET_HEADER_FIELD_PPPoE_PID):
28486 + return CC_PC_FF_PPPPID;
28487 +
28488 + default:
28489 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28490 + return CC_PC_ILLEGAL;
28491 + }
28492 +
28493 + case (HEADER_TYPE_UDP):
28494 + switch (field.udp)
28495 + {
28496 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
28497 + return CC_PC_FF_L4PSRC;
28498 +
28499 + case (NET_HEADER_FIELD_UDP_PORT_DST):
28500 + return CC_PC_FF_L4PDST;
28501 +
28502 + case (NET_HEADER_FIELD_UDP_PORT_DST
28503 + | NET_HEADER_FIELD_UDP_PORT_SRC):
28504 + return CC_PC_FF_L4PSRC_L4PDST;
28505 +
28506 + default:
28507 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28508 + return CC_PC_ILLEGAL;
28509 + }
28510 +
28511 + default:
28512 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28513 + return CC_PC_ILLEGAL;
28514 + }
28515 +}
28516 +
28517 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
28518 + uint32_t offset, bool glblMask,
28519 + uint8_t *parseArrayOffset)
28520 +{
28521 + bool offsetRelevant = FALSE;
28522 +
28523 + if (offset)
28524 + offsetRelevant = TRUE;
28525 +
28526 + switch (hdr)
28527 + {
28528 + case (HEADER_TYPE_NONE):
28529 + ASSERT_COND(FALSE);
28530 + return CC_PC_ILLEGAL;
28531 +
28532 + case (HEADER_TYPE_ETH):
28533 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
28534 + break;
28535 +
28536 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
28537 + if (offset || glblMask)
28538 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
28539 + else
28540 + return CC_PC_PR_SHIM1;
28541 + break;
28542 +
28543 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
28544 + if (offset || glblMask)
28545 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
28546 + else
28547 + return CC_PC_PR_SHIM2;
28548 + break;
28549 +
28550 + case (HEADER_TYPE_LLC_SNAP):
28551 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
28552 + break;
28553 +
28554 + case (HEADER_TYPE_PPPoE):
28555 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
28556 + break;
28557 +
28558 + case (HEADER_TYPE_MPLS):
28559 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28560 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28561 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
28562 + else
28563 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28564 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
28565 + else
28566 + {
28567 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
28568 + return CC_PC_ILLEGAL;
28569 + }
28570 + break;
28571 +
28572 + case (HEADER_TYPE_IPv4):
28573 + case (HEADER_TYPE_IPv6):
28574 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28575 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28576 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
28577 + else
28578 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
28579 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
28580 + else
28581 + {
28582 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
28583 + return CC_PC_ILLEGAL;
28584 + }
28585 + break;
28586 +
28587 + case (HEADER_TYPE_MINENCAP):
28588 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
28589 + break;
28590 +
28591 + case (HEADER_TYPE_GRE):
28592 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
28593 + break;
28594 +
28595 + case (HEADER_TYPE_TCP):
28596 + case (HEADER_TYPE_UDP):
28597 + case (HEADER_TYPE_IPSEC_AH):
28598 + case (HEADER_TYPE_IPSEC_ESP):
28599 + case (HEADER_TYPE_DCCP):
28600 + case (HEADER_TYPE_SCTP):
28601 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
28602 + break;
28603 +
28604 + default:
28605 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
28606 + return CC_PC_ILLEGAL;
28607 + }
28608 +
28609 + if (offsetRelevant)
28610 + return CC_PR_OFFSET;
28611 + else
28612 + return CC_PR_WITHOUT_OFFSET;
28613 +}
28614 +
28615 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
28616 + uint32_t offset, uint8_t *parseArrayOffset,
28617 + e_FmPcdHdrIndex hdrIndex)
28618 +{
28619 + bool offsetRelevant = FALSE;
28620 +
28621 + if (offset)
28622 + offsetRelevant = TRUE;
28623 +
28624 + switch (hdr)
28625 + {
28626 + case (HEADER_TYPE_NONE):
28627 + ASSERT_COND(FALSE);
28628 + break;
28629 + case (HEADER_TYPE_ETH):
28630 + switch (field.eth)
28631 + {
28632 + case (NET_HEADER_FIELD_ETH_TYPE):
28633 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
28634 + break;
28635 +
28636 + default:
28637 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28638 + return CC_PC_ILLEGAL;
28639 + }
28640 + break;
28641 +
28642 + case (HEADER_TYPE_VLAN):
28643 + switch (field.vlan)
28644 + {
28645 + case (NET_HEADER_FIELD_VLAN_TCI):
28646 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
28647 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
28648 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
28649 + else
28650 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
28651 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
28652 + break;
28653 +
28654 + default:
28655 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
28656 + return CC_PC_ILLEGAL;
28657 + }
28658 + break;
28659 +
28660 + default:
28661 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
28662 + return CC_PC_ILLEGAL;
28663 + }
28664 +
28665 + if (offsetRelevant)
28666 + return CC_PR_OFFSET;
28667 + else
28668 + return CC_PR_WITHOUT_OFFSET;
28669 +}
28670 +
28671 +static void FillAdOfTypeResult(t_Handle h_Ad,
28672 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28673 + t_FmPcd *p_FmPcd,
28674 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
28675 +{
28676 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
28677 + t_Handle h_TmpAd;
28678 + uint32_t tmp = 0, tmpNia = 0;
28679 + uint16_t profileId;
28680 + t_Handle p_AdNewPtr = NULL;
28681 + t_Error err = E_OK;
28682 +
28683 + /* There are 3 cases handled in this routine of building a "result" type AD.
28684 + * Case 1: No Manip. The action descriptor is built within the match table.
28685 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28686 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28687 + * initialized and returned here.
28688 + * p_AdResult (within the match table) will be initialized after
28689 + * this routine returns and point to the existing AD.
28690 + * Case 3: Manip exists. The action descriptor is built within the match table.
28691 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
28692 + *
28693 + * If statistics were enabled and the statistics mode of this node requires
28694 + * a statistics Ad, it will be placed after the result Ad and before the
28695 + * manip Ad, if manip Ad exists here.
28696 + */
28697 +
28698 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28699 + * AD will be written into the match table itself (case (1))*/
28700 + p_AdNewPtr = p_AdResult;
28701 +
28702 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28703 + if (p_FmPcdCcStatsParams)
28704 + {
28705 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28706 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28707 +
28708 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
28709 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28710 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28711 + h_Ad = h_TmpAd;
28712 +
28713 + p_AdNewPtr = h_Ad;
28714 + p_AdResult = h_Ad;
28715 +
28716 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28717 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28718 + }
28719 +
28720 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
28721 + if (p_CcNextEngineParams->h_Manip)
28722 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
28723 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
28724 +
28725 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28726 + if (p_AdNewPtr)
28727 + {
28728 + /* case (1) and (2) */
28729 + switch (p_CcNextEngineParams->nextEngine)
28730 + {
28731 + case (e_FM_PCD_DONE):
28732 + if (p_CcNextEngineParams->params.enqueueParams.action
28733 + == e_FM_PCD_ENQ_FRAME)
28734 + {
28735 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
28736 + {
28737 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28738 + tmp |=
28739 + p_CcNextEngineParams->params.enqueueParams.newFqid;
28740 +#if (DPAA_VERSION >= 11)
28741 + tmp |=
28742 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
28743 + & FM_PCD_AD_RESULT_VSP_MASK)
28744 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28745 +#endif /* (DPAA_VERSION >= 11) */
28746 + }
28747 + else
28748 + {
28749 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28750 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28751 + }
28752 + }
28753 +
28754 + if (p_CcNextEngineParams->params.enqueueParams.action
28755 + == e_FM_PCD_DROP_FRAME)
28756 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
28757 + else
28758 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
28759 + break;
28760 +
28761 + case (e_FM_PCD_KG):
28762 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
28763 + {
28764 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28765 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
28766 +#if (DPAA_VERSION >= 11)
28767 + tmp |=
28768 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
28769 + & FM_PCD_AD_RESULT_VSP_MASK)
28770 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28771 +#endif /* (DPAA_VERSION >= 11) */
28772 + }
28773 + else
28774 + {
28775 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28776 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
28777 + }
28778 + tmpNia = NIA_KG_DIRECT;
28779 + tmpNia |= NIA_ENG_KG;
28780 + tmpNia |= NIA_KG_CC_EN;
28781 + tmpNia |= FmPcdKgGetSchemeId(
28782 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
28783 + break;
28784 +
28785 + case (e_FM_PCD_PLCR):
28786 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
28787 + {
28788 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
28789 +
28790 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
28791 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
28792 + {
28793 + tmpNia |= NIA_PLCR_ABSOLUTE;
28794 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
28795 + (t_Handle)p_FmPcd,
28796 + e_FM_PCD_PLCR_SHARED,
28797 + NULL,
28798 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
28799 + &profileId);
28800 +
28801 + if (err != E_OK) {
28802 + REPORT_ERROR(MAJOR, err, NO_MSG);
28803 + return;
28804 + }
28805 +
28806 + }
28807 + else
28808 + profileId =
28809 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28810 +
28811 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
28812 +#if (DPAA_VERSION >= 11)
28813 + tmp |=
28814 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
28815 + & FM_PCD_AD_RESULT_VSP_MASK)
28816 + << FM_PCD_AD_RESULT_VSP_SHIFT;
28817 +#endif /* (DPAA_VERSION >= 11) */
28818 + WRITE_UINT32(
28819 + p_AdResult->plcrProfile,
28820 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
28821 + }
28822 + else
28823 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
28824 +
28825 + tmpNia |=
28826 + NIA_ENG_PLCR
28827 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
28828 + break;
28829 +
28830 + default:
28831 + return;
28832 + }WRITE_UINT32(p_AdResult->fqid, tmp);
28833 +
28834 + if (p_CcNextEngineParams->h_Manip)
28835 + {
28836 + tmp = GET_UINT32(p_AdResult->plcrProfile);
28837 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
28838 + - (p_FmPcd->physicalMuramBase)) >> 4;
28839 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
28840 +
28841 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
28842 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
28843 + }
28844 +
28845 +#if (DPAA_VERSION >= 11)
28846 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
28847 +#endif /* (DPAA_VERSION >= 11) */
28848 + WRITE_UINT32(p_AdResult->nia, tmpNia);
28849 + }
28850 +}
28851 +
28852 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
28853 + t_Handle h_FmPort, t_Handle h_FmTree,
28854 + bool validate)
28855 +{
28856 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
28857 +
28858 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
28859 + p_CcTree->keyAndNextEngineParams,
28860 + p_CcTree->numOfEntries,
28861 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
28862 + h_FmTree, FALSE);
28863 +}
28864 +
28865 +
28866 +static void ReleaseNewNodeCommonPart(
28867 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28868 +{
28869 + if (p_AdditionalInfo->p_AdTableNew)
28870 + FM_MURAM_FreeMem(
28871 + FmPcdGetMuramHandle(
28872 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28873 + p_AdditionalInfo->p_AdTableNew);
28874 +
28875 + if (p_AdditionalInfo->p_KeysMatchTableNew)
28876 + FM_MURAM_FreeMem(
28877 + FmPcdGetMuramHandle(
28878 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
28879 + p_AdditionalInfo->p_KeysMatchTableNew);
28880 +}
28881 +
28882 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
28883 + uint8_t *p_Mask)
28884 +{
28885 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
28886 +
28887 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
28888 + && !p_CcNode->lclMask)
28889 + {
28890 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
28891 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
28892 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
28893 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
28894 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
28895 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
28896 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
28897 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
28898 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
28899 + {
28900 + p_CcNode->glblMaskSize = 0;
28901 + p_CcNode->lclMask = TRUE;
28902 + }
28903 + else
28904 + {
28905 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
28906 + p_CcNode->glblMaskUpdated = TRUE;
28907 + p_CcNode->glblMaskSize = 4;
28908 + }
28909 + }
28910 + else
28911 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
28912 + {
28913 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
28914 + {
28915 + p_CcNode->lclMask = TRUE;
28916 + p_CcNode->glblMaskSize = 0;
28917 + }
28918 + }
28919 + else
28920 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
28921 + {
28922 + uint32_t tmpMask = 0xffffffff;
28923 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
28924 + {
28925 + p_CcNode->lclMask = TRUE;
28926 + p_CcNode->glblMaskSize = 0;
28927 + }
28928 + }
28929 + else
28930 + if (p_Mask)
28931 + {
28932 + p_CcNode->lclMask = TRUE;
28933 + p_CcNode->glblMaskSize = 0;
28934 + }
28935 +
28936 + /* In static mode (maxNumOfKeys > 0), local mask is supported
28937 + only is mask support was enabled at initialization */
28938 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
28939 + {
28940 + p_CcNode->lclMask = FALSE;
28941 + p_CcNode->glblMaskSize = prvGlblMaskSize;
28942 + return ERROR_CODE(E_NOT_SUPPORTED);
28943 + }
28944 +
28945 + return E_OK;
28946 +}
28947 +
28948 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
28949 +{
28950 + t_FmPcd *p_FmPcd;
28951 + t_Handle h_Ad;
28952 +
28953 + if (isTree)
28954 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28955 + else
28956 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
28957 +
28958 + if ((isTree && p_FmPcd->p_CcShadow)
28959 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
28960 + {
28961 + /* The allocated shadow is divided as follows:
28962 + 0 . . . 16 . . .
28963 + ---------------------------------------------------
28964 + | Shadow | Shadow Keys | Shadow Next |
28965 + | Ad | Match Table | Engine Table |
28966 + | (16 bytes) | (maximal size) | (maximal size) |
28967 + ---------------------------------------------------
28968 + */
28969 + if (!p_FmPcd->p_CcShadow)
28970 + {
28971 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
28972 + return NULL;
28973 + }
28974 +
28975 + h_Ad = p_FmPcd->p_CcShadow;
28976 + }
28977 + else
28978 + {
28979 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
28980 + FM_PCD_CC_AD_ENTRY_SIZE,
28981 + FM_PCD_CC_AD_TABLE_ALIGN);
28982 + if (!h_Ad)
28983 + {
28984 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
28985 + return NULL;
28986 + }
28987 + }
28988 +
28989 + return h_Ad;
28990 +}
28991 +
28992 +static t_Error BuildNewNodeCommonPart(
28993 + t_FmPcdCcNode *p_CcNode, int *size,
28994 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
28995 +{
28996 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
28997 +
28998 + if (p_CcNode->lclMask)
28999 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
29000 + else
29001 + *size = p_CcNode->ccKeySizeAccExtraction;
29002 +
29003 + if (p_CcNode->maxNumOfKeys == 0)
29004 + {
29005 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
29006 + FmPcdGetMuramHandle(p_FmPcd),
29007 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
29008 + * FM_PCD_CC_AD_ENTRY_SIZE),
29009 + FM_PCD_CC_AD_TABLE_ALIGN);
29010 + if (!p_AdditionalInfo->p_AdTableNew)
29011 + RETURN_ERROR(
29012 + MAJOR, E_NO_MEMORY,
29013 + ("MURAM allocation for CC node action descriptors table"));
29014 +
29015 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
29016 + FmPcdGetMuramHandle(p_FmPcd),
29017 + (uint32_t)(*size * sizeof(uint8_t)
29018 + * (p_AdditionalInfo->numOfKeys + 1)),
29019 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
29020 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
29021 + {
29022 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29023 + p_AdditionalInfo->p_AdTableNew);
29024 + p_AdditionalInfo->p_AdTableNew = NULL;
29025 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29026 + ("MURAM allocation for CC node key match table"));
29027 + }
29028 +
29029 + MemSet8(
29030 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
29031 + 0,
29032 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
29033 + * FM_PCD_CC_AD_ENTRY_SIZE));
29034 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
29035 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
29036 + }
29037 + else
29038 + {
29039 + /* The allocated shadow is divided as follows:
29040 + 0 . . . 16 . . .
29041 + ---------------------------------------------------
29042 + | Shadow | Shadow Keys | Shadow Next |
29043 + | Ad | Match Table | Engine Table |
29044 + | (16 bytes) | (maximal size) | (maximal size) |
29045 + ---------------------------------------------------
29046 + */
29047 +
29048 + if (!p_FmPcd->p_CcShadow)
29049 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
29050 +
29051 + p_AdditionalInfo->p_KeysMatchTableNew =
29052 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
29053 + p_AdditionalInfo->p_AdTableNew =
29054 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
29055 +
29056 + MemSet8(
29057 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
29058 + 0,
29059 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
29060 + * FM_PCD_CC_AD_ENTRY_SIZE));
29061 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
29062 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
29063 + }
29064 +
29065 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
29066 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
29067 +
29068 + return E_OK;
29069 +}
29070 +
29071 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
29072 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29073 + t_FmPcdCcKeyParams *p_KeyParams,
29074 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
29075 +{
29076 + t_Error err = E_OK;
29077 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29078 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29079 + int size;
29080 + int i = 0, j = 0;
29081 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
29082 + uint32_t requiredAction = 0;
29083 + bool prvLclMask;
29084 + t_CcNodeInformation *p_CcNodeInformation;
29085 + t_FmPcdCcStatsParams statsParams = { 0 };
29086 + t_List *p_Pos;
29087 + t_FmPcdStatsObj *p_StatsObj;
29088 +
29089 + /* Check that new NIA is legal */
29090 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
29091 + p_CcNode->statisticsMode);
29092 + if (err)
29093 + RETURN_ERROR(MAJOR, err, NO_MSG);
29094 +
29095 + prvLclMask = p_CcNode->lclMask;
29096 +
29097 + /* Check that new key is not require update of localMask */
29098 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
29099 + p_KeyParams->p_Mask);
29100 + if (err)
29101 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29102 +
29103 + /* Update internal data structure with new next engine for the given index */
29104 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29105 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29106 +
29107 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
29108 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
29109 +
29110 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29111 + == e_FM_PCD_CC)
29112 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29113 + {
29114 + err =
29115 + AllocAndFillAdForContLookupManip(
29116 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
29117 + if (err)
29118 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29119 + }
29120 +
29121 + if (p_KeyParams->p_Mask)
29122 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
29123 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
29124 + else
29125 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29126 + p_CcNode->userSizeOfExtraction);
29127 +
29128 + /* Update numOfKeys */
29129 + if (add)
29130 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
29131 + else
29132 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
29133 +
29134 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
29135 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29136 + if (err)
29137 + RETURN_ERROR(MAJOR, err, NO_MSG);
29138 +
29139 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29140 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29141 + {
29142 + err = FmPcdManipCheckParamsForCcNextEngine(
29143 + &p_KeyParams->ccNextEngineParams, &requiredAction);
29144 + if (err)
29145 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29146 + }
29147 +
29148 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29149 + requiredAction;
29150 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29151 + UPDATE_CC_WITH_TREE;
29152 +
29153 + /* Update new Ad and new Key Table according to new requirement */
29154 + i = 0;
29155 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
29156 + {
29157 + p_AdTableNewTmp =
29158 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29159 +
29160 + if (j == keyIndex)
29161 + {
29162 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
29163 + {
29164 + /* Allocate a statistics object that holds statistics AD and counters.
29165 + - For added key - New statistics AD and counters pointer need to be allocated
29166 + new statistics object. If statistics were enabled, we need to replace the
29167 + existing descriptor with a new descriptor with nullified counters.
29168 + */
29169 + p_StatsObj = GetStatsObj(p_CcNode);
29170 + ASSERT_COND(p_StatsObj);
29171 +
29172 + /* Store allocated statistics object */
29173 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29174 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29175 + p_StatsObj;
29176 +
29177 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29178 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29179 +#if (DPAA_VERSION >= 11)
29180 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
29181 +
29182 +#endif /* (DPAA_VERSION >= 11) */
29183 +
29184 + /* Building action descriptor for the received new key */
29185 + NextStepAd(p_AdTableNewTmp, &statsParams,
29186 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29187 + }
29188 + else
29189 + {
29190 + /* Building action descriptor for the received new key */
29191 + NextStepAd(p_AdTableNewTmp, NULL,
29192 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
29193 + }
29194 +
29195 + /* Copy the received new key into keys match table */
29196 + p_KeysMatchTableNewTmp =
29197 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
29198 +
29199 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
29200 + p_CcNode->userSizeOfExtraction);
29201 +
29202 + /* Update mask for the received new key */
29203 + if (p_CcNode->lclMask)
29204 + {
29205 + if (p_KeyParams->p_Mask)
29206 + {
29207 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29208 + p_CcNode->ccKeySizeAccExtraction),
29209 + p_KeyParams->p_Mask,
29210 + p_CcNode->userSizeOfExtraction);
29211 + }
29212 + else
29213 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29214 + {
29215 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29216 + p_CcNode->ccKeySizeAccExtraction),
29217 + 0xff, p_CcNode->userSizeOfExtraction);
29218 + }
29219 + else
29220 + {
29221 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29222 + p_CcNode->ccKeySizeAccExtraction),
29223 + p_CcNode->p_GlblMask,
29224 + p_CcNode->userSizeOfExtraction);
29225 + }
29226 + }
29227 +
29228 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
29229 + if (!add)
29230 + i++;
29231 + }
29232 + else
29233 + {
29234 + /* Copy existing action descriptors to the newly allocated Ad table */
29235 + p_AdTableOldTmp =
29236 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29237 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
29238 + FM_PCD_CC_AD_ENTRY_SIZE);
29239 +
29240 + /* Copy existing keys and their masks to the newly allocated keys match table */
29241 + p_KeysMatchTableNewTmp =
29242 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29243 + p_KeysMatchTableOldTmp =
29244 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
29245 +
29246 + if (p_CcNode->lclMask)
29247 + {
29248 + if (prvLclMask)
29249 + {
29250 + MemCpy8(
29251 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29252 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29253 + p_CcNode->ccKeySizeAccExtraction);
29254 + }
29255 + else
29256 + {
29257 + p_KeysMatchTableOldTmp =
29258 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29259 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29260 +
29261 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29262 + {
29263 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29264 + p_CcNode->ccKeySizeAccExtraction),
29265 + 0xff, p_CcNode->userSizeOfExtraction);
29266 + }
29267 + else
29268 + {
29269 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29270 + p_CcNode->ccKeySizeAccExtraction),
29271 + p_CcNode->p_GlblMask,
29272 + p_CcNode->userSizeOfExtraction);
29273 + }
29274 + }
29275 + }
29276 +
29277 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29278 + p_CcNode->ccKeySizeAccExtraction);
29279 +
29280 + i++;
29281 + }
29282 + }
29283 +
29284 + /* Miss action descriptor */
29285 + p_AdTableNewTmp =
29286 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29287 + p_AdTableOldTmp =
29288 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
29289 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29290 +
29291 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
29292 + {
29293 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
29294 + {
29295 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29296 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29297 + /* Update the manipulation which has to be updated from parameters of the port */
29298 + /* It's has to be updated with restrictions defined in the function */
29299 + err =
29300 + SetRequiredAction(
29301 + p_CcNode->h_FmPcd,
29302 + p_CcNode->shadowAction
29303 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29304 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29305 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29306 + 1, p_CcNodeInformation->h_CcNode);
29307 + if (err)
29308 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29309 +
29310 + err =
29311 + CcUpdateParam(
29312 + p_CcNode->h_FmPcd,
29313 + NULL,
29314 + NULL,
29315 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29316 + 1,
29317 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
29318 + TRUE, p_CcNodeInformation->index,
29319 + p_CcNodeInformation->h_CcNode, TRUE);
29320 + if (err)
29321 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29322 + }
29323 + }
29324 +
29325 + if (p_CcNode->lclMask)
29326 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
29327 +
29328 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
29329 + p_AdditionalInfo->h_NodeForAdd =
29330 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
29331 + if (p_KeyParams->ccNextEngineParams.h_Manip)
29332 + p_AdditionalInfo->h_ManipForAdd =
29333 + p_KeyParams->ccNextEngineParams.h_Manip;
29334 +
29335 +#if (DPAA_VERSION >= 11)
29336 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
29337 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
29338 + p_AdditionalInfo->h_FrmReplicForAdd =
29339 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
29340 +#endif /* (DPAA_VERSION >= 11) */
29341 +
29342 + if (!add)
29343 + {
29344 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29345 + == e_FM_PCD_CC)
29346 + p_AdditionalInfo->h_NodeForRmv =
29347 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29348 +
29349 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29350 + p_AdditionalInfo->h_ManipForRmv =
29351 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29352 +
29353 + /* If statistics were previously enabled, store the old statistics object to be released */
29354 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29355 + {
29356 + p_AdditionalInfo->p_StatsObjForRmv =
29357 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29358 + }
29359 +
29360 +#if (DPAA_VERSION >= 11)
29361 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29362 + == e_FM_PCD_FR)
29363 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29364 + p_AdditionalInfo->h_FrmReplicForRmv =
29365 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29366 +#endif /* (DPAA_VERSION >= 11) */
29367 + }
29368 +
29369 + return E_OK;
29370 +}
29371 +
29372 +static t_Error BuildNewNodeRemoveKey(
29373 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
29374 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29375 +{
29376 + int i = 0, j = 0;
29377 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29378 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29379 + int size;
29380 + t_Error err = E_OK;
29381 +
29382 + /*save new numOfKeys*/
29383 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
29384 +
29385 + /*function which allocates in the memory new KeyTbl, AdTbl*/
29386 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29387 + if (err)
29388 + RETURN_ERROR(MAJOR, err, NO_MSG);
29389 +
29390 + /*update new Ad and new Key Table according to new requirement*/
29391 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
29392 + {
29393 + if (j == keyIndex)
29394 + j++;
29395 +
29396 + if (j == p_CcNode->numOfKeys)
29397 + break;
29398 + p_AdTableNewTmp =
29399 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29400 + p_AdTableOldTmp =
29401 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29402 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29403 +
29404 + p_KeysMatchTableOldTmp =
29405 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
29406 + p_KeysMatchTableNewTmp =
29407 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
29408 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29409 + size * sizeof(uint8_t));
29410 + }
29411 +
29412 + p_AdTableNewTmp =
29413 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
29414 + p_AdTableOldTmp =
29415 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
29416 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29417 +
29418 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29419 + == e_FM_PCD_CC)
29420 + p_AdditionalInfo->h_NodeForRmv =
29421 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29422 +
29423 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29424 + p_AdditionalInfo->h_ManipForRmv =
29425 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29426 +
29427 + /* If statistics were previously enabled, store the old statistics object to be released */
29428 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29429 + {
29430 + p_AdditionalInfo->p_StatsObjForRmv =
29431 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29432 + }
29433 +
29434 +#if (DPAA_VERSION >= 11)
29435 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29436 + == e_FM_PCD_FR)
29437 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29438 + p_AdditionalInfo->h_FrmReplicForRmv =
29439 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29440 +#endif /* (DPAA_VERSION >= 11) */
29441 +
29442 + return E_OK;
29443 +}
29444 +
29445 +static t_Error BuildNewNodeModifyKey(
29446 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
29447 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29448 +{
29449 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
29450 + t_Error err = E_OK;
29451 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
29452 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
29453 + int size;
29454 + int i = 0, j = 0;
29455 + bool prvLclMask;
29456 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
29457 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
29458 +
29459 + prvLclMask = p_CcNode->lclMask;
29460 +
29461 + /* Check that new key is not require update of localMask */
29462 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
29463 + if (err)
29464 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29465 +
29466 + /* Update internal data structure with new next engine for the given index */
29467 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
29468 + p_CcNode->userSizeOfExtraction);
29469 +
29470 + if (p_Mask)
29471 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
29472 + p_CcNode->userSizeOfExtraction);
29473 + else
29474 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
29475 + p_CcNode->userSizeOfExtraction);
29476 +
29477 + /*function which build in the memory new KeyTbl, AdTbl*/
29478 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
29479 + if (err)
29480 + RETURN_ERROR(MAJOR, err, NO_MSG);
29481 +
29482 + /*fill the New AdTable and New KeyTable*/
29483 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
29484 + {
29485 + p_AdTableNewTmp =
29486 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
29487 + p_AdTableOldTmp =
29488 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
29489 +
29490 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29491 +
29492 + if (j == keyIndex)
29493 + {
29494 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
29495 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
29496 + {
29497 + /* As statistics were enabled, we need to update the existing
29498 + statistics descriptor with a new nullified counters. */
29499 + p_StatsObj = GetStatsObj(p_CcNode);
29500 + ASSERT_COND(p_StatsObj);
29501 +
29502 + SetStatsCounters(
29503 + p_AdTableNewTmp,
29504 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
29505 + - p_FmPcd->physicalMuramBase)));
29506 +
29507 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
29508 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
29509 +
29510 + /* As we need to replace only the counters, we build a new statistics
29511 + object that holds the old AD and the new counters - this will be the
29512 + currently used statistics object.
29513 + The newly allocated AD is not required and may be released back to
29514 + the available objects with the previous counters pointer. */
29515 + p_StatsObj->h_StatsAd =
29516 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29517 +
29518 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
29519 + tmpStatsObj.h_StatsAd;
29520 +
29521 + /* Store allocated statistics object */
29522 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29523 + p_StatsObj;
29524 +
29525 + /* As statistics were previously enabled, store the old statistics object to be released */
29526 + p_AdditionalInfo->p_StatsObjForRmv =
29527 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
29528 + }
29529 +
29530 + p_KeysMatchTableNewTmp =
29531 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29532 +
29533 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
29534 + p_CcNode->userSizeOfExtraction);
29535 +
29536 + if (p_CcNode->lclMask)
29537 + {
29538 + if (p_Mask)
29539 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29540 + p_CcNode->ccKeySizeAccExtraction),
29541 + p_Mask, p_CcNode->userSizeOfExtraction);
29542 + else
29543 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29544 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29545 + p_CcNode->ccKeySizeAccExtraction),
29546 + 0xff, p_CcNode->userSizeOfExtraction);
29547 + else
29548 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
29549 + p_CcNode->ccKeySizeAccExtraction),
29550 + p_CcNode->p_GlblMask,
29551 + p_CcNode->userSizeOfExtraction);
29552 + }
29553 + }
29554 + else
29555 + {
29556 + p_KeysMatchTableNewTmp =
29557 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
29558 + p_KeysMatchTableOldTmp =
29559 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
29560 +
29561 + if (p_CcNode->lclMask)
29562 + {
29563 + if (prvLclMask)
29564 + MemCpy8(
29565 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29566 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
29567 + p_CcNode->userSizeOfExtraction);
29568 + else
29569 + {
29570 + p_KeysMatchTableOldTmp =
29571 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
29572 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
29573 +
29574 + if (p_CcNode->ccKeySizeAccExtraction > 4)
29575 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
29576 + p_CcNode->ccKeySizeAccExtraction),
29577 + 0xff, p_CcNode->userSizeOfExtraction);
29578 + else
29579 + MemCpy8(
29580 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
29581 + p_CcNode->p_GlblMask,
29582 + p_CcNode->userSizeOfExtraction);
29583 + }
29584 + }
29585 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
29586 + p_CcNode->ccKeySizeAccExtraction);
29587 + }
29588 + }
29589 +
29590 + p_AdTableNewTmp =
29591 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
29592 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
29593 +
29594 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
29595 +
29596 + return E_OK;
29597 +}
29598 +
29599 +static t_Error BuildNewNodeModifyNextEngine(
29600 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29601 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
29602 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
29603 +{
29604 + t_Error err = E_OK;
29605 + uint32_t requiredAction = 0;
29606 + t_List *p_Pos;
29607 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
29608 + t_Handle p_Ad;
29609 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
29610 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
29611 + t_FmPcdStatsObj *p_StatsObj;
29612 + t_FmPcdCcStatsParams statsParams = { 0 };
29613 +
29614 + ASSERT_COND(p_CcNextEngineParams);
29615 +
29616 + /* check that new NIA is legal */
29617 + if (!p_AdditionalInfo->tree)
29618 + err = ValidateNextEngineParams(
29619 + h_FmPcd, p_CcNextEngineParams,
29620 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
29621 + else
29622 + /* Statistics are not supported for CC root */
29623 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
29624 + e_FM_PCD_CC_STATS_MODE_NONE);
29625 + if (err)
29626 + RETURN_ERROR(MAJOR, err, NO_MSG);
29627 +
29628 + /* Update internal data structure for next engine per index (index - key) */
29629 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
29630 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
29631 +
29632 + /* Check that manip is legal and what requiredAction is necessary for this manip */
29633 + if (p_CcNextEngineParams->h_Manip)
29634 + {
29635 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
29636 + &requiredAction);
29637 + if (err)
29638 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29639 + }
29640 +
29641 + if (!p_AdditionalInfo->tree)
29642 + {
29643 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29644 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
29645 + p_Ad = p_FmPcdCcNode1->h_AdTable;
29646 +
29647 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29648 + == e_FM_PCD_CC)
29649 + p_AdditionalInfo->h_NodeForRmv =
29650 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29651 +
29652 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29653 + p_AdditionalInfo->h_ManipForRmv =
29654 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29655 +
29656 +#if (DPAA_VERSION >= 11)
29657 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29658 + == e_FM_PCD_FR)
29659 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29660 + p_AdditionalInfo->h_FrmReplicForRmv =
29661 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29662 +#endif /* (DPAA_VERSION >= 11) */
29663 + }
29664 + else
29665 + {
29666 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29667 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
29668 +
29669 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29670 + == e_FM_PCD_CC)
29671 + p_AdditionalInfo->h_NodeForRmv =
29672 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
29673 +
29674 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
29675 + p_AdditionalInfo->h_ManipForRmv =
29676 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
29677 +
29678 +#if (DPAA_VERSION >= 11)
29679 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
29680 + == e_FM_PCD_FR)
29681 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
29682 + p_AdditionalInfo->h_FrmReplicForRmv =
29683 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
29684 +#endif /* (DPAA_VERSION >= 11) */
29685 + }
29686 +
29687 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29688 + && p_CcNextEngineParams->h_Manip)
29689 + {
29690 + err = AllocAndFillAdForContLookupManip(
29691 + p_CcNextEngineParams->params.ccParams.h_CcNode);
29692 + if (err)
29693 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29694 + }
29695 +
29696 + ASSERT_COND(p_Ad);
29697 +
29698 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29699 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
29700 +
29701 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
29702 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
29703 + only the actual Nia-Ad should be modified. */
29704 + if ((!p_AdditionalInfo->tree)
29705 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29706 + && (p_CcNextEngineParams->statisticsEn))
29707 + ccNodeInfo.h_CcNode =
29708 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
29709 +
29710 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29711 +
29712 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29713 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
29714 + if (!p_Ad)
29715 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
29716 + ("MURAM allocation for CC node action descriptor"));
29717 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
29718 +
29719 + /* If statistics were not enabled before, but requested now - Allocate a statistics
29720 + object that holds statistics AD and counters. */
29721 + if ((!p_AdditionalInfo->tree)
29722 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29723 + && (p_CcNextEngineParams->statisticsEn))
29724 + {
29725 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
29726 + ASSERT_COND(p_StatsObj);
29727 +
29728 + /* Store allocated statistics object */
29729 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
29730 + p_StatsObj;
29731 +
29732 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
29733 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
29734 +
29735 +#if (DPAA_VERSION >= 11)
29736 + statsParams.h_StatsFLRs =
29737 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
29738 +
29739 +#endif /* (DPAA_VERSION >= 11) */
29740 +
29741 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
29742 + }
29743 + else
29744 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
29745 +
29746 + ccNodeInfo.h_CcNode = p_Ad;
29747 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
29748 +
29749 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
29750 + requiredAction;
29751 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
29752 + UPDATE_CC_WITH_TREE;
29753 +
29754 + if (!p_AdditionalInfo->tree)
29755 + {
29756 + ASSERT_COND(p_FmPcdCcNode1);
29757 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
29758 + {
29759 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
29760 + {
29761 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29762 +
29763 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
29764 + /* Update the manipulation which has to be updated from parameters of the port
29765 + it's has to be updated with restrictions defined in the function */
29766 +
29767 + err =
29768 + SetRequiredAction(
29769 + p_FmPcdCcNode1->h_FmPcd,
29770 + p_FmPcdCcNode1->shadowAction
29771 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29772 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29773 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
29774 + if (err)
29775 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29776 +
29777 + err = CcUpdateParam(
29778 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
29779 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
29780 + p_Ad, TRUE, p_CcNodeInformation->index,
29781 + p_CcNodeInformation->h_CcNode, TRUE);
29782 + if (err)
29783 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29784 + }
29785 + }
29786 + }
29787 + else
29788 + {
29789 + ASSERT_COND(p_FmPcdCcTree);
29790 +
29791 + err =
29792 + SetRequiredAction(
29793 + h_FmPcd,
29794 + p_FmPcdCcTree->requiredAction
29795 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
29796 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29797 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
29798 + if (err)
29799 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29800 +
29801 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
29802 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
29803 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
29804 + if (err)
29805 + RETURN_ERROR(MAJOR, err, (NO_MSG));
29806 + }
29807 +
29808 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
29809 + p_AdditionalInfo->h_NodeForAdd =
29810 + p_CcNextEngineParams->params.ccParams.h_CcNode;
29811 + if (p_CcNextEngineParams->h_Manip)
29812 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
29813 +
29814 + /* If statistics were previously enabled, but now are disabled,
29815 + store the old statistics object to be released */
29816 + if ((!p_AdditionalInfo->tree)
29817 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
29818 + && (!p_CcNextEngineParams->statisticsEn))
29819 + {
29820 + p_AdditionalInfo->p_StatsObjForRmv =
29821 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
29822 +
29823 +
29824 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
29825 + }
29826 +#if (DPAA_VERSION >= 11)
29827 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
29828 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
29829 + p_AdditionalInfo->h_FrmReplicForAdd =
29830 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
29831 +#endif /* (DPAA_VERSION >= 11) */
29832 +
29833 + return E_OK;
29834 +}
29835 +
29836 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
29837 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29838 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29839 +{
29840 + t_CcNodeInformation *p_CcNodeInformation;
29841 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
29842 + t_List *p_Pos;
29843 + int i = 0;
29844 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
29845 + t_CcNodeInformation ccNodeInfo;
29846 +
29847 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
29848 + {
29849 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29850 + p_NodePtrOnCurrentMdfNode =
29851 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
29852 +
29853 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
29854 +
29855 + /* Search in the previous node which exact index points on this current modified node for getting AD */
29856 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
29857 + {
29858 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29859 + == e_FM_PCD_CC)
29860 + {
29861 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29862 + == (t_Handle)p_CrntMdfNode)
29863 + {
29864 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
29865 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
29866 + else
29867 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
29868 + p_AdTablePtOnCrntCurrentMdfNode =
29869 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
29870 + else
29871 + p_AdTablePtOnCrntCurrentMdfNode =
29872 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
29873 +
29874 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29875 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
29876 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29877 +
29878 + if (!(*p_NextEngineParams))
29879 + *p_NextEngineParams =
29880 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29881 + }
29882 + }
29883 + }
29884 +
29885 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
29886 + }
29887 +}
29888 +
29889 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
29890 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
29891 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
29892 +{
29893 + t_CcNodeInformation *p_CcNodeInformation;
29894 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
29895 + t_List *p_Pos;
29896 + int i = 0;
29897 + t_Handle p_AdTableTmp;
29898 + t_CcNodeInformation ccNodeInfo;
29899 +
29900 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
29901 + {
29902 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
29903 + p_TreePtrOnCurrentMdfNode =
29904 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
29905 +
29906 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
29907 +
29908 + /*search in the trees which exact index points on this current modified node for getting AD */
29909 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
29910 + {
29911 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
29912 + == e_FM_PCD_CC)
29913 + {
29914 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
29915 + == (t_Handle)p_CrntMdfNode)
29916 + {
29917 + p_AdTableTmp =
29918 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
29919 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
29920 + ccNodeInfo.h_CcNode = p_AdTableTmp;
29921 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
29922 +
29923 + if (!(*p_NextEngineParams))
29924 + *p_NextEngineParams =
29925 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
29926 + }
29927 + }
29928 + }
29929 +
29930 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
29931 + }
29932 +}
29933 +
29934 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
29935 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
29936 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
29937 +{
29938 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
29939 + int i = 0, j = 0;
29940 + bool wasUpdate = FALSE;
29941 + t_FmPcdCcNode *p_CcNode = NULL;
29942 + t_FmPcdCcTree *p_FmPcdCcTree;
29943 + uint16_t numOfKeys;
29944 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
29945 +
29946 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
29947 +
29948 + if (!tree)
29949 + {
29950 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
29951 + numOfKeys = p_CcNode->numOfKeys;
29952 +
29953 + /* node has to be pointed by another node or tree */
29954 +
29955 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29956 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
29957 + if (!p_KeyAndNextEngineParams)
29958 + {
29959 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29960 + return NULL;
29961 + }
29962 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
29963 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
29964 +
29965 + if (ttlCheck)
29966 + {
29967 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
29968 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
29969 + {
29970 + XX_Free(p_KeyAndNextEngineParams);
29971 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_FF_IPV4TTL or CC_PC_FF_IPV6HOP_LIMIT can not be used for this operation"));
29972 + return NULL;
29973 + }
29974 + }
29975 +
29976 + if (hashCheck)
29977 + {
29978 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
29979 + {
29980 + XX_Free(p_KeyAndNextEngineParams);
29981 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
29982 + return NULL;
29983 + }
29984 + }
29985 + }
29986 + else
29987 + {
29988 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
29989 + numOfKeys = p_FmPcdCcTree->numOfEntries;
29990 +
29991 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
29992 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
29993 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
29994 + if (!p_KeyAndNextEngineParams)
29995 + {
29996 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
29997 + return NULL;
29998 + }
29999 + memcpy(p_KeyAndNextEngineParams,
30000 + p_FmPcdCcTree->keyAndNextEngineParams,
30001 + FM_PCD_MAX_NUM_OF_CC_GROUPS
30002 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
30003 + }
30004 +
30005 + p_FmPcdModifyCcKeyAdditionalParams =
30006 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
30007 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
30008 + if (!p_FmPcdModifyCcKeyAdditionalParams)
30009 + {
30010 + XX_Free(p_KeyAndNextEngineParams);
30011 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
30012 + return NULL;
30013 + }
30014 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
30015 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
30016 +
30017 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
30018 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
30019 +
30020 + while (i < numOfKeys)
30021 + {
30022 + if ((j == keyIndex) && !wasUpdate)
30023 + {
30024 + if (modifyState == e_MODIFY_STATE_ADD)
30025 + j++;
30026 + else
30027 + if (modifyState == e_MODIFY_STATE_REMOVE)
30028 + i++;
30029 + wasUpdate = TRUE;
30030 + }
30031 + else
30032 + {
30033 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
30034 + p_KeyAndNextEngineParams + i,
30035 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
30036 + i++;
30037 + j++;
30038 + }
30039 + }
30040 +
30041 + if (keyIndex == numOfKeys)
30042 + {
30043 + if (modifyState == e_MODIFY_STATE_ADD)
30044 + j++;
30045 + }
30046 +
30047 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
30048 + p_KeyAndNextEngineParams + numOfKeys,
30049 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
30050 +
30051 + XX_Free(p_KeyAndNextEngineParams);
30052 +
30053 + return p_FmPcdModifyCcKeyAdditionalParams;
30054 +}
30055 +
30056 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
30057 + t_FmPcdCcNode *p_CcNode,
30058 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
30059 + t_List *h_OldLst, t_List *h_NewLst)
30060 +{
30061 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
30062 + t_CcNodeInformation ccNodeInfo = { 0 };
30063 + t_Handle h_NewAd;
30064 + t_Handle h_OrigAd = NULL;
30065 +
30066 + /* Building a list of all action descriptors that point to the previous node */
30067 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
30068 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
30069 + &p_NextEngineParams);
30070 +
30071 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
30072 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
30073 + &p_NextEngineParams);
30074 +
30075 + /* This node must be found as next engine of one of its previous nodes or trees*/
30076 + if (p_NextEngineParams)
30077 + {
30078 + /* Building a new action descriptor that points to the modified node */
30079 + h_NewAd = GetNewAd(p_CcNode, FALSE);
30080 + if (!h_NewAd)
30081 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
30082 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30083 +
30084 + h_OrigAd = p_CcNode->h_Ad;
30085 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
30086 + p_NextEngineParams);
30087 +
30088 + ccNodeInfo.h_CcNode = h_NewAd;
30089 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
30090 +
30091 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
30092 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
30093 + }
30094 + return E_OK;
30095 +}
30096 +
30097 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
30098 +{
30099 + ASSERT_COND(p_FmPcdCcTree);
30100 +
30101 + /* this routine must be protected by the calling routine! */
30102 +
30103 + if (add)
30104 + p_FmPcdCcTree->owners++;
30105 + else
30106 + {
30107 + ASSERT_COND(p_FmPcdCcTree->owners);
30108 + p_FmPcdCcTree->owners--;
30109 + }
30110 +}
30111 +
30112 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
30113 +{
30114 + t_Error err = E_OK;
30115 + int i = 0;
30116 +
30117 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30118 + {
30119 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
30120 + {
30121 + err =
30122 + FmPcdManipCheckParamsWithCcNodeParams(
30123 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
30124 + (t_Handle)p_CcNode);
30125 + if (err)
30126 + return err;
30127 + }
30128 + }
30129 +
30130 + return err;
30131 +}
30132 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
30133 + t_FmPcdCcNodeParams *p_CcNodeParam,
30134 + uint32_t *p_NumOfRanges,
30135 + uint32_t *p_CountersArraySize)
30136 +{
30137 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
30138 + uint32_t i;
30139 +
30140 + UNUSED(p_CcNodeParam);
30141 +
30142 + switch (statisticsMode)
30143 + {
30144 + case e_FM_PCD_CC_STATS_MODE_NONE:
30145 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30146 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
30147 + RETURN_ERROR(
30148 + MAJOR,
30149 + E_INVALID_VALUE,
30150 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
30151 + return E_OK;
30152 +
30153 + case e_FM_PCD_CC_STATS_MODE_FRAME:
30154 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
30155 + *p_NumOfRanges = 1;
30156 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
30157 + return E_OK;
30158 +
30159 +#if (DPAA_VERSION >= 11)
30160 + case e_FM_PCD_CC_STATS_MODE_RMON:
30161 + {
30162 + uint16_t *p_FrameLengthRanges =
30163 + p_CcNodeParam->keysParams.frameLengthRanges;
30164 + uint32_t i;
30165 +
30166 + if (p_FrameLengthRanges[0] <= 0)
30167 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30168 +
30169 + if (p_FrameLengthRanges[0] == 0xFFFF)
30170 + {
30171 + *p_NumOfRanges = 1;
30172 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
30173 + return E_OK;
30174 + }
30175 +
30176 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
30177 + {
30178 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
30179 + RETURN_ERROR(
30180 + MAJOR,
30181 + E_INVALID_VALUE,
30182 + ("Frame length range must be larger at least by 1 from preceding range"));
30183 +
30184 + /* Stop when last range is reached */
30185 + if (p_FrameLengthRanges[i] == 0xFFFF)
30186 + break;
30187 + }
30188 +
30189 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
30190 + || (p_FrameLengthRanges[i] != 0xFFFF))
30191 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30192 + ("Last Frame length range must be 0xFFFF"));
30193 +
30194 + *p_NumOfRanges = i + 1;
30195 +
30196 + /* Allocate an extra counter for byte count, as counters
30197 + array always begins with byte count */
30198 + *p_CountersArraySize = (*p_NumOfRanges + 1)
30199 + * FM_PCD_CC_STATS_COUNTER_SIZE;
30200 +
30201 + }
30202 + return E_OK;
30203 +#endif /* (DPAA_VERSION >= 11) */
30204 +
30205 + default:
30206 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
30207 + }
30208 +}
30209 +
30210 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30211 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30212 +{
30213 + int tmp = 0;
30214 + t_FmPcdCcKeyParams *p_KeyParams;
30215 + t_Error err;
30216 + uint32_t requiredAction = 0;
30217 +
30218 + /* Validate statistics parameters */
30219 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30220 + &(p_CcNode->numOfStatsFLRs),
30221 + &(p_CcNode->countersArraySize));
30222 + if (err)
30223 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30224 +
30225 + /* Validate next engine parameters on Miss */
30226 + err = ValidateNextEngineParams(
30227 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30228 + p_CcNode->statisticsMode);
30229 + if (err)
30230 + RETURN_ERROR(MAJOR, err,
30231 + ("For this node MissNextEngineParams are not valid"));
30232 +
30233 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30234 + {
30235 + err = FmPcdManipCheckParamsForCcNextEngine(
30236 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30237 + &requiredAction);
30238 + if (err)
30239 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30240 + }
30241 +
30242 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30243 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30244 + sizeof(t_FmPcdCcNextEngineParams));
30245 +
30246 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30247 + requiredAction;
30248 +
30249 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30250 + == e_FM_PCD_CC)
30251 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30252 + {
30253 + err =
30254 + AllocAndFillAdForContLookupManip(
30255 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30256 + if (err)
30257 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30258 + }
30259 +
30260 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30261 + {
30262 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30263 +
30264 + if (!p_KeyParams->p_Key)
30265 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
30266 +
30267 + err = ValidateNextEngineParams(h_FmPcd,
30268 + &p_KeyParams->ccNextEngineParams,
30269 + p_CcNode->statisticsMode);
30270 + if (err)
30271 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30272 +
30273 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
30274 + p_KeyParams->p_Mask);
30275 + if (err)
30276 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30277 +
30278 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30279 + {
30280 + err = FmPcdManipCheckParamsForCcNextEngine(
30281 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30282 + if (err)
30283 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30284 + }
30285 +
30286 + /* Store 'key' parameters - key, mask (if passed by the user) */
30287 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
30288 + p_CcNodeParam->keysParams.keySize);
30289 +
30290 + if (p_KeyParams->p_Mask)
30291 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
30292 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
30293 + else
30294 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
30295 + p_CcNodeParam->keysParams.keySize);
30296 +
30297 + /* Store next engine parameters */
30298 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30299 + &p_KeyParams->ccNextEngineParams,
30300 + sizeof(t_FmPcdCcNextEngineParams));
30301 +
30302 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30303 +
30304 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30305 + == e_FM_PCD_CC)
30306 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30307 + {
30308 + err =
30309 + AllocAndFillAdForContLookupManip(
30310 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30311 + if (err)
30312 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30313 + }
30314 + }
30315 +
30316 + if (p_CcNode->maxNumOfKeys)
30317 + {
30318 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
30319 + RETURN_ERROR(
30320 + MAJOR,
30321 + E_INVALID_VALUE,
30322 + ("Number of keys exceed the provided maximal number of keys"));
30323 + }
30324 +
30325 + *isKeyTblAlloc = TRUE;
30326 +
30327 + return E_OK;
30328 +}
30329 +
30330 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
30331 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
30332 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
30333 +{
30334 + int tmp = 0;
30335 + t_FmPcdCcKeyParams *p_KeyParams;
30336 + t_Error err;
30337 + uint8_t key = 0x01;
30338 + uint32_t requiredAction = 0;
30339 +
30340 + if (p_CcNode->numOfKeys != 1)
30341 + RETURN_ERROR(
30342 + MAJOR,
30343 + E_INVALID_VALUE,
30344 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
30345 +
30346 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
30347 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
30348 + RETURN_ERROR(
30349 + MAJOR,
30350 + E_INVALID_VALUE,
30351 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
30352 +
30353 + /* Validate statistics parameters */
30354 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30355 + &(p_CcNode->numOfStatsFLRs),
30356 + &(p_CcNode->countersArraySize));
30357 + if (err)
30358 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30359 +
30360 + err = ValidateNextEngineParams(
30361 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30362 + p_CcNodeParam->keysParams.statisticsMode);
30363 + if (err)
30364 + RETURN_ERROR(MAJOR, err,
30365 + ("For this node MissNextEngineParams are not valid"));
30366 +
30367 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
30368 + {
30369 + err = FmPcdManipCheckParamsForCcNextEngine(
30370 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30371 + &requiredAction);
30372 + if (err)
30373 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30374 + }
30375 +
30376 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
30377 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30378 + sizeof(t_FmPcdCcNextEngineParams));
30379 +
30380 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
30381 + requiredAction;
30382 +
30383 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
30384 + == e_FM_PCD_CC)
30385 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
30386 + {
30387 + err =
30388 + AllocAndFillAdForContLookupManip(
30389 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
30390 + if (err)
30391 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30392 + }
30393 +
30394 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30395 + {
30396 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30397 +
30398 + if (p_KeyParams->p_Mask)
30399 + RETURN_ERROR(
30400 + MAJOR,
30401 + E_INVALID_VALUE,
30402 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
30403 +
30404 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
30405 + RETURN_ERROR(
30406 + MAJOR,
30407 + E_INVALID_VALUE,
30408 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
30409 +
30410 + err = ValidateNextEngineParams(h_FmPcd,
30411 + &p_KeyParams->ccNextEngineParams,
30412 + p_CcNode->statisticsMode);
30413 + if (err)
30414 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30415 +
30416 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30417 + {
30418 + err = FmPcdManipCheckParamsForCcNextEngine(
30419 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30420 + if (err)
30421 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30422 + }
30423 +
30424 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
30425 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
30426 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
30427 +
30428 + /* Store NextEngine parameters */
30429 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30430 + &p_KeyParams->ccNextEngineParams,
30431 + sizeof(t_FmPcdCcNextEngineParams));
30432 +
30433 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30434 + == e_FM_PCD_CC)
30435 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30436 + {
30437 + err =
30438 + AllocAndFillAdForContLookupManip(
30439 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30440 + if (err)
30441 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30442 + }
30443 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
30444 + }
30445 +
30446 + *isKeyTblAlloc = FALSE;
30447 +
30448 + return E_OK;
30449 +}
30450 +
30451 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
30452 + t_FmPcdCcNodeParams *p_CcNodeParam,
30453 + t_FmPcdCcNode *p_CcNode,
30454 + bool *isKeyTblAlloc)
30455 +{
30456 + int tmp = 0, countOnes = 0;
30457 + t_FmPcdCcKeyParams *p_KeyParams;
30458 + t_Error err;
30459 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
30460 + uint16_t countMask = (uint16_t)(glblMask >> 4);
30461 + uint32_t requiredAction = 0;
30462 +
30463 + if (glblMask & 0x000f)
30464 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
30465 + ("icIndxMask has to be with last nibble 0"));
30466 +
30467 + while (countMask)
30468 + {
30469 + countOnes++;
30470 + countMask = (uint16_t)(countMask >> 1);
30471 + }
30472 +
30473 + if (!POWER_OF_2(p_CcNode->numOfKeys))
30474 + RETURN_ERROR(
30475 + MAJOR,
30476 + E_INVALID_VALUE,
30477 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
30478 +
30479 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
30480 + RETURN_ERROR(
30481 + MAJOR,
30482 + E_INVALID_VALUE,
30483 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
30484 +
30485 + if (p_CcNodeParam->keysParams.maxNumOfKeys
30486 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
30487 + RETURN_ERROR(
30488 + MAJOR,
30489 + E_INVALID_VALUE,
30490 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
30491 +
30492 + /* Validate statistics parameters */
30493 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
30494 + &(p_CcNode->numOfStatsFLRs),
30495 + &(p_CcNode->countersArraySize));
30496 + if (err)
30497 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
30498 +
30499 + err = ValidateNextEngineParams(
30500 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
30501 + p_CcNode->statisticsMode);
30502 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30503 + RETURN_ERROR(
30504 + MAJOR,
30505 + err,
30506 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
30507 +
30508 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
30509 + {
30510 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
30511 +
30512 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
30513 + RETURN_ERROR(
30514 + MAJOR,
30515 + E_INVALID_VALUE,
30516 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
30517 +
30518 + if ((glblMask & (tmp * 16)) == (tmp * 16))
30519 + {
30520 + err = ValidateNextEngineParams(h_FmPcd,
30521 + &p_KeyParams->ccNextEngineParams,
30522 + p_CcNode->statisticsMode);
30523 + if (err)
30524 + RETURN_ERROR(
30525 + MAJOR,
30526 + err,
30527 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
30528 +
30529 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30530 + {
30531 + err = FmPcdManipCheckParamsForCcNextEngine(
30532 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30533 + if (err)
30534 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30535 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
30536 + requiredAction;
30537 + }
30538 +
30539 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
30540 + &p_KeyParams->ccNextEngineParams,
30541 + sizeof(t_FmPcdCcNextEngineParams));
30542 +
30543 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
30544 + == e_FM_PCD_CC)
30545 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
30546 + {
30547 + err =
30548 + AllocAndFillAdForContLookupManip(
30549 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
30550 + if (err)
30551 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30552 + }
30553 + }
30554 + else
30555 + {
30556 + err = ValidateNextEngineParams(h_FmPcd,
30557 + &p_KeyParams->ccNextEngineParams,
30558 + p_CcNode->statisticsMode);
30559 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
30560 + RETURN_ERROR(
30561 + MAJOR,
30562 + err,
30563 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
30564 + }
30565 + }
30566 +
30567 + *isKeyTblAlloc = FALSE;
30568 + cpu_to_be16s(&glblMask);
30569 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
30570 +
30571 + return E_OK;
30572 +}
30573 +
30574 +static t_Error ModifyNextEngineParamNode(
30575 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
30576 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
30577 +{
30578 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
30579 + t_FmPcd *p_FmPcd;
30580 + t_List h_OldPointersLst, h_NewPointersLst;
30581 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
30582 + t_Error err = E_OK;
30583 +
30584 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
30585 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
30586 +
30587 + if (keyIndex >= p_CcNode->numOfKeys)
30588 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30589 + ("keyIndex > previously cleared last index + 1"));
30590 +
30591 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30592 +
30593 + INIT_LIST(&h_OldPointersLst);
30594 + INIT_LIST(&h_NewPointersLst);
30595 +
30596 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
30597 + e_MODIFY_STATE_CHANGE, FALSE,
30598 + FALSE, FALSE);
30599 + if (!p_ModifyKeyParams)
30600 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
30601 +
30602 + if (p_CcNode->maxNumOfKeys
30603 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
30604 + {
30605 + XX_Free(p_ModifyKeyParams);
30606 + return ERROR_CODE(E_BUSY);
30607 + }
30608 +
30609 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
30610 + p_FmPcdCcNextEngineParams,
30611 + &h_OldPointersLst, &h_NewPointersLst,
30612 + p_ModifyKeyParams);
30613 + if (err)
30614 + {
30615 + XX_Free(p_ModifyKeyParams);
30616 + if (p_CcNode->maxNumOfKeys)
30617 + RELEASE_LOCK(p_FmPcd->shadowLock);
30618 + RETURN_ERROR(MAJOR, err, NO_MSG);
30619 + }
30620 +
30621 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
30622 + p_ModifyKeyParams, FALSE);
30623 +
30624 + if (p_CcNode->maxNumOfKeys)
30625 + RELEASE_LOCK(p_FmPcd->shadowLock);
30626 +
30627 + ReleaseLst(&h_OldPointersLst);
30628 + ReleaseLst(&h_NewPointersLst);
30629 +
30630 + return err;
30631 +}
30632 +
30633 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
30634 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
30635 +{
30636 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
30637 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
30638 + uint16_t i;
30639 +
30640 + ASSERT_COND(p_Key);
30641 + ASSERT_COND(p_KeyIndex);
30642 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
30643 +
30644 + if (keySize != p_CcNode->userSizeOfExtraction)
30645 + RETURN_ERROR(
30646 + MINOR, E_INVALID_VALUE,
30647 + ("Key size doesn't match the extraction size of the node"));
30648 +
30649 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
30650 + if (!p_Mask)
30651 + memset(tmpMask, 0xFF, keySize);
30652 +
30653 + for (i = 0; i < p_CcNode->numOfKeys; i++)
30654 + {
30655 + /* Comparing received key */
30656 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
30657 + == 0)
30658 + {
30659 + if (p_Mask)
30660 + {
30661 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
30662 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
30663 + keySize) == 0)
30664 + {
30665 + *p_KeyIndex = i;
30666 + return E_OK;
30667 + }
30668 + }
30669 + else
30670 + {
30671 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
30672 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
30673 + keySize) == 0)
30674 + {
30675 + *p_KeyIndex = i;
30676 + return E_OK;
30677 + }
30678 + }
30679 + }
30680 + }
30681 +
30682 + return ERROR_CODE(E_NOT_FOUND);
30683 +}
30684 +
30685 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
30686 + bool isKeyTblAlloc,
30687 + uint32_t *p_MatchTableSize,
30688 + uint32_t *p_AdTableSize)
30689 +{
30690 + uint32_t shadowSize;
30691 + t_Error err;
30692 +
30693 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
30694 + (if local mask support is requested) */
30695 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
30696 + * p_CcNode->maxNumOfKeys;
30697 +
30698 + if (p_CcNode->maskSupport)
30699 + *p_MatchTableSize *= 2;
30700 +
30701 + /* Calculate next action descriptors table, including one more entry for miss */
30702 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30703 + * FM_PCD_CC_AD_ENTRY_SIZE);
30704 +
30705 + /* Calculate maximal shadow size of this node.
30706 + All shadow structures will be used for runtime modifications host command. If
30707 + keys table was allocated for this node, the keys table and next engines table may
30708 + be modified in run time (entries added or removed), so shadow tables are requires.
30709 + Otherwise, the only supported runtime modification is a specific next engine update
30710 + and this requires shadow memory of a single AD */
30711 +
30712 + /* Shadow size should be enough to hold the following 3 structures:
30713 + * 1 - an action descriptor */
30714 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
30715 +
30716 + /* 2 - keys match table, if was allocated for the current node */
30717 + if (isKeyTblAlloc)
30718 + shadowSize += *p_MatchTableSize;
30719 +
30720 + /* 3 - next action descriptors table */
30721 + shadowSize += *p_AdTableSize;
30722 +
30723 + /* Update shadow to the calculated size */
30724 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
30725 + FM_PCD_CC_AD_TABLE_ALIGN);
30726 + if (err != E_OK)
30727 + {
30728 + DeleteNode(p_CcNode);
30729 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
30730 + }
30731 +
30732 + return E_OK;
30733 +}
30734 +
30735 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
30736 +{
30737 + t_FmPcdStatsObj *p_StatsObj;
30738 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
30739 + uint32_t i;
30740 +
30741 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
30742 + if (!h_FmMuram)
30743 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30744 +
30745 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
30746 + will be allocated to support runtime modifications */
30747 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
30748 + {
30749 + /* Allocate list object structure */
30750 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
30751 + if (!p_StatsObj)
30752 + {
30753 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30754 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
30755 + }
30756 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
30757 +
30758 + /* Allocate statistics AD from MURAM */
30759 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
30760 + FM_PCD_CC_AD_ENTRY_SIZE,
30761 + FM_PCD_CC_AD_TABLE_ALIGN);
30762 + if (!h_StatsAd)
30763 + {
30764 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30765 + XX_Free(p_StatsObj);
30766 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30767 + ("MURAM allocation for statistics ADs"));
30768 + }
30769 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
30770 +
30771 + /* Allocate statistics counters from MURAM */
30772 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
30773 + h_FmMuram, p_CcNode->countersArraySize,
30774 + FM_PCD_CC_AD_TABLE_ALIGN);
30775 + if (!h_StatsCounters)
30776 + {
30777 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
30778 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
30779 + XX_Free(p_StatsObj);
30780 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30781 + ("MURAM allocation for statistics counters"));
30782 + }
30783 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
30784 +
30785 + p_StatsObj->h_StatsAd = h_StatsAd;
30786 + p_StatsObj->h_StatsCounters = h_StatsCounters;
30787 +
30788 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
30789 + }
30790 +
30791 + return E_OK;
30792 +}
30793 +
30794 +static t_Error MatchTableGetKeyStatistics(
30795 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30796 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
30797 +{
30798 + uint32_t *p_StatsCounters, i;
30799 +
30800 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
30801 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30802 + ("Statistics were not enabled for this match table"));
30803 +
30804 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
30805 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
30806 + ("Statistics were not enabled for this key"));
30807 +
30808 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
30809 +
30810 + p_StatsCounters =
30811 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
30812 + ASSERT_COND(p_StatsCounters);
30813 +
30814 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
30815 +
30816 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
30817 + {
30818 + p_StatsCounters =
30819 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
30820 +
30821 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
30822 +
30823 +#if (DPAA_VERSION >= 11)
30824 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
30825 + GET_UINT32(*p_StatsCounters);
30826 +#endif /* (DPAA_VERSION >= 11) */
30827 + }
30828 +
30829 + return E_OK;
30830 +}
30831 +
30832 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
30833 + t_FmPcdCcNodeParams *p_CcNodeParam)
30834 +{
30835 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
30836 + t_FmPcdCcNode *p_FmPcdCcNextNode;
30837 + t_Error err = E_OK;
30838 + uint32_t tmp, keySize;
30839 + bool glblMask = FALSE;
30840 + t_FmPcdCcKeyParams *p_KeyParams;
30841 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
30842 +#if (DPAA_VERSION >= 11)
30843 + t_Handle h_StatsFLRs;
30844 +#endif /* (DPAA_VERSION >= 11) */
30845 + bool fullField = FALSE;
30846 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
30847 + bool isKeyTblAlloc, fromIc = FALSE;
30848 + uint32_t matchTableSize, adTableSize;
30849 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
30850 + t_FmPcdStatsObj *p_StatsObj;
30851 + t_FmPcdCcStatsParams statsParams = { 0 };
30852 + t_Handle h_Manip;
30853 +
30854 + ASSERT_COND(h_FmPcd);
30855 + ASSERT_COND(p_CcNode);
30856 + ASSERT_COND(p_CcNodeParam);
30857 +
30858 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
30859 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30860 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30861 +
30862 + p_CcNode->h_FmPcd = h_FmPcd;
30863 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
30864 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
30865 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
30866 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
30867 +
30868 + /* For backward compatibility - even if statistics mode is nullified,
30869 + we'll fix it to frame mode so we can support per-key request for
30870 + statistics using 'statisticsEn' in next engine parameters */
30871 + if (!p_CcNode->maxNumOfKeys
30872 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
30873 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
30874 +
30875 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
30876 + if (!h_FmMuram)
30877 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
30878 +
30879 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
30880 + INIT_LIST(&p_CcNode->ccTreeIdLst);
30881 + INIT_LIST(&p_CcNode->ccTreesLst);
30882 + INIT_LIST(&p_CcNode->availableStatsLst);
30883 +
30884 + p_CcNode->h_Spinlock = XX_InitSpinlock();
30885 + if (!p_CcNode->h_Spinlock)
30886 + {
30887 + DeleteNode(p_CcNode);
30888 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
30889 + }
30890 +
30891 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
30892 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
30893 + == HEADER_TYPE_IPv4)
30894 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
30895 + == HEADER_TYPE_IPv6))
30896 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
30897 + == e_FM_PCD_EXTRACT_FULL_FIELD)
30898 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
30899 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
30900 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
30901 + == NET_HEADER_FIELD_IPv4_TTL)))
30902 + {
30903 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30904 + &isKeyTblAlloc);
30905 + glblMask = FALSE;
30906 + }
30907 + else
30908 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
30909 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30910 + == e_FM_PCD_EXTRACT_FROM_KEY)
30911 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30912 + == e_FM_PCD_EXTRACT_FROM_HASH)
30913 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
30914 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
30915 + {
30916 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
30917 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
30918 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
30919 + {
30920 + DeleteNode(p_CcNode);
30921 + RETURN_ERROR(
30922 + MAJOR,
30923 + E_INVALID_VALUE,
30924 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
30925 + }
30926 +
30927 + icCode = IcDefineCode(p_CcNodeParam);
30928 + fromIc = TRUE;
30929 + if (icCode == CC_PRIVATE_INFO_NONE)
30930 + {
30931 + DeleteNode(p_CcNode);
30932 + RETURN_ERROR(
30933 + MAJOR,
30934 + E_INVALID_STATE,
30935 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
30936 + }
30937 +
30938 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
30939 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
30940 + {
30941 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30942 + &isKeyTblAlloc);
30943 + glblMask = TRUE;
30944 + }
30945 + else
30946 + {
30947 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
30948 + &isKeyTblAlloc);
30949 + if (p_CcNode->glblMaskSize)
30950 + glblMask = TRUE;
30951 + }
30952 + }
30953 + else
30954 + {
30955 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
30956 + if (p_CcNode->glblMaskSize)
30957 + glblMask = TRUE;
30958 + }
30959 +
30960 + if (err)
30961 + {
30962 + DeleteNode(p_CcNode);
30963 + RETURN_ERROR(MAJOR, err, NO_MSG);
30964 + }
30965 +
30966 + switch (p_CcNodeParam->extractCcParams.type)
30967 + {
30968 + case (e_FM_PCD_EXTRACT_BY_HDR):
30969 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
30970 + {
30971 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
30972 + p_CcNode->parseCode =
30973 + GetFullFieldParseCode(
30974 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30975 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
30976 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
30977 + GetSizeHeaderField(
30978 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
30979 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
30980 + &p_CcNode->sizeOfExtraction);
30981 + fullField = TRUE;
30982 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
30983 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30984 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30985 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30986 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30987 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30988 + && (p_CcNode->parseCode
30989 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30990 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30991 + && (p_CcNode->parseCode
30992 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
30993 + && glblMask)
30994 + {
30995 + glblMask = FALSE;
30996 + p_CcNode->glblMaskSize = 4;
30997 + p_CcNode->lclMask = TRUE;
30998 + }
30999 + break;
31000 +
31001 + case (e_FM_PCD_EXTRACT_FROM_HDR):
31002 + p_CcNode->sizeOfExtraction =
31003 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
31004 + p_CcNode->offset =
31005 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
31006 + p_CcNode->userOffset =
31007 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
31008 + p_CcNode->parseCode =
31009 + GetPrParseCode(
31010 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
31011 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
31012 + p_CcNode->offset, glblMask,
31013 + &p_CcNode->prsArrayOffset);
31014 + break;
31015 +
31016 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
31017 + p_CcNode->offset =
31018 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
31019 + p_CcNode->userOffset =
31020 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
31021 + p_CcNode->sizeOfExtraction =
31022 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
31023 + p_CcNode->parseCode =
31024 + GetFieldParseCode(
31025 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
31026 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
31027 + p_CcNode->offset,
31028 + &p_CcNode->prsArrayOffset,
31029 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
31030 + break;
31031 +
31032 + default:
31033 + DeleteNode(p_CcNode);
31034 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
31035 + }
31036 + break;
31037 +
31038 + case (e_FM_PCD_EXTRACT_NON_HDR):
31039 + /* get the field code for the generic extract */
31040 + p_CcNode->sizeOfExtraction =
31041 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
31042 + p_CcNode->offset =
31043 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
31044 + p_CcNode->userOffset =
31045 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
31046 + p_CcNode->parseCode = GetGenParseCode(
31047 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
31048 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
31049 + fromIc, icCode);
31050 +
31051 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
31052 + {
31053 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
31054 + {
31055 + DeleteNode(p_CcNode);
31056 + RETURN_ERROR(
31057 + MAJOR,
31058 + E_INVALID_SELECTION,
31059 + ("when node of the type CC_PC_GENERIC_IC_HASH_INDEXED offset + size can not be bigger then size of HASH 64 bits (8 bytes)"));
31060 + }
31061 + }
31062 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
31063 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
31064 + {
31065 + p_CcNode->offset += p_CcNode->prsArrayOffset;
31066 + p_CcNode->prsArrayOffset = 0;
31067 + }
31068 + break;
31069 +
31070 + default:
31071 + DeleteNode(p_CcNode);
31072 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
31073 + }
31074 +
31075 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
31076 + {
31077 + DeleteNode(p_CcNode);
31078 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
31079 + }
31080 +
31081 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
31082 + || !p_CcNode->sizeOfExtraction)
31083 + {
31084 + DeleteNode(p_CcNode);
31085 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31086 + ("sizeOfExatrction can not be greater than 56 and not 0"));
31087 + }
31088 +
31089 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
31090 + {
31091 + DeleteNode(p_CcNode);
31092 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31093 + ("keySize has to be equal to sizeOfExtraction"));
31094 + }
31095 +
31096 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
31097 +
31098 + if (!glblMask)
31099 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
31100 +
31101 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
31102 + if (err != E_OK)
31103 + {
31104 + DeleteNode(p_CcNode);
31105 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31106 + ("keySize has to be equal to sizeOfExtraction"));
31107 + }
31108 +
31109 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
31110 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
31111 + &p_CcNode->ccKeySizeAccExtraction);
31112 +
31113 + /* If local mask is used, it is stored next to each key in the keys match table */
31114 + if (p_CcNode->lclMask)
31115 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
31116 + else
31117 + keySize = p_CcNode->ccKeySizeAccExtraction;
31118 +
31119 + /* Update CC shadow with maximal size required by this node */
31120 + if (p_CcNode->maxNumOfKeys)
31121 + {
31122 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
31123 + &adTableSize);
31124 + if (err != E_OK)
31125 + {
31126 + DeleteNode(p_CcNode);
31127 + RETURN_ERROR(MAJOR, err, NO_MSG);
31128 + }
31129 +
31130 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
31131 +
31132 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
31133 + {
31134 + err = AllocStatsObjs(p_CcNode);
31135 + if (err != E_OK)
31136 + {
31137 + DeleteNode(p_CcNode);
31138 + RETURN_ERROR(MAJOR, err, NO_MSG);
31139 + }
31140 + }
31141 +
31142 + /* If manipulation will be initialized before this node, it will use the table
31143 + descriptor in the AD table of previous node and this node will need an extra
31144 + AD as his table descriptor. */
31145 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
31146 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
31147 + if (!p_CcNode->h_TmpAd)
31148 + {
31149 + DeleteNode(p_CcNode);
31150 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31151 + ("MURAM allocation for CC action descriptor"));
31152 + }
31153 + }
31154 + else
31155 + {
31156 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
31157 + * (p_CcNode->numOfKeys + 1));
31158 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
31159 + * (p_CcNode->numOfKeys + 1));
31160 + }
31161 +
31162 +#if (DPAA_VERSION >= 11)
31163 + switch (p_CcNode->statisticsMode)
31164 + {
31165 +
31166 + case e_FM_PCD_CC_STATS_MODE_RMON:
31167 + /* If RMON statistics or RMON conditional statistics modes are requested,
31168 + allocate frame length ranges array */
31169 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
31170 + h_FmMuram,
31171 + (uint32_t)(p_CcNode->numOfStatsFLRs)
31172 + * FM_PCD_CC_STATS_FLR_SIZE,
31173 + FM_PCD_CC_AD_TABLE_ALIGN);
31174 +
31175 + if (!p_CcNode->h_StatsFLRs)
31176 + {
31177 + DeleteNode(p_CcNode);
31178 + RETURN_ERROR(
31179 + MAJOR, E_NO_MEMORY,
31180 + ("MURAM allocation for CC frame length ranges array"));
31181 + }
31182 +
31183 + /* Initialize using value received from the user */
31184 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
31185 + {
31186 + uint16_t flr =
31187 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
31188 +
31189 + h_StatsFLRs =
31190 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
31191 +
31192 + MemCpy8(h_StatsFLRs,
31193 + &flr,
31194 + FM_PCD_CC_STATS_FLR_SIZE);
31195 + }
31196 + break;
31197 +
31198 + default:
31199 + break;
31200 + }
31201 +#endif /* (DPAA_VERSION >= 11) */
31202 +
31203 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
31204 + identification, IPv6 hop count identification, etc. */
31205 + if (isKeyTblAlloc)
31206 + {
31207 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
31208 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
31209 + if (!p_CcNode->h_KeysMatchTable)
31210 + {
31211 + DeleteNode(p_CcNode);
31212 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31213 + ("MURAM allocation for CC node key match table"));
31214 + }
31215 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
31216 + }
31217 +
31218 + /* Allocate action descriptors table */
31219 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
31220 + FM_PCD_CC_AD_TABLE_ALIGN);
31221 + if (!p_CcNode->h_AdTable)
31222 + {
31223 + DeleteNode(p_CcNode);
31224 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31225 + ("MURAM allocation for CC node action descriptors table"));
31226 + }
31227 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
31228 +
31229 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
31230 + p_AdTableTmp = p_CcNode->h_AdTable;
31231 +
31232 + /* For each key, create the key and the next step AD */
31233 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31234 + {
31235 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31236 +
31237 + if (p_KeysMatchTblTmp)
31238 + {
31239 + /* Copy the key */
31240 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
31241 + p_CcNode->sizeOfExtraction);
31242 +
31243 + /* Copy the key mask or initialize it to 0xFF..F */
31244 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
31245 + {
31246 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
31247 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31248 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31249 + }
31250 + else
31251 + if (p_CcNode->lclMask)
31252 + {
31253 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
31254 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
31255 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
31256 + }
31257 +
31258 + p_KeysMatchTblTmp =
31259 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
31260 + }
31261 +
31262 + /* Create the next action descriptor in the match table */
31263 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
31264 + {
31265 + p_StatsObj = GetStatsObj(p_CcNode);
31266 + ASSERT_COND(p_StatsObj);
31267 +
31268 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31269 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31270 +#if (DPAA_VERSION >= 11)
31271 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31272 +
31273 +#endif /* (DPAA_VERSION >= 11) */
31274 + NextStepAd(p_AdTableTmp, &statsParams,
31275 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
31276 +
31277 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31278 + }
31279 + else
31280 + {
31281 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
31282 + p_FmPcd);
31283 +
31284 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31285 + }
31286 +
31287 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31288 + }
31289 +
31290 + /* Update next engine for the 'miss' entry */
31291 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
31292 + {
31293 + p_StatsObj = GetStatsObj(p_CcNode);
31294 + ASSERT_COND(p_StatsObj);
31295 +
31296 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
31297 + allocated by the hash table. So, if this node is a bucket of a hash table,
31298 + we'll replace the locally allocated counters with the shared counters. */
31299 + if (p_CcNode->isHashBucket)
31300 + {
31301 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
31302 +
31303 + /* Store original counters pointer and replace it with mutual preallocated pointer */
31304 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
31305 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
31306 + }
31307 +
31308 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31309 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31310 +#if (DPAA_VERSION >= 11)
31311 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
31312 +
31313 +#endif /* (DPAA_VERSION >= 11) */
31314 +
31315 + NextStepAd(p_AdTableTmp, &statsParams,
31316 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31317 + p_FmPcd);
31318 +
31319 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
31320 + }
31321 + else
31322 + {
31323 + NextStepAd(p_AdTableTmp, NULL,
31324 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31325 + p_FmPcd);
31326 +
31327 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
31328 + }
31329 +
31330 + /* This parameter will be used to initialize the "key length" field in the action descriptor
31331 + that points to this node and it should be 0 for full field extraction */
31332 + if (fullField == TRUE)
31333 + p_CcNode->sizeOfExtraction = 0;
31334 +
31335 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31336 + {
31337 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31338 + == e_FM_PCD_CC)
31339 + {
31340 + p_FmPcdCcNextNode =
31341 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
31342 + p_CcInformation = FindNodeInfoInReleventLst(
31343 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
31344 + p_FmPcdCcNextNode->h_Spinlock);
31345 + if (!p_CcInformation)
31346 + {
31347 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31348 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31349 + ccNodeInfo.index = 1;
31350 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
31351 + &ccNodeInfo,
31352 + p_FmPcdCcNextNode->h_Spinlock);
31353 + }
31354 + else
31355 + p_CcInformation->index++;
31356 +
31357 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31358 + {
31359 + h_Manip =
31360 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
31361 + p_CcInformation = FindNodeInfoInReleventLst(
31362 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31363 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
31364 + if (!p_CcInformation)
31365 + {
31366 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31367 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
31368 + ccNodeInfo.index = 1;
31369 + EnqueueNodeInfoToRelevantLst(
31370 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
31371 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
31372 + }
31373 + else
31374 + p_CcInformation->index++;
31375 + }
31376 + }
31377 + }
31378 +
31379 + p_AdTableTmp = p_CcNode->h_AdTable;
31380 +
31381 + if (!FmPcdLockTryLockAll(h_FmPcd))
31382 + {
31383 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31384 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
31385 + return ERROR_CODE(E_BUSY);
31386 + }
31387 +
31388 + /* Required action for each next engine */
31389 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
31390 + {
31391 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
31392 + {
31393 + err = SetRequiredAction(
31394 + h_FmPcd,
31395 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
31396 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
31397 + NULL);
31398 + if (err)
31399 + {
31400 + FmPcdLockUnlockAll(h_FmPcd);
31401 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
31402 + RETURN_ERROR(MAJOR, err, NO_MSG);
31403 + }
31404 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31405 + }
31406 + }
31407 +
31408 + FmPcdLockUnlockAll(h_FmPcd);
31409 +
31410 + return E_OK;
31411 +}
31412 +/************************** End of static functions **************************/
31413 +
31414 +/*****************************************************************************/
31415 +/* Inter-module API routines */
31416 +/*****************************************************************************/
31417 +
31418 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
31419 + t_Handle h_Spinlock)
31420 +{
31421 + t_CcNodeInformation *p_CcInformation;
31422 + t_List *p_Pos;
31423 + uint32_t intFlags;
31424 +
31425 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31426 +
31427 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31428 + p_Pos = LIST_NEXT(p_Pos))
31429 + {
31430 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31431 +
31432 + ASSERT_COND(p_CcInformation->h_CcNode);
31433 +
31434 + if (p_CcInformation->h_CcNode == h_Info)
31435 + {
31436 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31437 + return p_CcInformation;
31438 + }
31439 + }
31440 +
31441 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31442 +
31443 + return NULL;
31444 +}
31445 +
31446 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
31447 + t_Handle h_Spinlock)
31448 +{
31449 + t_CcNodeInformation *p_CcInformation;
31450 + uint32_t intFlags = 0;
31451 +
31452 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
31453 + sizeof(t_CcNodeInformation));
31454 +
31455 + if (p_CcInformation)
31456 + {
31457 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
31458 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
31459 + INIT_LIST(&p_CcInformation->node);
31460 +
31461 + if (h_Spinlock)
31462 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31463 +
31464 + LIST_AddToTail(&p_CcInformation->node, p_List);
31465 +
31466 + if (h_Spinlock)
31467 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31468 + }
31469 + else
31470 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
31471 +}
31472 +
31473 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
31474 + t_Handle h_Spinlock)
31475 +{
31476 + t_CcNodeInformation *p_CcInformation = NULL;
31477 + uint32_t intFlags = 0;
31478 + t_List *p_Pos;
31479 +
31480 + if (h_Spinlock)
31481 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
31482 +
31483 + if (LIST_IsEmpty(p_List))
31484 + {
31485 + XX_RestoreAllIntr(intFlags);
31486 + return;
31487 + }
31488 +
31489 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
31490 + p_Pos = LIST_NEXT(p_Pos))
31491 + {
31492 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
31493 + ASSERT_COND(p_CcInformation);
31494 + ASSERT_COND(p_CcInformation->h_CcNode);
31495 + if (p_CcInformation->h_CcNode == h_Info)
31496 + break;
31497 + }
31498 +
31499 + if (p_CcInformation)
31500 + {
31501 + LIST_DelAndInit(&p_CcInformation->node);
31502 + XX_Free(p_CcInformation);
31503 + }
31504 +
31505 + if (h_Spinlock)
31506 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
31507 +}
31508 +
31509 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
31510 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
31511 + t_FmPcd *p_FmPcd)
31512 +{
31513 + switch (p_FmPcdCcNextEngineParams->nextEngine)
31514 + {
31515 + case (e_FM_PCD_KG):
31516 + case (e_FM_PCD_PLCR):
31517 + case (e_FM_PCD_DONE):
31518 + /* if NIA is not CC, create a "result" type AD */
31519 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31520 + p_FmPcdCcNextEngineParams);
31521 + break;
31522 +#if (DPAA_VERSION >= 11)
31523 + case (e_FM_PCD_FR):
31524 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
31525 + {
31526 + FillAdOfTypeContLookup(
31527 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31528 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31529 + p_FmPcdCcNextEngineParams->h_Manip,
31530 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
31531 + FrmReplicGroupUpdateOwner(
31532 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
31533 + TRUE/* add */);
31534 + }
31535 + break;
31536 +#endif /* (DPAA_VERSION >= 11) */
31537 +
31538 + case (e_FM_PCD_CC):
31539 + /* if NIA is not CC, create a TD to continue the CC lookup */
31540 + FillAdOfTypeContLookup(
31541 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
31542 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31543 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
31544 +
31545 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
31546 + TRUE);
31547 + break;
31548 +
31549 + default:
31550 + return;
31551 + }
31552 +}
31553 +
31554 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31555 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
31556 + bool createSchemes)
31557 +{
31558 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31559 + t_FmPcdCcNextEngineParams nextEngineParams;
31560 + t_NetEnvParams netEnvParams;
31561 + t_Handle h_Ad;
31562 + bool isIpv6Present;
31563 + uint8_t ipv4GroupId, ipv6GroupId;
31564 + t_Error err;
31565 +
31566 + ASSERT_COND(p_FmPcdCcTree);
31567 +
31568 + /* this routine must be protected by the calling routine! */
31569 +
31570 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31571 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31572 +
31573 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31574 +
31575 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
31576 +
31577 + if (isIpv6Present
31578 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
31579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31580 +
31581 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31582 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
31583 +
31584 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31585 + nextEngineParams.h_Manip = h_IpReassemblyManip;
31586 +
31587 + /* Lock tree */
31588 + err = CcRootTryLock(p_FmPcdCcTree);
31589 + if (err)
31590 + return ERROR_CODE(E_BUSY);
31591 +
31592 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
31593 + {
31594 + CcRootReleaseLock(p_FmPcdCcTree);
31595 + return E_OK;
31596 + }
31597 +
31598 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
31599 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
31600 + {
31601 + CcRootReleaseLock(p_FmPcdCcTree);
31602 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31603 + ("This tree was previously updated with different IPR"));
31604 + }
31605 +
31606 + /* Initialize IPR for the first time for this tree */
31607 + if (isIpv6Present)
31608 + {
31609 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
31610 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
31611 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
31612 +
31613 + if (createSchemes)
31614 + {
31615 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
31616 + p_FmPcdCcTree,
31617 + h_IpReassemblyManip, FALSE,
31618 + ipv6GroupId);
31619 + if (err)
31620 + {
31621 + p_FmPcdCcTree->numOfGrps--;
31622 + CcRootReleaseLock(p_FmPcdCcTree);
31623 + RETURN_ERROR(MAJOR, err, NO_MSG);
31624 + }
31625 + }
31626 +
31627 + NextStepAd(
31628 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
31629 + NULL, &nextEngineParams, h_FmPcd);
31630 + }
31631 +
31632 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
31633 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
31634 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
31635 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31636 +
31637 + if (createSchemes)
31638 + {
31639 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
31640 + h_IpReassemblyManip, TRUE,
31641 + ipv4GroupId);
31642 + if (err)
31643 + {
31644 + p_FmPcdCcTree->numOfGrps--;
31645 + if (isIpv6Present)
31646 + {
31647 + p_FmPcdCcTree->numOfGrps--;
31648 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
31649 + }
31650 + CcRootReleaseLock(p_FmPcdCcTree);
31651 + RETURN_ERROR(MAJOR, err, NO_MSG);
31652 + }
31653 + }
31654 +
31655 + NextStepAd(
31656 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31657 + NULL, &nextEngineParams, h_FmPcd);
31658 +
31659 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
31660 +
31661 + CcRootReleaseLock(p_FmPcdCcTree);
31662 +
31663 + return E_OK;
31664 +}
31665 +
31666 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
31667 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
31668 + bool createSchemes)
31669 +{
31670 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31671 + t_FmPcdCcNextEngineParams nextEngineParams;
31672 + t_NetEnvParams netEnvParams;
31673 + t_Handle h_Ad;
31674 + uint8_t groupId;
31675 + t_Error err;
31676 +
31677 + ASSERT_COND(p_FmPcdCcTree);
31678 +
31679 + /* this routine must be protected by the calling routine! */
31680 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
31681 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
31682 +
31683 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31684 +
31685 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
31686 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
31687 +
31688 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
31689 + nextEngineParams.h_Manip = h_ReassemblyManip;
31690 +
31691 + /* Lock tree */
31692 + err = CcRootTryLock(p_FmPcdCcTree);
31693 + if (err)
31694 + return ERROR_CODE(E_BUSY);
31695 +
31696 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
31697 + {
31698 + CcRootReleaseLock(p_FmPcdCcTree);
31699 + return E_OK;
31700 + }
31701 +
31702 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
31703 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
31704 + {
31705 + CcRootReleaseLock(p_FmPcdCcTree);
31706 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31707 + ("This tree was previously updated with different CPR"));
31708 + }
31709 +
31710 + groupId = p_FmPcdCcTree->numOfGrps++;
31711 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
31712 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
31713 +
31714 + if (createSchemes)
31715 + {
31716 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
31717 + p_FmPcdCcTree,
31718 + h_ReassemblyManip, groupId);
31719 + if (err)
31720 + {
31721 + p_FmPcdCcTree->numOfGrps--;
31722 + CcRootReleaseLock(p_FmPcdCcTree);
31723 + RETURN_ERROR(MAJOR, err, NO_MSG);
31724 + }
31725 + }
31726 +
31727 + NextStepAd(
31728 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
31729 + NULL, &nextEngineParams, h_FmPcd);
31730 +
31731 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
31732 +
31733 + CcRootReleaseLock(p_FmPcdCcTree);
31734 +
31735 + return E_OK;
31736 +}
31737 +
31738 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
31739 +{
31740 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31741 +
31742 + ASSERT_COND(p_FmPcdCcTree);
31743 +
31744 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
31745 +}
31746 +
31747 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
31748 + t_Handle h_SavedManipParams)
31749 +{
31750 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
31751 +
31752 + ASSERT_COND(p_FmPcdCcTree);
31753 +
31754 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
31755 +}
31756 +
31757 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
31758 +{
31759 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31760 +
31761 + ASSERT_COND(p_CcNode);
31762 +
31763 + return p_CcNode->parseCode;
31764 +}
31765 +
31766 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
31767 +{
31768 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31769 +
31770 + ASSERT_COND(p_CcNode);
31771 +
31772 + return p_CcNode->offset;
31773 +}
31774 +
31775 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
31776 +{
31777 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
31778 +
31779 + ASSERT_COND(p_CcNode);
31780 +
31781 + return p_CcNode->numOfKeys;
31782 +}
31783 +
31784 +t_Error FmPcdCcModifyNextEngineParamTree(
31785 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
31786 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
31787 +{
31788 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
31789 + t_FmPcd *p_FmPcd;
31790 + t_List h_OldPointersLst, h_NewPointersLst;
31791 + uint16_t keyIndex;
31792 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31793 + t_Error err = E_OK;
31794 +
31795 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
31796 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
31797 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
31798 +
31799 + if (grpId >= p_FmPcdCcTree->numOfGrps)
31800 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
31801 + ("grpId you asked > numOfGroup of relevant tree"));
31802 +
31803 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
31804 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
31805 +
31806 + p_FmPcd = (t_FmPcd *)h_FmPcd;
31807 +
31808 + INIT_LIST(&h_OldPointersLst);
31809 + INIT_LIST(&h_NewPointersLst);
31810 +
31811 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
31812 + + index);
31813 +
31814 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
31815 + e_MODIFY_STATE_CHANGE, FALSE,
31816 + FALSE, TRUE);
31817 + if (!p_ModifyKeyParams)
31818 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31819 +
31820 + p_ModifyKeyParams->tree = TRUE;
31821 +
31822 + if (p_FmPcd->p_CcShadow
31823 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31824 + {
31825 + XX_Free(p_ModifyKeyParams);
31826 + return ERROR_CODE(E_BUSY);
31827 + }
31828 +
31829 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
31830 + p_FmPcdCcNextEngineParams,
31831 + &h_OldPointersLst, &h_NewPointersLst,
31832 + p_ModifyKeyParams);
31833 + if (err)
31834 + {
31835 + XX_Free(p_ModifyKeyParams);
31836 + RETURN_ERROR(MAJOR, err, NO_MSG);
31837 + }
31838 +
31839 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31840 + p_ModifyKeyParams, FALSE);
31841 +
31842 + if (p_FmPcd->p_CcShadow)
31843 + RELEASE_LOCK(p_FmPcd->shadowLock);
31844 +
31845 + ReleaseLst(&h_OldPointersLst);
31846 + ReleaseLst(&h_NewPointersLst);
31847 +
31848 + return err;
31849 +
31850 +}
31851 +
31852 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31853 + uint16_t keyIndex)
31854 +{
31855 +
31856 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31857 + t_FmPcd *p_FmPcd;
31858 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31859 + t_List h_OldPointersLst, h_NewPointersLst;
31860 + bool useShadowStructs = FALSE;
31861 + t_Error err = E_OK;
31862 +
31863 + if (keyIndex >= p_CcNode->numOfKeys)
31864 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31865 + ("impossible to remove key when numOfKeys <= keyIndex"));
31866 +
31867 + if (p_CcNode->h_FmPcd != h_FmPcd)
31868 + RETURN_ERROR(
31869 + MAJOR,
31870 + E_INVALID_VALUE,
31871 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31872 +
31873 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31874 +
31875 + INIT_LIST(&h_OldPointersLst);
31876 + INIT_LIST(&h_NewPointersLst);
31877 +
31878 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31879 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
31880 + FALSE);
31881 + if (!p_ModifyKeyParams)
31882 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31883 +
31884 + if (p_CcNode->maxNumOfKeys)
31885 + {
31886 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31887 + {
31888 + XX_Free(p_ModifyKeyParams);
31889 + return ERROR_CODE(E_BUSY);
31890 + }
31891 +
31892 + useShadowStructs = TRUE;
31893 + }
31894 +
31895 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
31896 + if (err)
31897 + {
31898 + XX_Free(p_ModifyKeyParams);
31899 + if (p_CcNode->maxNumOfKeys)
31900 + RELEASE_LOCK(p_FmPcd->shadowLock);
31901 + RETURN_ERROR(MAJOR, err, NO_MSG);
31902 + }
31903 +
31904 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31905 + &h_OldPointersLst,
31906 + &h_NewPointersLst);
31907 + if (err)
31908 + {
31909 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
31910 + XX_Free(p_ModifyKeyParams);
31911 + if (p_CcNode->maxNumOfKeys)
31912 + RELEASE_LOCK(p_FmPcd->shadowLock);
31913 + RETURN_ERROR(MAJOR, err, NO_MSG);
31914 + }
31915 +
31916 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
31917 + p_ModifyKeyParams, useShadowStructs);
31918 +
31919 + if (p_CcNode->maxNumOfKeys)
31920 + RELEASE_LOCK(p_FmPcd->shadowLock);
31921 +
31922 + ReleaseLst(&h_OldPointersLst);
31923 + ReleaseLst(&h_NewPointersLst);
31924 +
31925 + return err;
31926 +}
31927 +
31928 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
31929 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
31930 + uint8_t *p_Mask)
31931 +{
31932 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
31933 + t_FmPcd *p_FmPcd;
31934 + t_List h_OldPointersLst, h_NewPointersLst;
31935 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
31936 + uint16_t tmpKeyIndex;
31937 + bool useShadowStructs = FALSE;
31938 + t_Error err = E_OK;
31939 +
31940 + if (keyIndex >= p_CcNode->numOfKeys)
31941 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
31942 + ("keyIndex > previously cleared last index + 1"));
31943 +
31944 + if (keySize != p_CcNode->userSizeOfExtraction)
31945 + RETURN_ERROR(
31946 + MAJOR,
31947 + E_INVALID_VALUE,
31948 + ("size for ModifyKey has to be the same as defined in SetNode"));
31949 +
31950 + if (p_CcNode->h_FmPcd != h_FmPcd)
31951 + RETURN_ERROR(
31952 + MAJOR,
31953 + E_INVALID_VALUE,
31954 + ("handler to FmPcd is different from the handle provided at node initialization time"));
31955 +
31956 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
31957 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
31958 + RETURN_ERROR(
31959 + MINOR,
31960 + E_ALREADY_EXISTS,
31961 + ("The received key and mask pair was already found in the match table of the provided node"));
31962 +
31963 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31964 +
31965 + INIT_LIST(&h_OldPointersLst);
31966 + INIT_LIST(&h_NewPointersLst);
31967 +
31968 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
31969 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
31970 + FALSE);
31971 + if (!p_ModifyKeyParams)
31972 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
31973 +
31974 + if (p_CcNode->maxNumOfKeys)
31975 + {
31976 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
31977 + {
31978 + XX_Free(p_ModifyKeyParams);
31979 + return ERROR_CODE(E_BUSY);
31980 + }
31981 +
31982 + useShadowStructs = TRUE;
31983 + }
31984 +
31985 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
31986 + p_ModifyKeyParams);
31987 + if (err)
31988 + {
31989 + XX_Free(p_ModifyKeyParams);
31990 + if (p_CcNode->maxNumOfKeys)
31991 + RELEASE_LOCK(p_FmPcd->shadowLock);
31992 + RETURN_ERROR(MAJOR, err, NO_MSG);
31993 + }
31994 +
31995 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
31996 + &h_OldPointersLst,
31997 + &h_NewPointersLst);
31998 + if (err)
31999 + {
32000 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32001 + XX_Free(p_ModifyKeyParams);
32002 + if (p_CcNode->maxNumOfKeys)
32003 + RELEASE_LOCK(p_FmPcd->shadowLock);
32004 + RETURN_ERROR(MAJOR, err, NO_MSG);
32005 + }
32006 +
32007 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32008 + p_ModifyKeyParams, useShadowStructs);
32009 +
32010 + if (p_CcNode->maxNumOfKeys)
32011 + RELEASE_LOCK(p_FmPcd->shadowLock);
32012 +
32013 + ReleaseLst(&h_OldPointersLst);
32014 + ReleaseLst(&h_NewPointersLst);
32015 +
32016 + return err;
32017 +}
32018 +
32019 +t_Error FmPcdCcModifyMissNextEngineParamNode(
32020 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32021 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32022 +{
32023 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32024 + t_FmPcd *p_FmPcd;
32025 + t_List h_OldPointersLst, h_NewPointersLst;
32026 + uint16_t keyIndex;
32027 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32028 + t_Error err = E_OK;
32029 +
32030 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
32031 +
32032 + keyIndex = p_CcNode->numOfKeys;
32033 +
32034 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32035 +
32036 + INIT_LIST(&h_OldPointersLst);
32037 + INIT_LIST(&h_NewPointersLst);
32038 +
32039 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32040 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
32041 + FALSE);
32042 + if (!p_ModifyKeyParams)
32043 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32044 +
32045 + if (p_CcNode->maxNumOfKeys
32046 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32047 + {
32048 + XX_Free(p_ModifyKeyParams);
32049 + return ERROR_CODE(E_BUSY);
32050 + }
32051 +
32052 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
32053 + p_FmPcdCcNextEngineParams,
32054 + &h_OldPointersLst, &h_NewPointersLst,
32055 + p_ModifyKeyParams);
32056 + if (err)
32057 + {
32058 + XX_Free(p_ModifyKeyParams);
32059 + if (p_CcNode->maxNumOfKeys)
32060 + RELEASE_LOCK(p_FmPcd->shadowLock);
32061 + RETURN_ERROR(MAJOR, err, NO_MSG);
32062 + }
32063 +
32064 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32065 + p_ModifyKeyParams, FALSE);
32066 +
32067 + if (p_CcNode->maxNumOfKeys)
32068 + RELEASE_LOCK(p_FmPcd->shadowLock);
32069 +
32070 + ReleaseLst(&h_OldPointersLst);
32071 + ReleaseLst(&h_NewPointersLst);
32072 +
32073 + return err;
32074 +}
32075 +
32076 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32077 + uint16_t keyIndex, uint8_t keySize,
32078 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
32079 +{
32080 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32081 + t_FmPcd *p_FmPcd;
32082 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32083 + t_List h_OldPointersLst, h_NewPointersLst;
32084 + bool useShadowStructs = FALSE;
32085 + uint16_t tmpKeyIndex;
32086 + t_Error err = E_OK;
32087 +
32088 + if (keyIndex > p_CcNode->numOfKeys)
32089 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
32090 + ("keyIndex > previously cleared last index + 1"));
32091 +
32092 + if (keySize != p_CcNode->userSizeOfExtraction)
32093 + RETURN_ERROR(
32094 + MAJOR,
32095 + E_INVALID_VALUE,
32096 + ("keySize has to be defined as it was defined in initialization step"));
32097 +
32098 + if (p_CcNode->h_FmPcd != h_FmPcd)
32099 + RETURN_ERROR(
32100 + MAJOR,
32101 + E_INVALID_VALUE,
32102 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32103 +
32104 + if (p_CcNode->maxNumOfKeys)
32105 + {
32106 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
32107 + RETURN_ERROR(
32108 + MAJOR,
32109 + E_FULL,
32110 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
32111 + }
32112 + else
32113 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
32114 + RETURN_ERROR(
32115 + MAJOR,
32116 + E_INVALID_VALUE,
32117 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
32118 +
32119 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32120 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32121 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32122 + RETURN_ERROR(
32123 + MAJOR,
32124 + E_ALREADY_EXISTS,
32125 + ("The received key and mask pair was already found in the match table of the provided node"));
32126 +
32127 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32128 +
32129 + INIT_LIST(&h_OldPointersLst);
32130 + INIT_LIST(&h_NewPointersLst);
32131 +
32132 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32133 + e_MODIFY_STATE_ADD, TRUE, TRUE,
32134 + FALSE);
32135 + if (!p_ModifyKeyParams)
32136 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32137 +
32138 + if (p_CcNode->maxNumOfKeys)
32139 + {
32140 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32141 + {
32142 + XX_Free(p_ModifyKeyParams);
32143 + return ERROR_CODE(E_BUSY);
32144 + }
32145 +
32146 + useShadowStructs = TRUE;
32147 + }
32148 +
32149 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32150 + p_FmPcdCcKeyParams,
32151 + p_ModifyKeyParams, TRUE);
32152 + if (err)
32153 + {
32154 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32155 + XX_Free(p_ModifyKeyParams);
32156 + if (p_CcNode->maxNumOfKeys)
32157 + RELEASE_LOCK(p_FmPcd->shadowLock);
32158 + RETURN_ERROR(MAJOR, err, NO_MSG);
32159 + }
32160 +
32161 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32162 + &h_OldPointersLst,
32163 + &h_NewPointersLst);
32164 + if (err)
32165 + {
32166 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32167 + XX_Free(p_ModifyKeyParams);
32168 + if (p_CcNode->maxNumOfKeys)
32169 + RELEASE_LOCK(p_FmPcd->shadowLock);
32170 + RETURN_ERROR(MAJOR, err, NO_MSG);
32171 + }
32172 +
32173 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32174 + p_ModifyKeyParams, useShadowStructs);
32175 + if (p_CcNode->maxNumOfKeys)
32176 + RELEASE_LOCK(p_FmPcd->shadowLock);
32177 +
32178 + ReleaseLst(&h_OldPointersLst);
32179 + ReleaseLst(&h_NewPointersLst);
32180 +
32181 + return err;
32182 +}
32183 +
32184 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32185 + uint16_t keyIndex, uint8_t keySize,
32186 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
32187 +{
32188 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32189 + t_FmPcd *p_FmPcd;
32190 + t_List h_OldPointersLst, h_NewPointersLst;
32191 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32192 + uint16_t tmpKeyIndex;
32193 + bool useShadowStructs = FALSE;
32194 + t_Error err = E_OK;
32195 +
32196 + if (keyIndex > p_CcNode->numOfKeys)
32197 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32198 + ("keyIndex > previously cleared last index + 1"));
32199 +
32200 + if (keySize != p_CcNode->userSizeOfExtraction)
32201 + RETURN_ERROR(
32202 + MAJOR,
32203 + E_INVALID_VALUE,
32204 + ("keySize has to be defined as it was defined in initialization step"));
32205 +
32206 + if (p_CcNode->h_FmPcd != h_FmPcd)
32207 + RETURN_ERROR(
32208 + MAJOR,
32209 + E_INVALID_VALUE,
32210 + ("handler to FmPcd is different from the handle provided at node initialization time"));
32211 +
32212 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
32213 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
32214 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
32215 + RETURN_ERROR(
32216 + MINOR,
32217 + E_ALREADY_EXISTS,
32218 + ("The received key and mask pair was already found in the match table of the provided node"));
32219 +
32220 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32221 +
32222 + INIT_LIST(&h_OldPointersLst);
32223 + INIT_LIST(&h_NewPointersLst);
32224 +
32225 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32226 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
32227 + FALSE);
32228 + if (!p_ModifyKeyParams)
32229 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32230 +
32231 + if (p_CcNode->maxNumOfKeys)
32232 + {
32233 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32234 + {
32235 + XX_Free(p_ModifyKeyParams);
32236 + return ERROR_CODE(E_BUSY);
32237 + }
32238 +
32239 + useShadowStructs = TRUE;
32240 + }
32241 +
32242 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
32243 + p_FmPcdCcKeyParams,
32244 + p_ModifyKeyParams, FALSE);
32245 + if (err)
32246 + {
32247 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32248 + XX_Free(p_ModifyKeyParams);
32249 + if (p_CcNode->maxNumOfKeys)
32250 + RELEASE_LOCK(p_FmPcd->shadowLock);
32251 + RETURN_ERROR(MAJOR, err, NO_MSG);
32252 + }
32253 +
32254 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
32255 + &h_OldPointersLst,
32256 + &h_NewPointersLst);
32257 + if (err)
32258 + {
32259 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
32260 + XX_Free(p_ModifyKeyParams);
32261 + if (p_CcNode->maxNumOfKeys)
32262 + RELEASE_LOCK(p_FmPcd->shadowLock);
32263 + RETURN_ERROR(MAJOR, err, NO_MSG);
32264 + }
32265 +
32266 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32267 + p_ModifyKeyParams, useShadowStructs);
32268 +
32269 + if (p_CcNode->maxNumOfKeys)
32270 + RELEASE_LOCK(p_FmPcd->shadowLock);
32271 +
32272 + ReleaseLst(&h_OldPointersLst);
32273 + ReleaseLst(&h_NewPointersLst);
32274 +
32275 + return err;
32276 +}
32277 +
32278 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
32279 + t_Handle h_Pointer)
32280 +{
32281 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32282 + t_CcNodeInformation *p_CcNodeInfo;
32283 +
32284 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
32285 + (uint32_t)ILLEGAL_BASE);
32286 +
32287 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
32288 +
32289 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
32290 + - p_FmPcd->physicalMuramBase);
32291 +}
32292 +
32293 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
32294 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
32295 +{
32296 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32297 +
32298 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32299 +
32300 + if (grpId >= p_FmPcdCcTree->numOfGrps)
32301 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
32302 + ("grpId you asked > numOfGroup of relevant tree"));
32303 +
32304 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
32305 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
32306 +
32307 + return E_OK;
32308 +}
32309 +
32310 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
32311 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
32312 + t_Handle h_FmPort)
32313 +{
32314 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
32315 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32316 + t_Error err = E_OK;
32317 +
32318 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
32319 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32320 +
32321 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32322 +
32323 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
32324 +
32325 + if (err == E_OK)
32326 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
32327 +
32328 + *p_Offset = (uint32_t)(XX_VirtToPhys(
32329 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
32330 + - p_FmPcd->physicalMuramBase);
32331 +
32332 + return err;
32333 +}
32334 +
32335 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
32336 +{
32337 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
32338 +
32339 + /* this routine must be protected by the calling routine by locking all PCD modules! */
32340 +
32341 + UNUSED(h_FmPcd);
32342 +
32343 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
32344 +
32345 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
32346 +
32347 + return E_OK;
32348 +}
32349 +
32350 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
32351 + t_List *p_List)
32352 +{
32353 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32354 + t_List *p_Pos, *p_Tmp;
32355 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
32356 + uint32_t intFlags;
32357 + t_Error err = E_OK;
32358 +
32359 + intFlags = FmPcdLock(h_FmPcd);
32360 +
32361 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
32362 + {
32363 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32364 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
32365 +
32366 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
32367 +
32368 + if (err)
32369 + {
32370 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
32371 + {
32372 + if (p_Tmp == p_Pos)
32373 + break;
32374 +
32375 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
32376 + }
32377 + break;
32378 + }
32379 +
32380 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
32381 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
32382 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
32383 + }
32384 +
32385 + FmPcdUnlock(h_FmPcd, intFlags);
32386 + CORE_MemoryBarrier();
32387 +
32388 + return err;
32389 +}
32390 +
32391 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
32392 +{
32393 + t_List *p_Pos;
32394 + t_CcNodeInformation *p_CcNodeInfo;
32395 + t_Handle h_FmPcdCcTree;
32396 + uint32_t intFlags;
32397 +
32398 + intFlags = FmPcdLock(h_FmPcd);
32399 +
32400 + LIST_FOR_EACH(p_Pos, p_List)
32401 + {
32402 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
32403 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
32404 + CcRootReleaseLock(h_FmPcdCcTree);
32405 + }
32406 +
32407 + ReleaseLst(p_List);
32408 +
32409 + FmPcdUnlock(h_FmPcd, intFlags);
32410 + CORE_MemoryBarrier();
32411 +}
32412 +
32413 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
32414 +{
32415 + uint32_t intFlags;
32416 + uint32_t newSize = 0, newAlign = 0;
32417 + bool allocFail = FALSE;
32418 +
32419 + ASSERT_COND(p_FmPcd);
32420 +
32421 + if (!size)
32422 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
32423 +
32424 + if (!POWER_OF_2(align))
32425 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
32426 +
32427 + newSize = p_FmPcd->ccShadowSize;
32428 + newAlign = p_FmPcd->ccShadowAlign;
32429 +
32430 + /* Check if current shadow is large enough to hold the requested size */
32431 + if (size > p_FmPcd->ccShadowSize)
32432 + newSize = size;
32433 +
32434 + /* Check if current shadow matches the requested alignment */
32435 + if (align > p_FmPcd->ccShadowAlign)
32436 + newAlign = align;
32437 +
32438 + /* If a bigger shadow size or bigger shadow alignment are required,
32439 + a new shadow will be allocated */
32440 + if ((newSize != p_FmPcd->ccShadowSize)
32441 + || (newAlign != p_FmPcd->ccShadowAlign))
32442 + {
32443 + intFlags = FmPcdLock(p_FmPcd);
32444 +
32445 + if (p_FmPcd->p_CcShadow)
32446 + {
32447 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
32448 + p_FmPcd->ccShadowSize = 0;
32449 + p_FmPcd->ccShadowAlign = 0;
32450 + }
32451 +
32452 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
32453 + newSize, newAlign);
32454 + if (!p_FmPcd->p_CcShadow)
32455 + {
32456 + allocFail = TRUE;
32457 +
32458 + /* If new shadow size allocation failed,
32459 + re-allocate with previous parameters */
32460 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
32461 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
32462 + p_FmPcd->ccShadowAlign);
32463 + }
32464 +
32465 + FmPcdUnlock(p_FmPcd, intFlags);
32466 +
32467 + if (allocFail)
32468 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32469 + ("MURAM allocation for CC Shadow memory"));
32470 +
32471 + p_FmPcd->ccShadowSize = newSize;
32472 + p_FmPcd->ccShadowAlign = newAlign;
32473 + }
32474 +
32475 + return E_OK;
32476 +}
32477 +
32478 +#if (DPAA_VERSION >= 11)
32479 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
32480 + t_Handle h_ReplicGroup,
32481 + t_List *p_AdTables,
32482 + uint32_t *p_NumOfAdTables)
32483 +{
32484 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
32485 + int i = 0;
32486 + void * p_AdTable;
32487 + t_CcNodeInformation ccNodeInfo;
32488 +
32489 + ASSERT_COND(h_Node);
32490 + *p_NumOfAdTables = 0;
32491 +
32492 + /* search in the current node which exact index points on this current replicator group for getting AD */
32493 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
32494 + {
32495 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32496 + == e_FM_PCD_FR)
32497 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
32498 + == (t_Handle)h_ReplicGroup)))
32499 + {
32500 + /* save the current ad table in the list */
32501 + /* this entry uses the input replicator group */
32502 + p_AdTable =
32503 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
32504 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32505 + ccNodeInfo.h_CcNode = p_AdTable;
32506 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
32507 + (*p_NumOfAdTables)++;
32508 + }
32509 + }
32510 +
32511 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
32512 +}
32513 +#endif /* (DPAA_VERSION >= 11) */
32514 +/*********************** End of inter-module routines ************************/
32515 +
32516 +/****************************************/
32517 +/* API Init unit functions */
32518 +/****************************************/
32519 +
32520 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
32521 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
32522 +{
32523 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32524 + t_Error err = E_OK;
32525 + int i = 0, j = 0, k = 0;
32526 + t_FmPcdCcTree *p_FmPcdCcTree;
32527 + uint8_t numOfEntries;
32528 + t_Handle p_CcTreeTmp;
32529 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
32530 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
32531 + t_NetEnvParams netEnvParams;
32532 + uint8_t lastOne = 0;
32533 + uint32_t requiredAction = 0;
32534 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32535 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32536 +
32537 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32538 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
32539 +
32540 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32541 + {
32542 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32543 + return NULL;
32544 + }
32545 +
32546 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
32547 + if (!p_FmPcdCcTree)
32548 + {
32549 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
32550 + return NULL;
32551 + }
32552 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
32553 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
32554 +
32555 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
32556 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32557 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32558 + memset(p_Params,
32559 + 0,
32560 + FM_PCD_MAX_NUM_OF_CC_GROUPS
32561 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
32562 +
32563 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
32564 +
32565 +#ifdef FM_CAPWAP_SUPPORT
32566 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
32567 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
32568 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
32569 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
32570 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
32571 + {
32572 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
32573 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
32574 + {
32575 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
32576 + XX_Free(p_Params);
32577 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32578 + return NULL;
32579 + }
32580 + }
32581 +#endif /* FM_CAPWAP_SUPPORT */
32582 +
32583 + numOfEntries = 0;
32584 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
32585 +
32586 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
32587 + {
32588 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
32589 +
32590 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
32591 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
32592 + {
32593 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32594 + XX_Free(p_Params);
32595 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
32596 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
32597 + return NULL;
32598 + }
32599 +
32600 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
32601 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
32602 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
32603 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32604 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
32605 + {
32606 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32607 + XX_Free(p_Params);
32608 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
32609 + return NULL;
32610 + }
32611 +
32612 + if (lastOne)
32613 + {
32614 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
32615 + {
32616 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32617 + XX_Free(p_Params);
32618 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
32619 + return NULL;
32620 + }
32621 + }
32622 +
32623 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32624 +
32625 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
32626 + netEnvParams.numOfDistinctionUnits =
32627 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
32628 +
32629 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
32630 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
32631 +
32632 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
32633 + if (err)
32634 + {
32635 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32636 + XX_Free(p_Params);
32637 + REPORT_ERROR(MAJOR, err, NO_MSG);
32638 + return NULL;
32639 + }
32640 +
32641 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
32642 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
32643 + j++)
32644 + {
32645 + err = ValidateNextEngineParams(
32646 + h_FmPcd,
32647 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32648 + e_FM_PCD_CC_STATS_MODE_NONE);
32649 + if (err)
32650 + {
32651 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32652 + XX_Free(p_Params);
32653 + REPORT_ERROR(MAJOR, err, (NO_MSG));
32654 + return NULL;
32655 + }
32656 +
32657 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
32658 + {
32659 + err = FmPcdManipCheckParamsForCcNextEngine(
32660 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32661 + &requiredAction);
32662 + if (err)
32663 + {
32664 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32665 + XX_Free(p_Params);
32666 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32667 + return NULL;
32668 + }
32669 + }
32670 + p_KeyAndNextEngineParams = p_Params + k;
32671 +
32672 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
32673 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
32674 + sizeof(t_FmPcdCcNextEngineParams));
32675 +
32676 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
32677 + == e_FM_PCD_CC)
32678 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
32679 + {
32680 + err =
32681 + AllocAndFillAdForContLookupManip(
32682 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
32683 + if (err)
32684 + {
32685 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32686 + XX_Free(p_Params);
32687 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32688 + return NULL;
32689 + }
32690 + }
32691 +
32692 + requiredAction |= UPDATE_CC_WITH_TREE;
32693 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
32694 +
32695 + k++;
32696 + }
32697 + }
32698 +
32699 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
32700 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
32701 +
32702 + p_FmPcdCcTree->ccTreeBaseAddr =
32703 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
32704 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
32705 + FM_PCD_CC_TREE_ADDR_ALIGN));
32706 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
32707 + {
32708 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
32709 + XX_Free(p_Params);
32710 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
32711 + return NULL;
32712 + }
32713 + MemSet8(
32714 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
32715 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
32716 +
32717 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32718 +
32719 + for (i = 0; i < numOfEntries; i++)
32720 + {
32721 + p_KeyAndNextEngineParams = p_Params + i;
32722 +
32723 + NextStepAd(p_CcTreeTmp, NULL,
32724 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
32725 +
32726 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32727 +
32728 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
32729 + p_KeyAndNextEngineParams,
32730 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
32731 +
32732 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32733 + == e_FM_PCD_CC)
32734 + {
32735 + p_FmPcdCcNextNode =
32736 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
32737 + p_CcInformation = FindNodeInfoInReleventLst(
32738 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
32739 + p_FmPcdCcNextNode->h_Spinlock);
32740 +
32741 + if (!p_CcInformation)
32742 + {
32743 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
32744 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
32745 + ccNodeInfo.index = 1;
32746 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
32747 + &ccNodeInfo,
32748 + p_FmPcdCcNextNode->h_Spinlock);
32749 + }
32750 + else
32751 + p_CcInformation->index++;
32752 + }
32753 + }
32754 +
32755 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
32756 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
32757 +
32758 + if (!FmPcdLockTryLockAll(p_FmPcd))
32759 + {
32760 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32761 + XX_Free(p_Params);
32762 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32763 + return NULL;
32764 + }
32765 +
32766 + for (i = 0; i < numOfEntries; i++)
32767 + {
32768 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
32769 + {
32770 + err = SetRequiredAction(
32771 + h_FmPcd,
32772 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
32773 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
32774 + p_FmPcdCcTree);
32775 + if (err)
32776 + {
32777 + FmPcdLockUnlockAll(p_FmPcd);
32778 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32779 + XX_Free(p_Params);
32780 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32781 + return NULL;
32782 + }
32783 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32784 + }
32785 + }
32786 +
32787 + FmPcdLockUnlockAll(p_FmPcd);
32788 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
32789 + if (!p_FmPcdCcTree->p_Lock)
32790 + {
32791 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
32792 + XX_Free(p_Params);
32793 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
32794 + return NULL;
32795 + }
32796 +
32797 + XX_Free(p_Params);
32798 +
32799 + return p_FmPcdCcTree;
32800 +}
32801 +
32802 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
32803 +{
32804 + t_FmPcd *p_FmPcd;
32805 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32806 + int i = 0;
32807 +
32808 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32809 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32810 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32811 +
32812 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
32813 +
32814 + if (p_CcTree->owners)
32815 + RETURN_ERROR(
32816 + MAJOR,
32817 + E_INVALID_SELECTION,
32818 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
32819 +
32820 + /* Delete ip-reassembly schemes if exist */
32821 + if (p_CcTree->h_IpReassemblyManip)
32822 + {
32823 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
32824 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
32825 + }
32826 +
32827 + /* Delete capwap-reassembly schemes if exist */
32828 + if (p_CcTree->h_CapwapReassemblyManip)
32829 + {
32830 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
32831 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
32832 + }
32833 +
32834 + for (i = 0; i < p_CcTree->numOfEntries; i++)
32835 + {
32836 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32837 + == e_FM_PCD_CC)
32838 + UpdateNodeOwner(
32839 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32840 + FALSE);
32841 +
32842 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32843 + FmPcdManipUpdateOwner(
32844 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32845 + FALSE);
32846 +
32847 +#ifdef FM_CAPWAP_SUPPORT
32848 + if ((p_CcTree->numOfGrps == 1) &&
32849 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
32850 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
32851 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
32852 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
32853 + {
32854 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
32855 + return E_INVALID_STATE;
32856 + }
32857 +#endif /* FM_CAPWAP_SUPPORT */
32858 +
32859 +#if (DPAA_VERSION >= 11)
32860 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32861 + == e_FM_PCD_FR)
32862 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32863 + FrmReplicGroupUpdateOwner(
32864 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32865 + FALSE);
32866 +#endif /* (DPAA_VERSION >= 11) */
32867 + }
32868 +
32869 + if (p_CcTree->p_Lock)
32870 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
32871 +
32872 + DeleteTree(p_CcTree, p_FmPcd);
32873 +
32874 + return E_OK;
32875 +}
32876 +
32877 +t_Error FM_PCD_CcRootModifyNextEngine(
32878 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
32879 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32880 +{
32881 + t_FmPcd *p_FmPcd;
32882 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
32883 + t_Error err = E_OK;
32884 +
32885 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
32886 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
32887 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
32888 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
32889 +
32890 + if (!FmPcdLockTryLockAll(p_FmPcd))
32891 + {
32892 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
32893 + return ERROR_CODE(E_BUSY);
32894 + }
32895 +
32896 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
32897 + p_FmPcdCcNextEngineParams);
32898 + FmPcdLockUnlockAll(p_FmPcd);
32899 +
32900 + if (err)
32901 + {
32902 + RETURN_ERROR(MAJOR, err, NO_MSG);
32903 + }
32904 +
32905 + return E_OK;
32906 +}
32907 +
32908 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
32909 + t_FmPcdCcNodeParams *p_CcNodeParam)
32910 +{
32911 + t_FmPcdCcNode *p_CcNode;
32912 + t_Error err;
32913 +
32914 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
32915 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
32916 +
32917 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
32918 + if (!p_CcNode)
32919 + {
32920 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
32921 + return NULL;
32922 + }
32923 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
32924 +
32925 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
32926 +
32927 + switch(GET_ERROR_TYPE(err)
32928 +) {
32929 + case E_OK:
32930 + break;
32931 +
32932 + case E_BUSY:
32933 + DBG(TRACE, ("E_BUSY error"));
32934 + return NULL;
32935 +
32936 + default:
32937 + REPORT_ERROR(MAJOR, err, NO_MSG);
32938 + return NULL;
32939 + }
32940 +
32941 + return p_CcNode;
32942 +}
32943 +
32944 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
32945 +{
32946 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32947 + int i = 0;
32948 +
32949 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32950 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
32951 +
32952 + if (p_CcNode->owners)
32953 + RETURN_ERROR(
32954 + MAJOR,
32955 + E_INVALID_STATE,
32956 + ("This node cannot be removed because it is occupied; first unbind this node"));
32957 +
32958 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32959 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32960 + == e_FM_PCD_CC)
32961 + UpdateNodeOwner(
32962 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32963 + FALSE);
32964 +
32965 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32966 + == e_FM_PCD_CC)
32967 + UpdateNodeOwner(
32968 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
32969 + FALSE);
32970 +
32971 + /* Handle also Miss entry */
32972 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
32973 + {
32974 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
32975 + FmPcdManipUpdateOwner(
32976 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
32977 + FALSE);
32978 +
32979 +#if (DPAA_VERSION >= 11)
32980 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
32981 + == e_FM_PCD_FR)
32982 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
32983 + {
32984 + FrmReplicGroupUpdateOwner(
32985 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
32986 + FALSE);
32987 + }
32988 +#endif /* (DPAA_VERSION >= 11) */
32989 + }
32990 +
32991 + DeleteNode(p_CcNode);
32992 +
32993 + return E_OK;
32994 +}
32995 +
32996 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
32997 + uint8_t keySize,
32998 + t_FmPcdCcKeyParams *p_KeyParams)
32999 +{
33000 + t_FmPcd *p_FmPcd;
33001 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33002 + t_Error err = E_OK;
33003 +
33004 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33005 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33006 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33007 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33008 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33009 +
33010 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
33011 + keyIndex = p_CcNode->numOfKeys;
33012 +
33013 + if (!FmPcdLockTryLockAll(p_FmPcd))
33014 + {
33015 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33016 + return ERROR_CODE(E_BUSY);
33017 + }
33018 +
33019 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
33020 +
33021 + FmPcdLockUnlockAll(p_FmPcd);
33022 +
33023 + switch(GET_ERROR_TYPE(err)
33024 +) {
33025 + case E_OK:
33026 + return E_OK;
33027 +
33028 + case E_BUSY:
33029 + DBG(TRACE, ("E_BUSY error"));
33030 + return ERROR_CODE(E_BUSY);
33031 +
33032 + default:
33033 + RETURN_ERROR(MAJOR, err, NO_MSG);
33034 + }
33035 +}
33036 +
33037 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
33038 +{
33039 + t_FmPcd *p_FmPcd;
33040 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33041 + t_Error err = E_OK;
33042 +
33043 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33044 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33045 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33046 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33047 +
33048 + if (!FmPcdLockTryLockAll(p_FmPcd))
33049 + {
33050 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33051 + return ERROR_CODE(E_BUSY);
33052 + }
33053 +
33054 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33055 +
33056 + FmPcdLockUnlockAll(p_FmPcd);
33057 +
33058 + switch(GET_ERROR_TYPE(err)
33059 +) {
33060 + case E_OK:
33061 + return E_OK;
33062 +
33063 + case E_BUSY:
33064 + DBG(TRACE, ("E_BUSY error"));
33065 + return ERROR_CODE(E_BUSY);
33066 +
33067 + default:
33068 + RETURN_ERROR(MAJOR, err, NO_MSG);
33069 + }
33070 +
33071 + return E_OK;
33072 +}
33073 +
33074 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
33075 + uint8_t keySize, uint8_t *p_Key,
33076 + uint8_t *p_Mask)
33077 +{
33078 + t_FmPcd *p_FmPcd;
33079 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33080 + t_Error err = E_OK;
33081 +
33082 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33083 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33084 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33085 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33086 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33087 +
33088 +
33089 + if (!FmPcdLockTryLockAll(p_FmPcd))
33090 + {
33091 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33092 + return ERROR_CODE(E_BUSY);
33093 + }
33094 +
33095 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
33096 +
33097 + FmPcdLockUnlockAll(p_FmPcd);
33098 +
33099 + switch(GET_ERROR_TYPE(err)
33100 +) {
33101 + case E_OK:
33102 + return E_OK;
33103 +
33104 + case E_BUSY:
33105 + DBG(TRACE, ("E_BUSY error"));
33106 + return ERROR_CODE(E_BUSY);
33107 +
33108 + default:
33109 + RETURN_ERROR(MAJOR, err, NO_MSG);
33110 + }
33111 +}
33112 +
33113 +t_Error FM_PCD_MatchTableModifyNextEngine(
33114 + t_Handle h_CcNode, uint16_t keyIndex,
33115 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33116 +{
33117 + t_FmPcd *p_FmPcd;
33118 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33119 + t_Error err = E_OK;
33120 +
33121 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33122 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33123 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33124 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33125 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33126 +
33127 + if (!FmPcdLockTryLockAll(p_FmPcd))
33128 + {
33129 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33130 + return ERROR_CODE(E_BUSY);
33131 + }
33132 +
33133 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33134 + p_FmPcdCcNextEngineParams);
33135 +
33136 + FmPcdLockUnlockAll(p_FmPcd);
33137 +
33138 + switch(GET_ERROR_TYPE(err)
33139 +) {
33140 + case E_OK:
33141 + return E_OK;
33142 +
33143 + case E_BUSY:
33144 + DBG(TRACE, ("E_BUSY error"));
33145 + return ERROR_CODE(E_BUSY);
33146 +
33147 + default:
33148 + RETURN_ERROR(MAJOR, err, NO_MSG);
33149 + }
33150 +}
33151 +
33152 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
33153 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33154 +{
33155 + t_FmPcd *p_FmPcd;
33156 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33157 + t_Error err = E_OK;
33158 +
33159 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33160 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33161 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33162 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33163 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33164 +
33165 + if (!FmPcdLockTryLockAll(p_FmPcd))
33166 + {
33167 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33168 + return ERROR_CODE(E_BUSY);
33169 + }
33170 +
33171 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
33172 + p_FmPcdCcNextEngineParams);
33173 +
33174 + FmPcdLockUnlockAll(p_FmPcd);
33175 +
33176 + switch(GET_ERROR_TYPE(err)
33177 +) {
33178 + case E_OK:
33179 + return E_OK;
33180 +
33181 + case E_BUSY:
33182 + DBG(TRACE, ("E_BUSY error"));
33183 + return ERROR_CODE(E_BUSY);
33184 +
33185 + default:
33186 + RETURN_ERROR(MAJOR, err, NO_MSG);
33187 + }
33188 +}
33189 +
33190 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
33191 + uint16_t keyIndex,
33192 + uint8_t keySize,
33193 + t_FmPcdCcKeyParams *p_KeyParams)
33194 +{
33195 + t_FmPcd *p_FmPcd;
33196 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33197 + t_Error err = E_OK;
33198 +
33199 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33200 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33201 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33202 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33203 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33204 +
33205 + if (!FmPcdLockTryLockAll(p_FmPcd))
33206 + {
33207 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33208 + return ERROR_CODE(E_BUSY);
33209 + }
33210 +
33211 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
33212 + p_KeyParams);
33213 +
33214 + FmPcdLockUnlockAll(p_FmPcd);
33215 +
33216 + switch(GET_ERROR_TYPE(err)
33217 +) {
33218 + case E_OK:
33219 + return E_OK;
33220 +
33221 + case E_BUSY:
33222 + DBG(TRACE, ("E_BUSY error"));
33223 + return ERROR_CODE(E_BUSY);
33224 +
33225 + default:
33226 + RETURN_ERROR(MAJOR, err, NO_MSG);
33227 + }
33228 +}
33229 +
33230 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
33231 + uint8_t *p_Key, uint8_t *p_Mask)
33232 +{
33233 + t_FmPcd *p_FmPcd;
33234 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33235 + uint16_t keyIndex;
33236 + t_Error err;
33237 +
33238 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33239 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33240 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33241 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33242 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33243 +
33244 + if (!FmPcdLockTryLockAll(p_FmPcd))
33245 + {
33246 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33247 + return ERROR_CODE(E_BUSY);
33248 + }
33249 +
33250 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33251 + if (GET_ERROR_TYPE(err) != E_OK)
33252 + {
33253 + FmPcdLockUnlockAll(p_FmPcd);
33254 + RETURN_ERROR(
33255 + MAJOR,
33256 + err,
33257 + ("The received key and mask pair was not found in the match table of the provided node"));
33258 + }
33259 +
33260 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
33261 +
33262 + FmPcdLockUnlockAll(p_FmPcd);
33263 +
33264 + switch(GET_ERROR_TYPE(err)
33265 +) {
33266 + case E_OK:
33267 + return E_OK;
33268 +
33269 + case E_BUSY:
33270 + DBG(TRACE, ("E_BUSY error"));
33271 + return ERROR_CODE(E_BUSY);
33272 +
33273 + default:
33274 + RETURN_ERROR(MAJOR, err, NO_MSG);
33275 + }
33276 +}
33277 +
33278 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
33279 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33280 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33281 +{
33282 + t_FmPcd *p_FmPcd;
33283 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33284 + uint16_t keyIndex;
33285 + t_Error err;
33286 +
33287 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33288 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33289 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33290 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33291 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33292 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33293 +
33294 + if (!FmPcdLockTryLockAll(p_FmPcd))
33295 + {
33296 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33297 + return ERROR_CODE(E_BUSY);
33298 + }
33299 +
33300 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33301 + if (GET_ERROR_TYPE(err) != E_OK)
33302 + {
33303 + FmPcdLockUnlockAll(p_FmPcd);
33304 + RETURN_ERROR(
33305 + MAJOR,
33306 + err,
33307 + ("The received key and mask pair was not found in the match table of the provided node"));
33308 + }
33309 +
33310 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
33311 + p_FmPcdCcNextEngineParams);
33312 +
33313 + FmPcdLockUnlockAll(p_FmPcd);
33314 +
33315 + switch(GET_ERROR_TYPE(err)
33316 +) {
33317 + case E_OK:
33318 + return E_OK;
33319 +
33320 + case E_BUSY:
33321 + DBG(TRACE, ("E_BUSY error"));
33322 + return ERROR_CODE(E_BUSY);
33323 +
33324 + default:
33325 + RETURN_ERROR(MAJOR, err, NO_MSG);
33326 + }
33327 +}
33328 +
33329 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
33330 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33331 + t_FmPcdCcKeyParams *p_KeyParams)
33332 +{
33333 + t_FmPcd *p_FmPcd;
33334 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33335 + uint16_t keyIndex;
33336 + t_Error err;
33337 +
33338 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33339 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33340 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33341 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33342 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33343 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33344 +
33345 + if (!FmPcdLockTryLockAll(p_FmPcd))
33346 + {
33347 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33348 + return ERROR_CODE(E_BUSY);
33349 + }
33350 +
33351 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33352 + if (GET_ERROR_TYPE(err) != E_OK)
33353 + {
33354 + FmPcdLockUnlockAll(p_FmPcd);
33355 + RETURN_ERROR(
33356 + MAJOR,
33357 + err,
33358 + ("The received key and mask pair was not found in the match table of the provided node"));
33359 + }
33360 +
33361 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
33362 + p_KeyParams);
33363 +
33364 + FmPcdLockUnlockAll(p_FmPcd);
33365 +
33366 + switch(GET_ERROR_TYPE(err)
33367 +) {
33368 + case E_OK:
33369 + return E_OK;
33370 +
33371 + case E_BUSY:
33372 + DBG(TRACE, ("E_BUSY error"));
33373 + return ERROR_CODE(E_BUSY);
33374 +
33375 + default:
33376 + RETURN_ERROR(MAJOR, err, NO_MSG);
33377 + }
33378 +}
33379 +
33380 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
33381 + uint8_t *p_Key, uint8_t *p_Mask,
33382 + uint8_t *p_NewKey, uint8_t *p_NewMask)
33383 +{
33384 + t_FmPcd *p_FmPcd;
33385 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33386 + t_List h_List;
33387 + uint16_t keyIndex;
33388 + t_Error err;
33389 +
33390 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33391 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
33392 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33393 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33394 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
33395 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
33396 +
33397 + INIT_LIST(&h_List);
33398 +
33399 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
33400 + if (err)
33401 + {
33402 + DBG(TRACE, ("Node's trees lock failed"));
33403 + return ERROR_CODE(E_BUSY);
33404 + }
33405 +
33406 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33407 + if (GET_ERROR_TYPE(err) != E_OK)
33408 + {
33409 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33410 + RETURN_ERROR(MAJOR, err,
33411 + ("The received key and mask pair was not found in the "
33412 + "match table of the provided node"));
33413 + }
33414 +
33415 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
33416 + p_NewMask);
33417 +
33418 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
33419 +
33420 + switch(GET_ERROR_TYPE(err)
33421 +) {
33422 + case E_OK:
33423 + return E_OK;
33424 +
33425 + case E_BUSY:
33426 + DBG(TRACE, ("E_BUSY error"));
33427 + return ERROR_CODE(E_BUSY);
33428 +
33429 + default:
33430 + RETURN_ERROR(MAJOR, err, NO_MSG);
33431 + }
33432 +}
33433 +
33434 +t_Error FM_PCD_MatchTableGetNextEngine(
33435 + t_Handle h_CcNode, uint16_t keyIndex,
33436 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33437 +{
33438 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33439 +
33440 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
33441 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33442 +
33443 + if (keyIndex >= p_CcNode->numOfKeys)
33444 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33445 + ("keyIndex exceeds current number of keys"));
33446 +
33447 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
33448 + RETURN_ERROR(
33449 + MAJOR,
33450 + E_INVALID_VALUE,
33451 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
33452 +
33453 + memcpy(p_FmPcdCcNextEngineParams,
33454 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
33455 + sizeof(t_FmPcdCcNextEngineParams));
33456 +
33457 + return E_OK;
33458 +}
33459 +
33460 +
33461 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
33462 +{
33463 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33464 + uint32_t *p_StatsCounters, frameCount;
33465 + uint32_t intFlags;
33466 +
33467 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
33468 +
33469 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
33470 + {
33471 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
33472 + return 0;
33473 + }
33474 +
33475 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
33476 + && (p_CcNode->statisticsMode
33477 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33478 + {
33479 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
33480 + return 0;
33481 + }
33482 +
33483 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33484 +
33485 + if (keyIndex >= p_CcNode->numOfKeys)
33486 + {
33487 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33488 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
33489 + return 0;
33490 + }
33491 +
33492 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
33493 + {
33494 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33495 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
33496 + return 0;
33497 + }
33498 +
33499 + p_StatsCounters =
33500 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
33501 + ASSERT_COND(p_StatsCounters);
33502 +
33503 + /* The first counter is byte counter, so we need to advance to the next counter */
33504 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
33505 + FM_PCD_CC_STATS_COUNTER_SIZE)));
33506 +
33507 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33508 +
33509 + return frameCount;
33510 +}
33511 +
33512 +t_Error FM_PCD_MatchTableGetKeyStatistics(
33513 + t_Handle h_CcNode, uint16_t keyIndex,
33514 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33515 +{
33516 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33517 + uint32_t intFlags;
33518 + t_Error err;
33519 +
33520 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33521 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33522 +
33523 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33524 +
33525 + if (keyIndex >= p_CcNode->numOfKeys)
33526 + RETURN_ERROR(
33527 + MAJOR,
33528 + E_INVALID_STATE,
33529 + ("The provided keyIndex exceeds the number of keys in this match table"));
33530 +
33531 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33532 +
33533 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33534 +
33535 + if (err != E_OK)
33536 + RETURN_ERROR(MAJOR, err, NO_MSG);
33537 +
33538 + return E_OK;
33539 +}
33540 +
33541 +t_Error FM_PCD_MatchTableGetMissStatistics(
33542 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
33543 +{
33544 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33545 + uint32_t intFlags;
33546 + t_Error err;
33547 +
33548 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33549 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
33550 +
33551 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33552 +
33553 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
33554 + p_MissStatistics);
33555 +
33556 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33557 +
33558 + if (err != E_OK)
33559 + RETURN_ERROR(MAJOR, err, NO_MSG);
33560 +
33561 + return E_OK;
33562 +}
33563 +
33564 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
33565 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
33566 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
33567 +{
33568 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33569 + uint16_t keyIndex;
33570 + uint32_t intFlags;
33571 + t_Error err;
33572 +
33573 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33574 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
33575 +
33576 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
33577 +
33578 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
33579 + if (GET_ERROR_TYPE(err) != E_OK)
33580 + {
33581 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33582 + RETURN_ERROR(MAJOR, err,
33583 + ("The received key and mask pair was not found in the "
33584 + "match table of the provided node"));
33585 + }
33586 +
33587 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
33588 +
33589 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
33590 +
33591 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
33592 +
33593 + if (err != E_OK)
33594 + RETURN_ERROR(MAJOR, err, NO_MSG);
33595 +
33596 + return E_OK;
33597 +}
33598 +
33599 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
33600 + uint8_t keySize, uint8_t *p_Key,
33601 + uint8_t hashShift,
33602 + t_Handle *p_CcNodeBucketHandle,
33603 + uint8_t *p_BucketIndex,
33604 + uint16_t *p_LastIndex)
33605 +{
33606 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33607 + uint16_t glblMask;
33608 + uint64_t crc64 = 0;
33609 +
33610 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
33611 + SANITY_CHECK_RETURN_ERROR(
33612 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
33613 + E_INVALID_STATE);
33614 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33615 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
33616 +
33617 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
33618 + be16_to_cpus(&glblMask);
33619 +
33620 + crc64 = crc64_init();
33621 + crc64 = crc64_compute(p_Key, keySize, crc64);
33622 + crc64 >>= hashShift;
33623 +
33624 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
33625 + & glblMask) >> 4);
33626 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
33627 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
33628 +
33629 + *p_CcNodeBucketHandle =
33630 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
33631 + if (!*p_CcNodeBucketHandle)
33632 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
33633 +
33634 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
33635 +
33636 + return E_OK;
33637 +}
33638 +
33639 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
33640 +{
33641 + t_FmPcdCcNode *p_CcNodeHashTbl;
33642 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
33643 + t_FmPcdCcNode *p_CcNode;
33644 + t_Handle h_MissStatsCounters = NULL;
33645 + t_FmPcdCcKeyParams *p_HashKeyParams;
33646 + int i;
33647 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
33648 + bool statsEnForMiss = FALSE;
33649 + t_Error err;
33650 +
33651 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
33652 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
33653 +
33654 + if (p_Param->maxNumOfKeys == 0)
33655 + {
33656 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
33657 + return NULL;
33658 + }
33659 +
33660 + if (p_Param->hashResMask == 0)
33661 + {
33662 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
33663 + return NULL;
33664 + }
33665 +
33666 + /*Fix: QorIQ SDK / QSDK-2131*/
33667 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
33668 + {
33669 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Next PCD Engine for on-miss entry is invalid. On-miss entry is always required. You can use e_FM_PCD_DONE."));
33670 + return NULL;
33671 + }
33672 +
33673 +#if (DPAA_VERSION >= 11)
33674 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
33675 + {
33676 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
33677 + ("RMON statistics mode is not supported for hash table"));
33678 + return NULL;
33679 + }
33680 +#endif /* (DPAA_VERSION >= 11) */
33681 +
33682 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33683 + sizeof(t_FmPcdCcNodeParams));
33684 + if (!p_ExactMatchCcNodeParam)
33685 + {
33686 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
33687 + return NULL;
33688 + }
33689 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33690 +
33691 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
33692 + sizeof(t_FmPcdCcNodeParams));
33693 + if (!p_IndxHashCcNodeParam)
33694 + {
33695 + XX_Free(p_ExactMatchCcNodeParam);
33696 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
33697 + return NULL;
33698 + }
33699 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
33700 +
33701 + /* Calculate number of sets and number of ways of the hash table */
33702 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
33703 + while (countMask)
33704 + {
33705 + onesCount++;
33706 + countMask = (uint16_t)(countMask >> 1);
33707 + }
33708 +
33709 + numOfSets = (uint16_t)(1 << onesCount);
33710 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
33711 +
33712 + if (p_Param->maxNumOfKeys % numOfSets)
33713 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
33714 +
33715 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
33716 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
33717 + {
33718 + /* Allocating a statistics counters table that will be used by all
33719 + 'miss' entries of the hash table */
33720 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
33721 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
33722 + FM_PCD_CC_AD_TABLE_ALIGN);
33723 + if (!h_MissStatsCounters)
33724 + {
33725 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
33726 + XX_Free(p_IndxHashCcNodeParam);
33727 + XX_Free(p_ExactMatchCcNodeParam);
33728 + return NULL;
33729 + }
33730 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
33731 +
33732 + /* Always enable statistics for 'miss', so that a statistics AD will be
33733 + initialized from the start. We'll store the requested 'statistics enable'
33734 + value and it will be used when statistics are read by the user. */
33735 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
33736 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
33737 + }
33738 +
33739 + /* Building exact-match node params, will be used to create the hash buckets */
33740 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33741 +
33742 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
33743 + e_FM_PCD_EXTRACT_FROM_KEY;
33744 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
33745 + e_FM_PCD_ACTION_EXACT_MATCH;
33746 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
33747 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
33748 + p_Param->matchKeySize;
33749 +
33750 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
33751 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
33752 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
33753 + p_Param->statisticsMode;
33754 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
33755 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
33756 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
33757 + p_Param->ccNextEngineParamsForMiss;
33758 +
33759 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
33760 +
33761 + for (i = 0; i < numOfSets; i++)
33762 + {
33763 + /* Each exact-match node will be marked as a 'bucket' and provided with
33764 + a pointer to statistics counters, to be used for 'miss' entry
33765 + statistics */
33766 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
33767 + if (!p_CcNode)
33768 + break;
33769 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
33770 +
33771 + p_CcNode->isHashBucket = TRUE;
33772 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
33773 +
33774 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
33775 + if (err)
33776 + break;
33777 +
33778 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
33779 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
33780 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
33781 + p_CcNode;
33782 + }
33783 +
33784 + if (i < numOfSets)
33785 + {
33786 + for (i = i - 1; i >= 0; i--)
33787 + FM_PCD_MatchTableDelete(
33788 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
33789 +
33790 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33791 +
33792 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
33793 + XX_Free(p_IndxHashCcNodeParam);
33794 + XX_Free(p_ExactMatchCcNodeParam);
33795 + return NULL;
33796 + }
33797 +
33798 + /* Creating indexed-hash CC node */
33799 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
33800 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
33801 + e_FM_PCD_EXTRACT_FROM_HASH;
33802 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
33803 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
33804 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
33805 + p_Param->hashResMask;
33806 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
33807 + p_Param->hashShift;
33808 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
33809 +
33810 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
33811 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
33812 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
33813 + e_FM_PCD_CC_STATS_MODE_NONE;
33814 + /* Number of keys of this node is number of sets of the hash */
33815 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
33816 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
33817 +
33818 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
33819 +
33820 + if (p_CcNodeHashTbl)
33821 + {
33822 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
33823 +
33824 + /* Storing the allocated counters for buckets 'miss' in the hash table
33825 + and if statistics for miss were enabled. */
33826 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
33827 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
33828 + }
33829 +
33830 + XX_Free(p_IndxHashCcNodeParam);
33831 + XX_Free(p_ExactMatchCcNodeParam);
33832 +
33833 + return p_CcNodeHashTbl;
33834 +}
33835 +
33836 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
33837 +{
33838 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33839 + t_Handle h_FmPcd;
33840 + t_Handle *p_HashBuckets, h_MissStatsCounters;
33841 + uint16_t i, numOfBuckets;
33842 + t_Error err;
33843 +
33844 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33845 +
33846 + /* Store all hash buckets before the hash is freed */
33847 + numOfBuckets = p_HashTbl->numOfKeys;
33848 +
33849 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
33850 + if (!p_HashBuckets)
33851 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
33852 +
33853 + for (i = 0; i < numOfBuckets; i++)
33854 + p_HashBuckets[i] =
33855 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33856 +
33857 + h_FmPcd = p_HashTbl->h_FmPcd;
33858 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
33859 +
33860 + /* Free the hash */
33861 + err = FM_PCD_MatchTableDelete(p_HashTbl);
33862 +
33863 + /* Free each hash bucket */
33864 + for (i = 0; i < numOfBuckets; i++)
33865 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
33866 +
33867 + XX_Free(p_HashBuckets);
33868 +
33869 + /* Free statistics counters for 'miss', if these were allocated */
33870 + if (h_MissStatsCounters)
33871 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
33872 +
33873 + if (err)
33874 + RETURN_ERROR(MAJOR, err, NO_MSG);
33875 +
33876 + return E_OK;
33877 +}
33878 +
33879 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
33880 + t_FmPcdCcKeyParams *p_KeyParams)
33881 +{
33882 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33883 + t_Handle h_HashBucket;
33884 + uint8_t bucketIndex;
33885 + uint16_t lastIndex;
33886 + t_Error err;
33887 +
33888 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33889 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
33890 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
33891 +
33892 + if (p_KeyParams->p_Mask)
33893 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33894 + ("Keys masks not supported for hash table"));
33895 +
33896 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
33897 + p_KeyParams->p_Key,
33898 + p_HashTbl->kgHashShift,
33899 + &h_HashBucket, &bucketIndex,
33900 + &lastIndex);
33901 + if (err)
33902 + RETURN_ERROR(MAJOR, err, NO_MSG);
33903 +
33904 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
33905 + p_KeyParams);
33906 +}
33907 +
33908 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
33909 + uint8_t *p_Key)
33910 +{
33911 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33912 + t_Handle h_HashBucket;
33913 + uint8_t bucketIndex;
33914 + uint16_t lastIndex;
33915 + t_Error err;
33916 +
33917 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33918 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33919 +
33920 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33921 + p_HashTbl->kgHashShift,
33922 + &h_HashBucket, &bucketIndex,
33923 + &lastIndex);
33924 + if (err)
33925 + RETURN_ERROR(MAJOR, err, NO_MSG);
33926 +
33927 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
33928 +}
33929 +
33930 +t_Error FM_PCD_HashTableModifyNextEngine(
33931 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
33932 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33933 +{
33934 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33935 + t_Handle h_HashBucket;
33936 + uint8_t bucketIndex;
33937 + uint16_t lastIndex;
33938 + t_Error err;
33939 +
33940 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
33941 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
33942 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33943 +
33944 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
33945 + p_HashTbl->kgHashShift,
33946 + &h_HashBucket, &bucketIndex,
33947 + &lastIndex);
33948 + if (err)
33949 + RETURN_ERROR(MAJOR, err, NO_MSG);
33950 +
33951 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
33952 + NULL,
33953 + p_FmPcdCcNextEngineParams);
33954 +}
33955 +
33956 +t_Error FM_PCD_HashTableModifyMissNextEngine(
33957 + t_Handle h_HashTbl,
33958 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33959 +{
33960 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
33961 + t_Handle h_HashBucket;
33962 + uint8_t i;
33963 + bool nullifyMissStats = FALSE;
33964 + t_Error err;
33965 +
33966 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
33967 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
33968 +
33969 + if ((!p_HashTbl->h_MissStatsCounters)
33970 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33971 + RETURN_ERROR(
33972 + MAJOR,
33973 + E_CONFLICT,
33974 + ("Statistics are requested for a key, but statistics mode was set"
33975 + "to 'NONE' upon initialization"));
33976 +
33977 + if (p_HashTbl->h_MissStatsCounters)
33978 + {
33979 + if ((!p_HashTbl->statsEnForMiss)
33980 + && (p_FmPcdCcNextEngineParams->statisticsEn))
33981 + nullifyMissStats = TRUE;
33982 +
33983 + if ((p_HashTbl->statsEnForMiss)
33984 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
33985 + {
33986 + p_HashTbl->statsEnForMiss = FALSE;
33987 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
33988 + }
33989 + }
33990 +
33991 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
33992 + {
33993 + h_HashBucket =
33994 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
33995 +
33996 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
33997 + p_FmPcdCcNextEngineParams);
33998 + if (err)
33999 + RETURN_ERROR(MAJOR, err, NO_MSG);
34000 + }
34001 +
34002 + if (nullifyMissStats)
34003 + {
34004 + memset(p_HashTbl->h_MissStatsCounters, 0,
34005 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
34006 + memset(p_HashTbl->h_MissStatsCounters, 0,
34007 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
34008 + p_HashTbl->statsEnForMiss = TRUE;
34009 + }
34010 +
34011 + return E_OK;
34012 +}
34013 +
34014 +
34015 +t_Error FM_PCD_HashTableGetMissNextEngine(
34016 + t_Handle h_HashTbl,
34017 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34018 +{
34019 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
34020 + t_FmPcdCcNode *p_HashBucket;
34021 +
34022 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
34023 +
34024 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
34025 + p_HashBucket =
34026 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
34027 +
34028 + memcpy(p_FmPcdCcNextEngineParams,
34029 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
34030 + sizeof(t_FmPcdCcNextEngineParams));
34031 +
34032 + return E_OK;
34033 +}
34034 +
34035 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
34036 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
34037 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
34038 +{
34039 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
34040 + t_Handle h_HashBucket;
34041 + uint8_t bucketIndex;
34042 + uint16_t lastIndex;
34043 + t_Error err;
34044 +
34045 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
34046 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34047 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
34048 +
34049 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
34050 + p_HashTbl->kgHashShift,
34051 + &h_HashBucket, &bucketIndex,
34052 + &lastIndex);
34053 + if (err)
34054 + RETURN_ERROR(MAJOR, err, NO_MSG);
34055 +
34056 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
34057 + NULL, p_KeyStatistics);
34058 +}
34059 +
34060 +t_Error FM_PCD_HashTableGetMissStatistics(
34061 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
34062 +{
34063 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
34064 + t_Handle h_HashBucket;
34065 +
34066 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
34067 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
34068 +
34069 + if (!p_HashTbl->statsEnForMiss)
34070 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
34071 + ("Statistics were not enabled for miss"));
34072 +
34073 + h_HashBucket =
34074 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
34075 +
34076 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
34077 +}
34078 --- /dev/null
34079 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
34080 @@ -0,0 +1,399 @@
34081 +/*
34082 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34083 + *
34084 + * Redistribution and use in source and binary forms, with or without
34085 + * modification, are permitted provided that the following conditions are met:
34086 + * * Redistributions of source code must retain the above copyright
34087 + * notice, this list of conditions and the following disclaimer.
34088 + * * Redistributions in binary form must reproduce the above copyright
34089 + * notice, this list of conditions and the following disclaimer in the
34090 + * documentation and/or other materials provided with the distribution.
34091 + * * Neither the name of Freescale Semiconductor nor the
34092 + * names of its contributors may be used to endorse or promote products
34093 + * derived from this software without specific prior written permission.
34094 + *
34095 + *
34096 + * ALTERNATIVELY, this software may be distributed under the terms of the
34097 + * GNU General Public License ("GPL") as published by the Free Software
34098 + * Foundation, either version 2 of that License or (at your option) any
34099 + * later version.
34100 + *
34101 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34102 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34103 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34104 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34105 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34106 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34107 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34108 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34109 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34110 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34111 + */
34112 +
34113 +
34114 +/******************************************************************************
34115 + @File fm_cc.h
34116 +
34117 + @Description FM PCD CC ...
34118 +*//***************************************************************************/
34119 +#ifndef __FM_CC_H
34120 +#define __FM_CC_H
34121 +
34122 +#include "std_ext.h"
34123 +#include "error_ext.h"
34124 +#include "list_ext.h"
34125 +
34126 +#include "fm_pcd.h"
34127 +
34128 +
34129 +/***********************************************************************/
34130 +/* Coarse classification defines */
34131 +/***********************************************************************/
34132 +
34133 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
34134 +
34135 +#define CC_PC_FF_MACDST 0x00
34136 +#define CC_PC_FF_MACSRC 0x01
34137 +#define CC_PC_FF_ETYPE 0x02
34138 +
34139 +#define CC_PC_FF_TCI1 0x03
34140 +#define CC_PC_FF_TCI2 0x04
34141 +
34142 +#define CC_PC_FF_MPLS1 0x06
34143 +#define CC_PC_FF_MPLS_LAST 0x07
34144 +
34145 +#define CC_PC_FF_IPV4DST1 0x08
34146 +#define CC_PC_FF_IPV4DST2 0x16
34147 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
34148 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
34149 +#define CC_PC_FF_IPV4PTYPE1 0x0A
34150 +#define CC_PC_FF_IPV4PTYPE2 0x18
34151 +#define CC_PC_FF_IPV4SRC1 0x0b
34152 +#define CC_PC_FF_IPV4SRC2 0x19
34153 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
34154 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
34155 +#define CC_PC_FF_IPV4TTL 0x29
34156 +
34157 +
34158 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
34159 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
34160 +#define CC_PC_FF_IPV6PTYPE1 0x0e
34161 +#define CC_PC_FF_IPV6PTYPE2 0x1c
34162 +#define CC_PC_FF_IPV6DST1 0x0f
34163 +#define CC_PC_FF_IPV6DST2 0x1d
34164 +#define CC_PC_FF_IPV6SRC1 0x10
34165 +#define CC_PC_FF_IPV6SRC2 0x1e
34166 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
34167 +#define CC_PC_FF_IPPID 0x24
34168 +#define CC_PC_FF_IPDSCP 0x76
34169 +
34170 +#define CC_PC_FF_GREPTYPE 0x11
34171 +
34172 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
34173 +#define CC_PC_FF_MINENCAP_IPDST 0x13
34174 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
34175 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
34176 +
34177 +#define CC_PC_FF_L4PSRC 0x1f
34178 +#define CC_PC_FF_L4PDST 0x20
34179 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
34180 +
34181 +#define CC_PC_FF_PPPPID 0x05
34182 +
34183 +#define CC_PC_PR_SHIM1 0x22
34184 +#define CC_PC_PR_SHIM2 0x23
34185 +
34186 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
34187 +#define CC_PC_GENERIC_WITH_MASK 0x28
34188 +#define CC_PC_GENERIC_IC_GMASK 0x2B
34189 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
34190 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
34191 +
34192 +#define CC_PR_OFFSET 0x25
34193 +#define CC_PR_WITHOUT_OFFSET 0x26
34194 +
34195 +#define CC_PC_PR_ETH_OFFSET 19
34196 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
34197 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
34198 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
34199 +#define CC_PC_PR_VLAN1_OFFSET 21
34200 +#define CC_PC_PR_VLAN2_OFFSET 22
34201 +#define CC_PC_PR_PPPOE_OFFSET 24
34202 +#define CC_PC_PR_MPLS1_OFFSET 25
34203 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
34204 +#define CC_PC_PR_IP1_OFFSET 27
34205 +#define CC_PC_PR_IP_LAST_OFFSET 28
34206 +#define CC_PC_PR_MINENC_OFFSET 28
34207 +#define CC_PC_PR_L4_OFFSET 30
34208 +#define CC_PC_PR_GRE_OFFSET 29
34209 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
34210 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
34211 +
34212 +#define CC_PC_ILLEGAL 0xff
34213 +#define CC_SIZE_ILLEGAL 0
34214 +
34215 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
34216 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
34217 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
34218 +#define FM_PCD_CC_NUM_OF_KEYS 255
34219 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
34220 +
34221 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
34222 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
34223 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
34224 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
34225 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
34226 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
34227 +
34228 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
34229 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
34230 +
34231 +#define FM_PCD_AD_STATS_TYPE 0x40000000
34232 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
34233 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
34234 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
34235 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
34236 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
34237 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
34238 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
34239 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
34240 +
34241 +
34242 +
34243 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
34244 +
34245 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
34246 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
34247 +
34248 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
34249 +#if (DPAA_VERSION >= 11)
34250 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
34251 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
34252 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
34253 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
34254 +#endif /* (DPAA_VERSION >= 11) */
34255 +
34256 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
34257 +#define CC_GLBL_MASK_SIZE 4
34258 +#define CC_AGING_MASK_SIZE 4
34259 +
34260 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
34261 +
34262 +#define CC_PRIVATE_INFO_NONE 0
34263 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
34264 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
34265 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
34266 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
34267 +
34268 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
34269 +/***********************************************************************/
34270 +/* Memory map */
34271 +/***********************************************************************/
34272 +#if defined(__MWERKS__) && !defined(__GNUC__)
34273 +#pragma pack(push,1)
34274 +#endif /* defined(__MWERKS__) && ... */
34275 +
34276 +typedef struct
34277 +{
34278 + volatile uint32_t fqid;
34279 + volatile uint32_t plcrProfile;
34280 + volatile uint32_t nia;
34281 + volatile uint32_t res;
34282 +} t_AdOfTypeResult;
34283 +
34284 +typedef struct
34285 +{
34286 + volatile uint32_t ccAdBase;
34287 + volatile uint32_t matchTblPtr;
34288 + volatile uint32_t pcAndOffsets;
34289 + volatile uint32_t gmask;
34290 +} t_AdOfTypeContLookup;
34291 +
34292 +typedef struct
34293 +{
34294 + volatile uint32_t profileTableAddr;
34295 + volatile uint32_t reserved;
34296 + volatile uint32_t nextActionIndx;
34297 + volatile uint32_t statsTableAddr;
34298 +} t_AdOfTypeStats;
34299 +
34300 +typedef union
34301 +{
34302 + volatile t_AdOfTypeResult adResult;
34303 + volatile t_AdOfTypeContLookup adContLookup;
34304 +} t_Ad;
34305 +
34306 +#if defined(__MWERKS__) && !defined(__GNUC__)
34307 +#pragma pack(pop)
34308 +#endif /* defined(__MWERKS__) && ... */
34309 +
34310 +
34311 +/***********************************************************************/
34312 +/* Driver's internal structures */
34313 +/***********************************************************************/
34314 +
34315 +typedef struct t_FmPcdStatsObj
34316 +{
34317 + t_Handle h_StatsAd;
34318 + t_Handle h_StatsCounters;
34319 + t_List node;
34320 +} t_FmPcdStatsObj;
34321 +
34322 +typedef struct
34323 +{
34324 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
34325 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
34326 +
34327 + t_FmPcdCcNextEngineParams nextEngineParams;
34328 + uint32_t requiredAction;
34329 + uint32_t shadowAction;
34330 +
34331 + t_FmPcdStatsObj *p_StatsObj;
34332 +
34333 +} t_FmPcdCcKeyAndNextEngineParams;
34334 +
34335 +typedef struct
34336 +{
34337 + t_Handle p_Ad;
34338 + e_FmPcdEngine fmPcdEngine;
34339 + bool adAllocated;
34340 + bool isTree;
34341 +
34342 + uint32_t myInfo;
34343 + t_List *h_CcNextNodesLst;
34344 + t_Handle h_AdditionalInfo;
34345 + t_Handle h_Node;
34346 +} t_FmPcdModifyCcAdditionalParams;
34347 +
34348 +typedef struct
34349 +{
34350 + t_Handle p_AdTableNew;
34351 + t_Handle p_KeysMatchTableNew;
34352 + t_Handle p_AdTableOld;
34353 + t_Handle p_KeysMatchTableOld;
34354 + uint16_t numOfKeys;
34355 + t_Handle h_CurrentNode;
34356 + uint16_t savedKeyIndex;
34357 + t_Handle h_NodeForAdd;
34358 + t_Handle h_NodeForRmv;
34359 + t_Handle h_ManipForRmv;
34360 + t_Handle h_ManipForAdd;
34361 + t_FmPcdStatsObj *p_StatsObjForRmv;
34362 +#if (DPAA_VERSION >= 11)
34363 + t_Handle h_FrmReplicForAdd;
34364 + t_Handle h_FrmReplicForRmv;
34365 +#endif /* (DPAA_VERSION >= 11) */
34366 + bool tree;
34367 +
34368 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34369 +} t_FmPcdModifyCcKeyAdditionalParams;
34370 +
34371 +typedef struct
34372 +{
34373 + t_Handle h_Manip;
34374 + t_Handle h_CcNode;
34375 +} t_CcNextEngineInfo;
34376 +
34377 +typedef struct
34378 +{
34379 + uint16_t numOfKeys;
34380 + uint16_t maxNumOfKeys;
34381 +
34382 + bool maskSupport;
34383 + uint32_t keysMatchTableMaxSize;
34384 +
34385 + e_FmPcdCcStatsMode statisticsMode;
34386 + uint32_t numOfStatsFLRs;
34387 + uint32_t countersArraySize;
34388 +
34389 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
34390 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
34391 + Holds the statistics counters allocated by the hash table and
34392 + are shared by all hash table buckets; */
34393 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
34394 + Holds the statistics counters that were allocated for this node
34395 + and replaced by the shared counters (allocated by the hash table); */
34396 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
34397 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
34398 + returned statistics count to user, statistics AD always present for 'miss'
34399 + for all hash buckets; */
34400 + bool glblMaskUpdated;
34401 + t_Handle p_GlblMask;
34402 + bool lclMask;
34403 + uint8_t parseCode;
34404 + uint8_t offset;
34405 + uint8_t prsArrayOffset;
34406 + bool ctrlFlow;
34407 + uint16_t owners;
34408 +
34409 + uint8_t ccKeySizeAccExtraction;
34410 + uint8_t sizeOfExtraction;
34411 + uint8_t glblMaskSize;
34412 +
34413 + t_Handle h_KeysMatchTable;
34414 + t_Handle h_AdTable;
34415 + t_Handle h_StatsAds;
34416 + t_Handle h_TmpAd;
34417 + t_Handle h_Ad;
34418 + t_Handle h_StatsFLRs;
34419 +
34420 + t_List availableStatsLst;
34421 +
34422 + t_List ccPrevNodesLst;
34423 +
34424 + t_List ccTreeIdLst;
34425 + t_List ccTreesLst;
34426 +
34427 + t_Handle h_FmPcd;
34428 + uint32_t shadowAction;
34429 + uint8_t userSizeOfExtraction;
34430 + uint8_t userOffset;
34431 + uint8_t kgHashShift; /* used in hash-table */
34432 +
34433 + t_Handle h_Spinlock;
34434 +
34435 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
34436 +} t_FmPcdCcNode;
34437 +
34438 +typedef struct
34439 +{
34440 + t_FmPcdCcNode *p_FmPcdCcNode;
34441 + bool occupied;
34442 + uint16_t owners;
34443 + volatile bool lock;
34444 +} t_FmPcdCcNodeArray;
34445 +
34446 +typedef struct
34447 +{
34448 + uint8_t numOfEntriesInGroup;
34449 + uint32_t totalBitsMask;
34450 + uint8_t baseGroupEntry;
34451 +} t_FmPcdCcGroupParam;
34452 +
34453 +typedef struct
34454 +{
34455 + t_Handle h_FmPcd;
34456 + uint8_t netEnvId;
34457 + uintptr_t ccTreeBaseAddr;
34458 + uint8_t numOfGrps;
34459 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34460 + t_List fmPortsLst;
34461 + t_FmPcdLock *p_Lock;
34462 + uint8_t numOfEntries;
34463 + uint16_t owners;
34464 + t_Handle h_FmPcdCcSavedManipParams;
34465 + bool modifiedState;
34466 + uint32_t requiredAction;
34467 + t_Handle h_IpReassemblyManip;
34468 + t_Handle h_CapwapReassemblyManip;
34469 +
34470 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
34471 +} t_FmPcdCcTree;
34472 +
34473 +
34474 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
34475 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
34476 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
34477 +
34478 +
34479 +#endif /* __FM_CC_H */
34480 --- /dev/null
34481 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
34482 @@ -0,0 +1,3242 @@
34483 +/*
34484 + * Copyright 2008-2012 Freescale Semiconductor Inc.
34485 + *
34486 + * Redistribution and use in source and binary forms, with or without
34487 + * modification, are permitted provided that the following conditions are met:
34488 + * * Redistributions of source code must retain the above copyright
34489 + * notice, this list of conditions and the following disclaimer.
34490 + * * Redistributions in binary form must reproduce the above copyright
34491 + * notice, this list of conditions and the following disclaimer in the
34492 + * documentation and/or other materials provided with the distribution.
34493 + * * Neither the name of Freescale Semiconductor nor the
34494 + * names of its contributors may be used to endorse or promote products
34495 + * derived from this software without specific prior written permission.
34496 + *
34497 + *
34498 + * ALTERNATIVELY, this software may be distributed under the terms of the
34499 + * GNU General Public License ("GPL") as published by the Free Software
34500 + * Foundation, either version 2 of that License or (at your option) any
34501 + * later version.
34502 + *
34503 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
34504 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34505 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34506 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
34507 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34508 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
34509 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34510 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34511 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34512 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34513 + */
34514 +
34515 +
34516 +/******************************************************************************
34517 + @File fm_kg.c
34518 +
34519 + @Description FM PCD ...
34520 +*//***************************************************************************/
34521 +#include "std_ext.h"
34522 +#include "error_ext.h"
34523 +#include "string_ext.h"
34524 +#include "debug_ext.h"
34525 +#include "net_ext.h"
34526 +#include "fm_port_ext.h"
34527 +
34528 +#include "fm_common.h"
34529 +#include "fm_pcd.h"
34530 +#include "fm_hc.h"
34531 +#include "fm_pcd_ipc.h"
34532 +#include "fm_kg.h"
34533 +#include "fsl_fman_kg.h"
34534 +
34535 +
34536 +/****************************************/
34537 +/* static functions */
34538 +/****************************************/
34539 +
34540 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
34541 +{
34542 + ASSERT_COND(h_FmPcdKg);
34543 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
34544 +}
34545 +
34546 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
34547 +{
34548 + ASSERT_COND(h_FmPcdKg);
34549 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
34550 +}
34551 +
34552 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
34553 +{
34554 + ASSERT_COND(h_Scheme);
34555 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34556 +}
34557 +
34558 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
34559 +{
34560 + ASSERT_COND(h_Scheme);
34561 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
34562 +}
34563 +
34564 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
34565 +{
34566 + ASSERT_COND(h_Scheme);
34567 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34568 +}
34569 +
34570 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
34571 +{
34572 + ASSERT_COND(h_Scheme);
34573 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
34574 +}
34575 +
34576 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
34577 +{
34578 +
34579 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
34580 +
34581 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
34582 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
34583 +
34584 + return E_OK;
34585 +}
34586 +
34587 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
34588 +{
34589 + int i;
34590 +
34591 + switch (code)
34592 + {
34593 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
34594 + case (KG_SCH_GEN_DEFAULT):
34595 + case (KG_SCH_GEN_NEXTHDR):
34596 + for (i=0 ; i<numOfSwDefaults ; i++)
34597 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
34598 + return swDefaults[i].dfltSelect;
34599 + break;
34600 + case (KG_SCH_GEN_SHIM1):
34601 + case (KG_SCH_GEN_SHIM2):
34602 + case (KG_SCH_GEN_IP_PID_NO_V):
34603 + case (KG_SCH_GEN_ETH_NO_V):
34604 + case (KG_SCH_GEN_SNAP_NO_V):
34605 + case (KG_SCH_GEN_VLAN1_NO_V):
34606 + case (KG_SCH_GEN_VLAN2_NO_V):
34607 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
34608 + case (KG_SCH_GEN_PPP_NO_V):
34609 + case (KG_SCH_GEN_MPLS1_NO_V):
34610 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
34611 + case (KG_SCH_GEN_L3_NO_V):
34612 + case (KG_SCH_GEN_IP2_NO_V):
34613 + case (KG_SCH_GEN_GRE_NO_V):
34614 + case (KG_SCH_GEN_L4_NO_V):
34615 + for (i=0 ; i<numOfSwDefaults ; i++)
34616 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
34617 + return swDefaults[i].dfltSelect;
34618 + break;
34619 + case (KG_SCH_GEN_START_OF_FRM):
34620 + case (KG_SCH_GEN_ETH):
34621 + case (KG_SCH_GEN_SNAP):
34622 + case (KG_SCH_GEN_VLAN1):
34623 + case (KG_SCH_GEN_VLAN2):
34624 + case (KG_SCH_GEN_ETH_TYPE):
34625 + case (KG_SCH_GEN_PPP):
34626 + case (KG_SCH_GEN_MPLS1):
34627 + case (KG_SCH_GEN_MPLS2):
34628 + case (KG_SCH_GEN_MPLS3):
34629 + case (KG_SCH_GEN_MPLS_LAST):
34630 + case (KG_SCH_GEN_IPV4):
34631 + case (KG_SCH_GEN_IPV6):
34632 + case (KG_SCH_GEN_IPV4_TUNNELED):
34633 + case (KG_SCH_GEN_IPV6_TUNNELED):
34634 + case (KG_SCH_GEN_MIN_ENCAP):
34635 + case (KG_SCH_GEN_GRE):
34636 + case (KG_SCH_GEN_TCP):
34637 + case (KG_SCH_GEN_UDP):
34638 + case (KG_SCH_GEN_IPSEC_AH):
34639 + case (KG_SCH_GEN_SCTP):
34640 + case (KG_SCH_GEN_DCCP):
34641 + case (KG_SCH_GEN_IPSEC_ESP):
34642 + for (i=0 ; i<numOfSwDefaults ; i++)
34643 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
34644 + return swDefaults[i].dfltSelect;
34645 + break;
34646 + default:
34647 + break;
34648 + }
34649 +
34650 + return e_FM_PCD_KG_DFLT_ILLEGAL;
34651 +}
34652 +
34653 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
34654 +{
34655 + *p_Offset = 0;
34656 +
34657 + switch (src)
34658 + {
34659 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
34660 + return KG_SCH_GEN_START_OF_FRM;
34661 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
34662 + return KG_SCH_GEN_DEFAULT;
34663 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
34664 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34665 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
34666 + *p_Offset = 32;
34667 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
34668 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
34669 + return KG_SCH_GEN_NEXTHDR;
34670 + default:
34671 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
34672 + return 0;
34673 + }
34674 +}
34675 +
34676 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
34677 +{
34678 + if (!ignoreProtocolValidation)
34679 + switch (hdr)
34680 + {
34681 + case (HEADER_TYPE_NONE):
34682 + ASSERT_COND(FALSE);
34683 + case (HEADER_TYPE_ETH):
34684 + return KG_SCH_GEN_ETH;
34685 + case (HEADER_TYPE_LLC_SNAP):
34686 + return KG_SCH_GEN_SNAP;
34687 + case (HEADER_TYPE_PPPoE):
34688 + return KG_SCH_GEN_PPP;
34689 + case (HEADER_TYPE_MPLS):
34690 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34691 + return KG_SCH_GEN_MPLS1;
34692 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
34693 + return KG_SCH_GEN_MPLS2;
34694 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
34695 + return KG_SCH_GEN_MPLS3;
34696 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34697 + return KG_SCH_GEN_MPLS_LAST;
34698 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34699 + return 0;
34700 + case (HEADER_TYPE_IPv4):
34701 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34702 + return KG_SCH_GEN_IPV4;
34703 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34704 + return KG_SCH_GEN_IPV4_TUNNELED;
34705 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
34706 + return 0;
34707 + case (HEADER_TYPE_IPv6):
34708 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34709 + return KG_SCH_GEN_IPV6;
34710 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34711 + return KG_SCH_GEN_IPV6_TUNNELED;
34712 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
34713 + return 0;
34714 + case (HEADER_TYPE_GRE):
34715 + return KG_SCH_GEN_GRE;
34716 + case (HEADER_TYPE_TCP):
34717 + return KG_SCH_GEN_TCP;
34718 + case (HEADER_TYPE_UDP):
34719 + return KG_SCH_GEN_UDP;
34720 + case (HEADER_TYPE_IPSEC_AH):
34721 + return KG_SCH_GEN_IPSEC_AH;
34722 + case (HEADER_TYPE_IPSEC_ESP):
34723 + return KG_SCH_GEN_IPSEC_ESP;
34724 + case (HEADER_TYPE_SCTP):
34725 + return KG_SCH_GEN_SCTP;
34726 + case (HEADER_TYPE_DCCP):
34727 + return KG_SCH_GEN_DCCP;
34728 + default:
34729 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34730 + return 0;
34731 + }
34732 + else
34733 + switch (hdr)
34734 + {
34735 + case (HEADER_TYPE_NONE):
34736 + ASSERT_COND(FALSE);
34737 + case (HEADER_TYPE_ETH):
34738 + return KG_SCH_GEN_ETH_NO_V;
34739 + case (HEADER_TYPE_LLC_SNAP):
34740 + return KG_SCH_GEN_SNAP_NO_V;
34741 + case (HEADER_TYPE_PPPoE):
34742 + return KG_SCH_GEN_PPP_NO_V;
34743 + case (HEADER_TYPE_MPLS):
34744 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34745 + return KG_SCH_GEN_MPLS1_NO_V;
34746 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34747 + return KG_SCH_GEN_MPLS_LAST_NO_V;
34748 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
34749 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
34750 + else
34751 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
34752 + return 0;
34753 + case (HEADER_TYPE_IPv4):
34754 + case (HEADER_TYPE_IPv6):
34755 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34756 + return KG_SCH_GEN_L3_NO_V;
34757 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
34758 + return KG_SCH_GEN_IP2_NO_V;
34759 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
34760 + case (HEADER_TYPE_MINENCAP):
34761 + return KG_SCH_GEN_IP2_NO_V;
34762 + case (HEADER_TYPE_USER_DEFINED_L3):
34763 + return KG_SCH_GEN_L3_NO_V;
34764 + case (HEADER_TYPE_GRE):
34765 + return KG_SCH_GEN_GRE_NO_V;
34766 + case (HEADER_TYPE_TCP):
34767 + case (HEADER_TYPE_UDP):
34768 + case (HEADER_TYPE_IPSEC_AH):
34769 + case (HEADER_TYPE_IPSEC_ESP):
34770 + case (HEADER_TYPE_SCTP):
34771 + case (HEADER_TYPE_DCCP):
34772 + return KG_SCH_GEN_L4_NO_V;
34773 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
34774 + return KG_SCH_GEN_SHIM1;
34775 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
34776 + return KG_SCH_GEN_SHIM2;
34777 + default:
34778 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34779 + return 0;
34780 + }
34781 +}
34782 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
34783 +{
34784 + if (!ignoreProtocolValidation)
34785 + switch (hdr)
34786 + {
34787 + case (HEADER_TYPE_NONE):
34788 + ASSERT_COND(FALSE);
34789 + break;
34790 + case (HEADER_TYPE_ETH):
34791 + switch (field.eth)
34792 + {
34793 + case (NET_HEADER_FIELD_ETH_TYPE):
34794 + return KG_SCH_GEN_ETH_TYPE;
34795 + default:
34796 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34797 + return 0;
34798 + }
34799 + break;
34800 + case (HEADER_TYPE_VLAN):
34801 + switch (field.vlan)
34802 + {
34803 + case (NET_HEADER_FIELD_VLAN_TCI):
34804 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34805 + return KG_SCH_GEN_VLAN1;
34806 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34807 + return KG_SCH_GEN_VLAN2;
34808 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34809 + return 0;
34810 + }
34811 + break;
34812 + case (HEADER_TYPE_MPLS):
34813 + case (HEADER_TYPE_IPSEC_AH):
34814 + case (HEADER_TYPE_IPSEC_ESP):
34815 + case (HEADER_TYPE_LLC_SNAP):
34816 + case (HEADER_TYPE_PPPoE):
34817 + case (HEADER_TYPE_IPv4):
34818 + case (HEADER_TYPE_IPv6):
34819 + case (HEADER_TYPE_GRE):
34820 + case (HEADER_TYPE_MINENCAP):
34821 + case (HEADER_TYPE_USER_DEFINED_L3):
34822 + case (HEADER_TYPE_TCP):
34823 + case (HEADER_TYPE_UDP):
34824 + case (HEADER_TYPE_SCTP):
34825 + case (HEADER_TYPE_DCCP):
34826 + case (HEADER_TYPE_USER_DEFINED_L4):
34827 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34828 + return 0;
34829 + default:
34830 + break;
34831 +
34832 + }
34833 + else
34834 + switch (hdr)
34835 + {
34836 + case (HEADER_TYPE_NONE):
34837 + ASSERT_COND(FALSE);
34838 + break;
34839 + case (HEADER_TYPE_ETH):
34840 + switch (field.eth)
34841 + {
34842 + case (NET_HEADER_FIELD_ETH_TYPE):
34843 + return KG_SCH_GEN_ETH_TYPE_NO_V;
34844 + default:
34845 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34846 + return 0;
34847 + }
34848 + break;
34849 + case (HEADER_TYPE_VLAN):
34850 + switch (field.vlan)
34851 + {
34852 + case (NET_HEADER_FIELD_VLAN_TCI) :
34853 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
34854 + return KG_SCH_GEN_VLAN1_NO_V;
34855 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
34856 + return KG_SCH_GEN_VLAN2_NO_V;
34857 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
34858 + return 0;
34859 + }
34860 + break;
34861 + case (HEADER_TYPE_IPv4):
34862 + switch (field.ipv4)
34863 + {
34864 + case (NET_HEADER_FIELD_IPv4_PROTO):
34865 + return KG_SCH_GEN_IP_PID_NO_V;
34866 + default:
34867 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34868 + return 0;
34869 + }
34870 + break;
34871 + case (HEADER_TYPE_IPv6):
34872 + switch (field.ipv6)
34873 + {
34874 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
34875 + return KG_SCH_GEN_IP_PID_NO_V;
34876 + default:
34877 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34878 + return 0;
34879 + }
34880 + break;
34881 + case (HEADER_TYPE_MPLS):
34882 + case (HEADER_TYPE_LLC_SNAP):
34883 + case (HEADER_TYPE_PPPoE):
34884 + case (HEADER_TYPE_GRE):
34885 + case (HEADER_TYPE_MINENCAP):
34886 + case (HEADER_TYPE_USER_DEFINED_L3):
34887 + case (HEADER_TYPE_TCP):
34888 + case (HEADER_TYPE_UDP):
34889 + case (HEADER_TYPE_IPSEC_AH):
34890 + case (HEADER_TYPE_IPSEC_ESP):
34891 + case (HEADER_TYPE_SCTP):
34892 + case (HEADER_TYPE_DCCP):
34893 + case (HEADER_TYPE_USER_DEFINED_L4):
34894 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34895 + return 0;
34896 + default:
34897 + break;
34898 + }
34899 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
34900 + return 0;
34901 +}
34902 +
34903 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
34904 +{
34905 + UNUSED(p_FmPcd);
34906 +
34907 + switch (hdr)
34908 + {
34909 + case (HEADER_TYPE_NONE):
34910 + ASSERT_COND(FALSE);
34911 + break;
34912 + case (HEADER_TYPE_ETH):
34913 + switch (field.eth)
34914 + {
34915 + case (NET_HEADER_FIELD_ETH_DA):
34916 + return KG_SCH_KN_MACDST;
34917 + case (NET_HEADER_FIELD_ETH_SA):
34918 + return KG_SCH_KN_MACSRC;
34919 + case (NET_HEADER_FIELD_ETH_TYPE):
34920 + return KG_SCH_KN_ETYPE;
34921 + default:
34922 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34923 + return 0;
34924 + }
34925 + case (HEADER_TYPE_LLC_SNAP):
34926 + switch (field.llcSnap)
34927 + {
34928 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
34929 + return KG_SCH_KN_ETYPE;
34930 + default:
34931 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34932 + return 0;
34933 + }
34934 + case (HEADER_TYPE_VLAN):
34935 + switch (field.vlan)
34936 + {
34937 + case (NET_HEADER_FIELD_VLAN_TCI):
34938 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34939 + return KG_SCH_KN_TCI1;
34940 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34941 + return KG_SCH_KN_TCI2;
34942 + else
34943 + {
34944 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34945 + return 0;
34946 + }
34947 + default:
34948 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34949 + return 0;
34950 + }
34951 + case (HEADER_TYPE_MPLS):
34952 + switch (field.mpls)
34953 + {
34954 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
34955 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34956 + return KG_SCH_KN_MPLS1;
34957 + if (index == e_FM_PCD_HDR_INDEX_2)
34958 + return KG_SCH_KN_MPLS2;
34959 + if (index == e_FM_PCD_HDR_INDEX_LAST)
34960 + return KG_SCH_KN_MPLS_LAST;
34961 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
34962 + return 0;
34963 + default:
34964 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
34965 + return 0;
34966 + }
34967 + case (HEADER_TYPE_IPv4):
34968 + switch (field.ipv4)
34969 + {
34970 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
34971 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34972 + return KG_SCH_KN_IPSRC1;
34973 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34974 + return KG_SCH_KN_IPSRC2;
34975 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34976 + return 0;
34977 + case (NET_HEADER_FIELD_IPv4_DST_IP):
34978 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34979 + return KG_SCH_KN_IPDST1;
34980 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34981 + return KG_SCH_KN_IPDST2;
34982 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34983 + return 0;
34984 + case (NET_HEADER_FIELD_IPv4_PROTO):
34985 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34986 + return KG_SCH_KN_PTYPE1;
34987 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34988 + return KG_SCH_KN_PTYPE2;
34989 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34990 + return 0;
34991 + case (NET_HEADER_FIELD_IPv4_TOS):
34992 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
34993 + return KG_SCH_KN_IPTOS_TC1;
34994 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
34995 + return KG_SCH_KN_IPTOS_TC2;
34996 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
34997 + return 0;
34998 + default:
34999 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35000 + return 0;
35001 + }
35002 + case (HEADER_TYPE_IPv6):
35003 + switch (field.ipv6)
35004 + {
35005 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
35006 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35007 + return KG_SCH_KN_IPSRC1;
35008 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35009 + return KG_SCH_KN_IPSRC2;
35010 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35011 + return 0;
35012 + case (NET_HEADER_FIELD_IPv6_DST_IP):
35013 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35014 + return KG_SCH_KN_IPDST1;
35015 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35016 + return KG_SCH_KN_IPDST2;
35017 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35018 + return 0;
35019 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
35020 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35021 + return KG_SCH_KN_PTYPE1;
35022 + if (index == e_FM_PCD_HDR_INDEX_2)
35023 + return KG_SCH_KN_PTYPE2;
35024 + if (index == e_FM_PCD_HDR_INDEX_LAST)
35025 +#ifdef FM_KG_NO_IPPID_SUPPORT
35026 + if (p_FmPcd->fmRevInfo.majorRev < 6)
35027 + return KG_SCH_KN_PTYPE2;
35028 +#endif /* FM_KG_NO_IPPID_SUPPORT */
35029 + return KG_SCH_KN_IPPID;
35030 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35031 + return 0;
35032 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
35033 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35034 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
35035 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35036 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
35037 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35038 + return 0;
35039 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
35040 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35041 + return KG_SCH_KN_IPTOS_TC1;
35042 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35043 + return KG_SCH_KN_IPTOS_TC2;
35044 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35045 + return 0;
35046 + case (NET_HEADER_FIELD_IPv6_FL):
35047 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
35048 + return KG_SCH_KN_IPV6FL1;
35049 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
35050 + return KG_SCH_KN_IPV6FL2;
35051 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
35052 + return 0;
35053 + default:
35054 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35055 + return 0;
35056 + }
35057 + case (HEADER_TYPE_GRE):
35058 + switch (field.gre)
35059 + {
35060 + case (NET_HEADER_FIELD_GRE_TYPE):
35061 + return KG_SCH_KN_GREPTYPE;
35062 + default:
35063 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35064 + return 0;
35065 + }
35066 + case (HEADER_TYPE_MINENCAP):
35067 + switch (field.minencap)
35068 + {
35069 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
35070 + return KG_SCH_KN_IPSRC2;
35071 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
35072 + return KG_SCH_KN_IPDST2;
35073 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
35074 + return KG_SCH_KN_PTYPE2;
35075 + default:
35076 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35077 + return 0;
35078 + }
35079 + case (HEADER_TYPE_TCP):
35080 + switch (field.tcp)
35081 + {
35082 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
35083 + return KG_SCH_KN_L4PSRC;
35084 + case (NET_HEADER_FIELD_TCP_PORT_DST):
35085 + return KG_SCH_KN_L4PDST;
35086 + case (NET_HEADER_FIELD_TCP_FLAGS):
35087 + return KG_SCH_KN_TFLG;
35088 + default:
35089 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35090 + return 0;
35091 + }
35092 + case (HEADER_TYPE_UDP):
35093 + switch (field.udp)
35094 + {
35095 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
35096 + return KG_SCH_KN_L4PSRC;
35097 + case (NET_HEADER_FIELD_UDP_PORT_DST):
35098 + return KG_SCH_KN_L4PDST;
35099 + default:
35100 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35101 + return 0;
35102 + }
35103 + case (HEADER_TYPE_IPSEC_AH):
35104 + switch (field.ipsecAh)
35105 + {
35106 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
35107 + return KG_SCH_KN_IPSEC_SPI;
35108 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
35109 + return KG_SCH_KN_IPSEC_NH;
35110 + default:
35111 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35112 + return 0;
35113 + }
35114 + case (HEADER_TYPE_IPSEC_ESP):
35115 + switch (field.ipsecEsp)
35116 + {
35117 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
35118 + return KG_SCH_KN_IPSEC_SPI;
35119 + default:
35120 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35121 + return 0;
35122 + }
35123 + case (HEADER_TYPE_SCTP):
35124 + switch (field.sctp)
35125 + {
35126 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
35127 + return KG_SCH_KN_L4PSRC;
35128 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
35129 + return KG_SCH_KN_L4PDST;
35130 + default:
35131 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35132 + return 0;
35133 + }
35134 + case (HEADER_TYPE_DCCP):
35135 + switch (field.dccp)
35136 + {
35137 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
35138 + return KG_SCH_KN_L4PSRC;
35139 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
35140 + return KG_SCH_KN_L4PDST;
35141 + default:
35142 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35143 + return 0;
35144 + }
35145 + case (HEADER_TYPE_PPPoE):
35146 + switch (field.pppoe)
35147 + {
35148 + case (NET_HEADER_FIELD_PPPoE_PID):
35149 + return KG_SCH_KN_PPPID;
35150 + case (NET_HEADER_FIELD_PPPoE_SID):
35151 + return KG_SCH_KN_PPPSID;
35152 + default:
35153 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35154 + return 0;
35155 + }
35156 + default:
35157 + break;
35158 +
35159 + }
35160 +
35161 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
35162 + return 0;
35163 +}
35164 +
35165 +
35166 +static uint8_t GetKnownFieldId(uint32_t bitMask)
35167 +{
35168 + uint8_t cnt = 0;
35169 +
35170 + while (bitMask)
35171 + if (bitMask & 0x80000000)
35172 + break;
35173 + else
35174 + {
35175 + cnt++;
35176 + bitMask <<= 1;
35177 + }
35178 + return cnt;
35179 +
35180 +}
35181 +
35182 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
35183 +{
35184 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
35185 +
35186 + /* bitOffset 1-7 --> mask 0x1-0x7F */
35187 + if (bitOffset<8)
35188 + {
35189 + mask = 0;
35190 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
35191 + mask |= walking1Mask;
35192 + }
35193 + else
35194 + {
35195 + mask = 0xFF;
35196 + numOfOnesToClear = 0;
35197 + if (fqid && bitOffset>24)
35198 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
35199 + numOfOnesToClear = (uint8_t)(bitOffset-24);
35200 + else
35201 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
35202 + if (!fqid && bitOffset>8)
35203 + numOfOnesToClear = (uint8_t)(bitOffset-8);
35204 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
35205 + mask &= ~walking1Mask;
35206 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
35207 + }
35208 + return mask;
35209 +}
35210 +
35211 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35212 +{
35213 + t_FmPcdKg *p_FmPcdKg;
35214 + t_FmPcdKgScheme *p_Scheme;
35215 + uint32_t intFlags;
35216 + uint8_t relativeSchemeId;
35217 + int i;
35218 +
35219 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35220 +
35221 + /* for each scheme - update owners counters */
35222 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35223 + {
35224 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35225 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35226 +
35227 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35228 +
35229 + /* increment owners number */
35230 + intFlags = KgSchemeLock(p_Scheme);
35231 + p_Scheme->owners++;
35232 + KgSchemeUnlock(p_Scheme, intFlags);
35233 + }
35234 +}
35235 +
35236 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
35237 +{
35238 + t_FmPcdKg *p_FmPcdKg;
35239 + t_FmPcdKgScheme *p_Scheme;
35240 + uint32_t intFlags;
35241 + uint8_t relativeSchemeId;
35242 + int i;
35243 +
35244 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
35245 +
35246 + /* for each scheme - update owners counters */
35247 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
35248 + {
35249 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
35250 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
35251 +
35252 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
35253 +
35254 + /* increment owners number */
35255 + ASSERT_COND(p_Scheme->owners);
35256 + intFlags = KgSchemeLock(p_Scheme);
35257 + p_Scheme->owners--;
35258 + KgSchemeUnlock(p_Scheme, intFlags);
35259 + }
35260 +}
35261 +
35262 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
35263 +{
35264 + /* this routine is locked by the calling routine */
35265 + ASSERT_COND(p_Scheme);
35266 + ASSERT_COND(p_Scheme->valid);
35267 +
35268 + if (set)
35269 + p_Scheme->requiredActionFlag = TRUE;
35270 + else
35271 + {
35272 + p_Scheme->requiredAction = 0;
35273 + p_Scheme->requiredActionFlag = FALSE;
35274 + }
35275 +}
35276 +
35277 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
35278 +{
35279 + struct fman_kg_regs *p_KgRegs;
35280 +
35281 + uint32_t tmpKgarReg = 0, intFlags;
35282 + t_Error err = E_OK;
35283 +
35284 + /* The calling routine had locked the port, so for each port only one core can access
35285 + * (so we don't need a lock here) */
35286 +
35287 + if (p_FmPcd->h_Hc)
35288 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
35289 +
35290 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35291 +
35292 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
35293 + /* lock a common KG reg */
35294 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35295 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35296 + if (err)
35297 + {
35298 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35299 + RETURN_ERROR(MINOR, err, NO_MSG);
35300 + }
35301 +
35302 + fman_kg_write_sp(p_KgRegs, spReg, add);
35303 +
35304 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
35305 +
35306 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35307 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35308 + return err;
35309 +}
35310 +
35311 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
35312 +{
35313 + struct fman_kg_regs *p_KgRegs;
35314 + uint32_t tmpKgarReg, intFlags;
35315 + t_Error err;
35316 +
35317 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35318 +
35319 + if (p_FmPcd->h_Hc)
35320 + {
35321 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
35322 + return err;
35323 + }
35324 +
35325 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
35326 + fman_kg_write_cpp(p_KgRegs, cppReg);
35327 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
35328 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
35329 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
35330 +
35331 + return err;
35332 +}
35333 +
35334 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
35335 +{
35336 + uint32_t tmpKgpeCpp;
35337 +
35338 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
35339 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
35340 +
35341 + return tmpKgpeCpp;
35342 +}
35343 +
35344 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
35345 +{
35346 + uint32_t tmpKgpeCpp = 0;
35347 +
35348 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
35349 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
35350 +}
35351 +
35352 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
35353 +{
35354 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
35355 +}
35356 +
35357 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
35358 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
35359 +{
35360 + return (uint32_t)(FM_KG_KGAR_GO |
35361 + FM_KG_KGAR_READ |
35362 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
35363 + DUMMY_PORT_ID |
35364 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
35365 + FM_PCD_KG_KGAR_WSEL_MASK);
35366 +
35367 + /* if we ever want to write 1 by 1, use:
35368 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
35369 + */
35370 +}
35371 +#endif /* (defined(DEBUG_ERRORS) && ... */
35372 +
35373 +static void PcdKgErrorException(t_Handle h_FmPcd)
35374 +{
35375 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
35376 + uint32_t event,schemeIndexes = 0, index = 0;
35377 + struct fman_kg_regs *p_KgRegs;
35378 +
35379 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
35380 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35381 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
35382 +
35383 + if (event & FM_EX_KG_DOUBLE_ECC)
35384 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
35385 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
35386 + {
35387 + if (schemeIndexes)
35388 + {
35389 + while (schemeIndexes)
35390 + {
35391 + if (schemeIndexes & 0x1)
35392 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
35393 + schemeIndexes >>= 1;
35394 + index+=1;
35395 + }
35396 + }
35397 + else /* this should happen only when interrupt is forced. */
35398 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
35399 + }
35400 +}
35401 +
35402 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
35403 +{
35404 + t_Error err = E_OK;
35405 + t_FmPcdIpcKgSchemesParams kgAlloc;
35406 + uint32_t replyLength;
35407 + t_FmPcdIpcReply reply;
35408 + t_FmPcdIpcMsg msg;
35409 +
35410 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
35411 +
35412 + /* in GUEST_PARTITION, we use the IPC */
35413 + memset(&reply, 0, sizeof(reply));
35414 + memset(&msg, 0, sizeof(msg));
35415 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
35416 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
35417 + kgAlloc.guestId = p_FmPcd->guestId;
35418 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
35419 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
35420 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
35421 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
35422 + (uint8_t*)&msg,
35423 + sizeof(msg.msgId) + sizeof(kgAlloc),
35424 + (uint8_t*)&reply,
35425 + &replyLength,
35426 + NULL,
35427 + NULL)) != E_OK)
35428 + RETURN_ERROR(MAJOR, err, NO_MSG);
35429 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
35430 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
35431 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
35432 +
35433 + return (t_Error)reply.error;
35434 +}
35435 +
35436 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
35437 +{
35438 + t_Error err = E_OK;
35439 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
35440 +
35441 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
35442 +
35443 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
35444 + FmEnableRamsEcc(p_FmPcd->h_Fm);
35445 +
35446 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
35447 +
35448 + /* register even if no interrupts enabled, to allow future enablement */
35449 + FmRegisterIntr(p_FmPcd->h_Fm,
35450 + e_FM_MOD_KG,
35451 + 0,
35452 + e_FM_INTR_TYPE_ERR,
35453 + PcdKgErrorException,
35454 + p_FmPcd);
35455 +
35456 + fman_kg_enable_scheme_interrupts(p_Regs);
35457 +
35458 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
35459 + {
35460 + err = FmPcdKgAllocSchemes(p_FmPcd,
35461 + p_FmPcd->p_FmPcdKg->numOfSchemes,
35462 + p_FmPcd->guestId,
35463 + p_FmPcd->p_FmPcdKg->schemesIds);
35464 + if (err)
35465 + RETURN_ERROR(MINOR, err, NO_MSG);
35466 + }
35467 +
35468 + return E_OK;
35469 +}
35470 +
35471 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35472 +{
35473 + ASSERT_COND(!p_Scheme->valid);
35474 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35475 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35476 + p_Scheme->valid = TRUE;
35477 +}
35478 +
35479 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
35480 +{
35481 + if (p_Scheme->owners)
35482 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
35483 +
35484 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
35485 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
35486 + p_Scheme->valid = FALSE;
35487 +
35488 + return E_OK;
35489 +}
35490 +
35491 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
35492 + t_FmPcdKgSchemeParams *p_SchemeParams,
35493 + struct fman_kg_scheme_regs *p_SchemeRegs)
35494 +{
35495 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
35496 + uint32_t grpBits = 0;
35497 + uint8_t grpBase;
35498 + bool direct=TRUE, absolute=FALSE;
35499 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
35500 + t_Error err = E_OK;
35501 + int i = 0;
35502 + t_NetEnvParams netEnvParams;
35503 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
35504 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
35505 + uint8_t j, curr, idx;
35506 + uint8_t id, shift=0, code=0, offset=0, size=0;
35507 + t_FmPcdExtractEntry *p_Extract = NULL;
35508 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
35509 + bool generic = FALSE;
35510 + t_KnownFieldsMasks bitMask;
35511 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
35512 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
35513 + uint8_t numOfSwDefaults = 0;
35514 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
35515 + uint8_t currGenId = 0;
35516 +
35517 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
35518 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
35519 +
35520 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
35521 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35522 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
35523 +
35524 + /* by netEnv parameters, get match vector */
35525 + if (!p_SchemeParams->alwaysDirect)
35526 + {
35527 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
35528 + netEnvParams.netEnvId = p_Scheme->netEnvId;
35529 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
35530 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
35531 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
35532 + if (err)
35533 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
35534 + p_Scheme->matchVector = netEnvParams.vector;
35535 + }
35536 + else
35537 + {
35538 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
35539 + p_Scheme->netEnvId = ILLEGAL_NETENV;
35540 + }
35541 +
35542 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
35543 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
35544 +
35545 + if (p_SchemeParams->bypassFqidGeneration)
35546 + {
35547 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
35548 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35549 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
35550 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
35551 + if (p_SchemeParams->baseFqid)
35552 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
35553 + }
35554 + else
35555 + if (!p_SchemeParams->baseFqid)
35556 + DBG(WARNING, ("baseFqid is 0."));
35557 +
35558 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
35559 + {
35560 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
35561 + p_Scheme->directPlcr = direct;
35562 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
35563 + if (!direct && absolute)
35564 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
35565 +
35566 + if (direct)
35567 + {
35568 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
35569 + numOfProfiles = 1;
35570 + }
35571 + else
35572 + {
35573 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35574 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35575 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35576 + }
35577 + }
35578 +
35579 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
35580 + {
35581 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
35582 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35583 + {
35584 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
35585 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
35586 + }
35587 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
35588 +
35589 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
35590 + p_SchemeParams->kgNextEngineParams.cc.grpId,
35591 + &grpBits,
35592 + &grpBase);
35593 + if (err)
35594 + RETURN_ERROR(MAJOR, err, NO_MSG);
35595 + p_Scheme->ccUnits = grpBits;
35596 +
35597 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35598 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
35599 + {
35600 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
35601 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
35602 + absolute = FALSE;
35603 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
35604 + if (direct)
35605 + {
35606 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
35607 + numOfProfiles = 1;
35608 + }
35609 + else
35610 + {
35611 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35612 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
35613 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
35614 + }
35615 + }
35616 + }
35617 +
35618 + /* if policer is used directly after KG, or after CC */
35619 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
35620 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
35621 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
35622 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
35623 + {
35624 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
35625 + if (absolute)
35626 + {
35627 + /* for absolute direct policy only, */
35628 + relativeProfileId = profileId;
35629 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
35630 + if (err)
35631 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
35632 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
35633 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
35634 + p_Scheme->relativeProfileId = profileId;
35635 + }
35636 + else
35637 + {
35638 + /* save relative profile id's for later check */
35639 + p_Scheme->nextRelativePlcrProfile = TRUE;
35640 + p_Scheme->relativeProfileId = profileId;
35641 + p_Scheme->numOfProfiles = numOfProfiles;
35642 + }
35643 + }
35644 + else
35645 + {
35646 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
35647 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
35648 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
35649 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35650 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
35651 + if (p_SchemeParams->bypassFqidGeneration &&
35652 + p_SchemeParams->useHash &&
35653 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
35654 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35655 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
35656 + }
35657 +
35658 + /* configure all 21 scheme registers */
35659 + tmpReg = KG_SCH_MODE_EN;
35660 + switch (p_SchemeParams->nextEngine)
35661 + {
35662 + case (e_FM_PCD_PLCR):
35663 + /* add to mode register - NIA */
35664 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
35665 + tmpReg |= NIA_ENG_PLCR;
35666 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
35667 + /* initialize policer profile command - */
35668 + /* configure kgse_ppc */
35669 + if (direct)
35670 + /* use profileId as base, other fields are 0 */
35671 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35672 + else
35673 + {
35674 + if (shift > MAX_PP_SHIFT)
35675 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35676 +
35677 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35678 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35679 +
35680 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35681 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35682 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35683 + ppcTmp |= (uint32_t)profileId;
35684 +
35685 + p_SchemeRegs->kgse_ppc = ppcTmp;
35686 + }
35687 + break;
35688 + case (e_FM_PCD_CC):
35689 + /* mode reg - define NIA */
35690 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
35691 +
35692 + p_SchemeRegs->kgse_ccbs = grpBits;
35693 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
35694 +
35695 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
35696 + {
35697 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
35698 + {
35699 + /* find out if absolute or relative */
35700 + if (absolute)
35701 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("It is illegal to request a shared profile in a scheme that is in a KG->CC->PLCR flow"));
35702 + if (direct)
35703 + {
35704 + /* mask = 0, base = directProfileId */
35705 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
35706 + }
35707 + else
35708 + {
35709 + if (shift > MAX_PP_SHIFT)
35710 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
35711 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35712 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35713 +
35714 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
35715 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
35716 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
35717 + ppcTmp |= (uint32_t)profileId;
35718 +
35719 + p_SchemeRegs->kgse_ppc = ppcTmp;
35720 + }
35721 + }
35722 + }
35723 + break;
35724 + case (e_FM_PCD_DONE):
35725 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
35726 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
35727 + else
35728 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
35729 + break;
35730 + default:
35731 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
35732 + }
35733 + p_SchemeRegs->kgse_mode = tmpReg;
35734 +
35735 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
35736 +
35737 +#if (DPAA_VERSION >= 11)
35738 + if (p_SchemeParams->overrideStorageProfile)
35739 + {
35740 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
35741 +
35742 + if (p_SchemeParams->storageProfile.direct)
35743 + {
35744 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
35745 + shift = 0;
35746 + numOfProfiles = 1;
35747 + }
35748 + else
35749 + {
35750 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
35751 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
35752 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
35753 + }
35754 + if (shift > MAX_SP_SHIFT)
35755 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
35756 +
35757 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
35758 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
35759 +
35760 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
35761 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
35762 + tmpReg |= (uint32_t)profileId;
35763 +
35764 +
35765 + p_SchemeRegs->kgse_vsp = tmpReg;
35766 +
35767 + p_Scheme->vspe = TRUE;
35768 +
35769 + }
35770 + else
35771 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
35772 +#endif /* (DPAA_VERSION >= 11) */
35773 +
35774 + if (p_SchemeParams->useHash)
35775 + {
35776 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
35777 +
35778 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
35779 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
35780 +
35781 + /* configure kgse_dv0 */
35782 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
35783 +
35784 + /* configure kgse_dv1 */
35785 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
35786 +
35787 + if (!p_SchemeParams->bypassFqidGeneration)
35788 + {
35789 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
35790 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
35791 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
35792 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
35793 + }
35794 +
35795 + /* configure kgse_ekdv */
35796 + tmpReg = 0;
35797 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
35798 + {
35799 + switch (p_KeyAndHash->dflts[i].type)
35800 + {
35801 + case (e_FM_PCD_KG_MAC_ADDR):
35802 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
35803 + break;
35804 + case (e_FM_PCD_KG_TCI):
35805 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
35806 + break;
35807 + case (e_FM_PCD_KG_ENET_TYPE):
35808 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
35809 + break;
35810 + case (e_FM_PCD_KG_PPP_SESSION_ID):
35811 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
35812 + break;
35813 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
35814 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
35815 + break;
35816 + case (e_FM_PCD_KG_MPLS_LABEL):
35817 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
35818 + break;
35819 + case (e_FM_PCD_KG_IP_ADDR):
35820 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
35821 + break;
35822 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
35823 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
35824 + break;
35825 + case (e_FM_PCD_KG_IP_TOS_TC):
35826 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
35827 + break;
35828 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
35829 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35830 + break;
35831 + case (e_FM_PCD_KG_IPSEC_SPI):
35832 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
35833 + break;
35834 + case (e_FM_PCD_KG_L4_PORT):
35835 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
35836 + break;
35837 + case (e_FM_PCD_KG_TCP_FLAG):
35838 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
35839 + break;
35840 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
35841 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
35842 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35843 + numOfSwDefaults ++;
35844 + break;
35845 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
35846 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
35847 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35848 + numOfSwDefaults ++;
35849 + break;
35850 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
35851 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
35852 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
35853 + numOfSwDefaults ++;
35854 + break;
35855 + default:
35856 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
35857 + }
35858 + }
35859 + p_SchemeRegs->kgse_ekdv = tmpReg;
35860 +
35861 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
35862 + if (!p_LocalExtractsArray)
35863 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
35864 +
35865 + /* configure kgse_ekfc and kgse_gec */
35866 + knownTmp = 0;
35867 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
35868 + {
35869 + p_Extract = &p_KeyAndHash->extractArray[i];
35870 + switch (p_Extract->type)
35871 + {
35872 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
35873 + knownTmp |= KG_SCH_KN_PORT_ID;
35874 + /* save in driver structure */
35875 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
35876 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35877 + break;
35878 + case (e_FM_PCD_EXTRACT_BY_HDR):
35879 + switch (p_Extract->extractByHdr.hdr)
35880 + {
35881 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
35882 + case (HEADER_TYPE_UDP_LITE):
35883 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35884 + break;
35885 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
35886 + case (HEADER_TYPE_UDP_ENCAP_ESP):
35887 + switch (p_Extract->extractByHdr.type)
35888 + {
35889 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35890 + /* case where extraction from ESP only */
35891 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
35892 + {
35893 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35894 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
35895 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35896 + }
35897 + else
35898 + {
35899 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35900 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
35901 + }
35902 + break;
35903 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35904 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
35905 + {
35906 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35907 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35908 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35909 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35910 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35911 + break;
35912 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35913 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35914 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35915 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
35916 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35917 + break;
35918 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35919 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35920 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35921 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
35922 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35923 + break;
35924 + }
35925 + break;
35926 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35927 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
35928 + {
35929 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
35930 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
35931 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
35932 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
35933 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
35934 + break;
35935 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
35936 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35937 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35938 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
35939 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
35940 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35941 + break;
35942 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
35943 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
35944 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
35945 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
35946 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
35947 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
35948 + break;
35949 + }
35950 + break;
35951 + }
35952 + break;
35953 + default:
35954 + break;
35955 + }
35956 + switch (p_Extract->extractByHdr.type)
35957 + {
35958 + case (e_FM_PCD_EXTRACT_FROM_HDR):
35959 + generic = TRUE;
35960 + /* get the header code for the generic extract */
35961 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
35962 + /* set generic register fields */
35963 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
35964 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
35965 + break;
35966 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
35967 + generic = TRUE;
35968 + /* get the field code for the generic extract */
35969 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
35970 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
35971 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
35972 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
35973 + break;
35974 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
35975 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
35976 + {
35977 + /* if we have a known field for it - use it, otherwise use generic */
35978 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
35979 + p_Extract->extractByHdr.extractByHdrType.fullField);
35980 + if (bitMask)
35981 + {
35982 + knownTmp |= bitMask;
35983 + /* save in driver structure */
35984 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
35985 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
35986 + }
35987 + else
35988 + generic = TRUE;
35989 + }
35990 + else
35991 + generic = TRUE;
35992 + if (generic)
35993 + {
35994 + /* tmp - till we cover more headers under generic */
35995 + XX_Free(p_LocalExtractsArray);
35996 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
35997 + }
35998 + break;
35999 + default:
36000 + XX_Free(p_LocalExtractsArray);
36001 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36002 + }
36003 + break;
36004 + case (e_FM_PCD_EXTRACT_NON_HDR):
36005 + /* use generic */
36006 + generic = TRUE;
36007 + offset = 0;
36008 + /* get the field code for the generic extract */
36009 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
36010 + offset += p_Extract->extractNonHdr.offset;
36011 + size = p_Extract->extractNonHdr.size;
36012 + break;
36013 + default:
36014 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36015 + }
36016 +
36017 + if (generic)
36018 + {
36019 + /* set generic register fields */
36020 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
36021 + {
36022 + XX_Free(p_LocalExtractsArray);
36023 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
36024 + }
36025 + if (!code)
36026 + {
36027 + XX_Free(p_LocalExtractsArray);
36028 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
36029 + }
36030 +
36031 + genTmp = KG_SCH_GEN_VALID;
36032 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
36033 + genTmp |= offset;
36034 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
36035 + {
36036 + XX_Free(p_LocalExtractsArray);
36037 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
36038 + }
36039 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
36040 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
36041 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
36042 + DBG(WARNING, ("No sw default configured"));
36043 + else
36044 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
36045 +
36046 + genTmp |= KG_SCH_GEN_MASK;
36047 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
36048 + /* save in driver structure */
36049 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
36050 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
36051 + generic = FALSE;
36052 + }
36053 + }
36054 + p_SchemeRegs->kgse_ekfc = knownTmp;
36055 +
36056 + selectTmp = 0;
36057 + maskTmp = 0xFFFFFFFF;
36058 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
36059 +
36060 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
36061 + {
36062 + XX_Free(p_LocalExtractsArray);
36063 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
36064 + }
36065 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
36066 + {
36067 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
36068 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
36069 + /* Get the shift of the select field (depending on i) */
36070 + GET_MASK_SEL_SHIFT(shift,i);
36071 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
36072 + selectTmp |= id << shift;
36073 + else
36074 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
36075 +
36076 + /* Get the shift of the offset field (depending on i) - may
36077 + be in kgse_bmch or in kgse_fqb (depending on i) */
36078 + GET_MASK_OFFSET_SHIFT(shift,i);
36079 + if (i<=1)
36080 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
36081 + else
36082 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
36083 +
36084 + /* Get the shift of the mask field (depending on i) */
36085 + GET_MASK_SHIFT(shift,i);
36086 + /* pass all bits */
36087 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
36088 + /* clear bits that need masking */
36089 + maskTmp &= ~(0xFF << shift) ;
36090 + /* set mask bits */
36091 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
36092 + }
36093 + p_SchemeRegs->kgse_bmch = selectTmp;
36094 + p_SchemeRegs->kgse_bmcl = maskTmp;
36095 + /* kgse_fqb will be written t the end of the routine */
36096 +
36097 + /* configure kgse_hc */
36098 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
36099 + {
36100 + XX_Free(p_LocalExtractsArray);
36101 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
36102 + }
36103 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
36104 + {
36105 + XX_Free(p_LocalExtractsArray);
36106 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
36107 + }
36108 +
36109 + tmpReg = 0;
36110 +
36111 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
36112 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
36113 +
36114 + if (p_KeyAndHash->symmetricHash)
36115 + {
36116 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
36117 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
36118 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
36119 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
36120 + {
36121 + XX_Free(p_LocalExtractsArray);
36122 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
36123 + }
36124 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
36125 + }
36126 + p_SchemeRegs->kgse_hc = tmpReg;
36127 +
36128 + /* build the return array describing the order of the extractions */
36129 +
36130 + /* the last currGenId places of the array
36131 + are for generic extracts that are always last.
36132 + We now sort for the calculation of the order of the known
36133 + extractions we sort the known extracts between orderedArray[0] and
36134 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
36135 + for the calculation of the order of the generic extractions we use:
36136 + num_of_generic - currGenId
36137 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
36138 + first_generic_index = num_of_known */
36139 + curr = 0;
36140 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
36141 + {
36142 + if (p_LocalExtractsArray->extractsArray[i].known)
36143 + {
36144 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
36145 + j = curr;
36146 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
36147 + index in the user's extractions array */
36148 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
36149 + location */
36150 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
36151 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
36152 + {
36153 + p_Scheme->orderedArray[j] =
36154 + p_Scheme->orderedArray[j-1];
36155 + j--;
36156 + }
36157 + p_Scheme->orderedArray[j] = (uint8_t)i;
36158 + curr++;
36159 + }
36160 + else
36161 + {
36162 + /* index is first_generic_index + generic index (id) */
36163 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
36164 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
36165 + p_Scheme->orderedArray[idx]= (uint8_t)i;
36166 + }
36167 + }
36168 + XX_Free(p_LocalExtractsArray);
36169 + }
36170 + else
36171 + {
36172 + /* clear all unused registers: */
36173 + p_SchemeRegs->kgse_ekfc = 0;
36174 + p_SchemeRegs->kgse_ekdv = 0;
36175 + p_SchemeRegs->kgse_bmch = 0;
36176 + p_SchemeRegs->kgse_bmcl = 0;
36177 + p_SchemeRegs->kgse_hc = 0;
36178 + p_SchemeRegs->kgse_dv0 = 0;
36179 + p_SchemeRegs->kgse_dv1 = 0;
36180 + }
36181 +
36182 + if (p_SchemeParams->bypassFqidGeneration)
36183 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
36184 +
36185 + /* configure kgse_spc */
36186 + if ( p_SchemeParams->schemeCounter.update)
36187 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
36188 +
36189 +
36190 + /* check that are enough generic registers */
36191 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
36192 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
36193 +
36194 + /* extracted OR mask on Qid */
36195 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
36196 + {
36197 +
36198 + p_Scheme->extractedOrs = TRUE;
36199 + /* configure kgse_gec[i] */
36200 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
36201 + switch (p_ExtractOr->type)
36202 + {
36203 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
36204 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
36205 + offset = 0;
36206 + break;
36207 + case (e_FM_PCD_EXTRACT_BY_HDR):
36208 + /* get the header code for the generic extract */
36209 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
36210 + /* set generic register fields */
36211 + offset = p_ExtractOr->extractionOffset;
36212 + break;
36213 + case (e_FM_PCD_EXTRACT_NON_HDR):
36214 + /* get the field code for the generic extract */
36215 + offset = 0;
36216 + code = GetGenCode(p_ExtractOr->src, &offset);
36217 + offset += p_ExtractOr->extractionOffset;
36218 + break;
36219 + default:
36220 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
36221 + }
36222 +
36223 + /* set generic register fields */
36224 + if (!code)
36225 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
36226 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
36227 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
36228 + genTmp |= offset;
36229 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
36230 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
36231 +
36232 + /************************************************************************************
36233 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
36234 + in the following way:
36235 +
36236 + Driver API and implementation:
36237 + ==============================
36238 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
36239 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
36240 + are not overlapping FQID.
36241 + ------------------------
36242 + | FQID (24) |
36243 + ------------------------
36244 + --------
36245 + | | extracted OR byte
36246 + --------
36247 +
36248 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
36249 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
36250 + are not overlapping PP id.
36251 +
36252 + --------
36253 + | PP (8) |
36254 + --------
36255 + --------
36256 + | | extracted OR byte
36257 + --------
36258 +
36259 + HW implementation
36260 + =================
36261 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
36262 + as the highest byte of that word and may be rotated to effect any part os the FQID or
36263 + the PP.
36264 + ------------------------ --------
36265 + | FQID (24) || PP (8) |
36266 + ------------------------ --------
36267 + --------
36268 + | | extracted OR byte
36269 + --------
36270 +
36271 + ************************************************************************************/
36272 +
36273 + if (p_ExtractOr->bitOffsetInFqid)
36274 + {
36275 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
36276 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
36277 + if (p_ExtractOr->bitOffsetInFqid<8)
36278 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
36279 + else
36280 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
36281 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
36282 + }
36283 + else /* effect policer profile */
36284 + {
36285 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
36286 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
36287 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
36288 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
36289 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
36290 + }
36291 +
36292 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
36293 + /* clear bits that need masking */
36294 + genTmp &= ~KG_SCH_GEN_MASK ;
36295 + /* set mask bits */
36296 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
36297 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
36298 +
36299 + }
36300 + /* clear all unused GEC registers */
36301 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
36302 + p_SchemeRegs->kgse_gec[i] = 0;
36303 +
36304 + /* add base Qid for this scheme */
36305 + /* add configuration for kgse_fqb */
36306 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
36307 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
36308 +
36309 + fqbTmp |= p_SchemeParams->baseFqid;
36310 + p_SchemeRegs->kgse_fqb = fqbTmp;
36311 +
36312 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
36313 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
36314 +
36315 + return E_OK;
36316 +}
36317 +
36318 +
36319 +/*****************************************************************************/
36320 +/* Inter-module API routines */
36321 +/*****************************************************************************/
36322 +
36323 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
36324 +{
36325 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36326 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36327 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36328 + t_Error err = E_OK;
36329 + uint32_t oredVectors = 0;
36330 + int i, j;
36331 +
36332 + /* this routine is protected by the calling routine ! */
36333 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
36334 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
36335 +
36336 + /* find a new clsPlan group */
36337 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
36338 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
36339 + break;
36340 + if (i == FM_MAX_NUM_OF_PORTS)
36341 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
36342 +
36343 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
36344 +
36345 + p_Grp->clsPlanGrpId = (uint8_t)i;
36346 +
36347 + if (p_Grp->numOfOptions == 0)
36348 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
36349 +
36350 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
36351 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
36352 + p_ClsPlanGrp->owners = 0;
36353 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
36354 + if (p_Grp->numOfOptions != 0)
36355 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
36356 +
36357 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
36358 + /* a minimal group of 8 is required */
36359 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
36360 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
36361 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36362 + {
36363 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
36364 +
36365 + if (err)
36366 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
36367 + }
36368 + else
36369 + {
36370 + t_FmPcdIpcMsg msg;
36371 + uint32_t replyLength;
36372 + t_FmPcdIpcReply reply;
36373 +
36374 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36375 + memset(&reply, 0, sizeof(reply));
36376 + memset(&msg, 0, sizeof(msg));
36377 + memset(&kgAlloc, 0, sizeof(kgAlloc));
36378 + kgAlloc.guestId = p_FmPcd->guestId;
36379 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36380 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
36381 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36382 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
36383 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36384 + (uint8_t*)&msg,
36385 + sizeof(msg.msgId) + sizeof(kgAlloc),
36386 + (uint8_t*)&reply,
36387 + &replyLength,
36388 + NULL,
36389 + NULL)) != E_OK)
36390 + RETURN_ERROR(MAJOR, err, NO_MSG);
36391 +
36392 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
36393 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36394 + if ((t_Error)reply.error != E_OK)
36395 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
36396 +
36397 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
36398 + }
36399 +
36400 + /* build classification plan entries parameters */
36401 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
36402 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
36403 +
36404 + oredVectors = 0;
36405 + for (i = 0; i<p_Grp->numOfOptions; i++)
36406 + {
36407 + oredVectors |= p_Grp->optVectors[i];
36408 + /* save an array of used options - the indexes represent the power of 2 index */
36409 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
36410 + }
36411 + /* set the classification plan relevant entries so that all bits
36412 + * relevant to the list of options is cleared
36413 + */
36414 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36415 + p_ClsPlanSet->vectors[j] = ~oredVectors;
36416 +
36417 + for (i = 0; i<p_Grp->numOfOptions; i++)
36418 + {
36419 + /* option i got the place 2^i in the clsPlan array. all entries that
36420 + * have bit i set, should have the vector bit cleared. So each option
36421 + * has one location that it is exclusive (1,2,4,8...) and represent the
36422 + * presence of that option only, and other locations that represent a
36423 + * combination of options.
36424 + * e.g:
36425 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
36426 + * now represents a frame with ethernet-BC header - so the bit
36427 + * representing ethernet-BC should be set and all other option bits
36428 + * should be cleared.
36429 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
36430 + * vector[1] set, but they also have other bits set:
36431 + * 3=1+2, options 0 and 1
36432 + * 6=2+4, options 1 and 2
36433 + * 7=1+2+4, options 0,1,and 2
36434 + * 10=2+8, options 1 and 3
36435 + * etc.
36436 + * */
36437 +
36438 + /* now for each option (i), we set their bits in all entries (j)
36439 + * that contain bit 2^i.
36440 + */
36441 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
36442 + {
36443 + if (j & (1<<i))
36444 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
36445 + }
36446 + }
36447 +
36448 + return E_OK;
36449 +}
36450 +
36451 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
36452 +{
36453 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36454 + t_FmPcdIpcKgClsPlanParams kgAlloc;
36455 + t_Error err;
36456 + t_FmPcdIpcMsg msg;
36457 + uint32_t replyLength;
36458 + t_FmPcdIpcReply reply;
36459 +
36460 + /* check that no port is bound to this clsPlan */
36461 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
36462 + {
36463 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
36464 + return;
36465 + }
36466 +
36467 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
36468 +
36469 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
36470 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36471 + else
36472 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
36473 +
36474 + /* free blocks */
36475 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36476 + KgFreeClsPlanEntries(h_FmPcd,
36477 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
36478 + p_FmPcd->guestId,
36479 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
36480 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
36481 + {
36482 + memset(&reply, 0, sizeof(reply));
36483 + memset(&msg, 0, sizeof(msg));
36484 + kgAlloc.guestId = p_FmPcd->guestId;
36485 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
36486 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
36487 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
36488 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36489 + replyLength = sizeof(uint32_t);
36490 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36491 + (uint8_t*)&msg,
36492 + sizeof(msg.msgId) + sizeof(kgAlloc),
36493 + (uint8_t*)&reply,
36494 + &replyLength,
36495 + NULL,
36496 + NULL);
36497 + if (err != E_OK)
36498 + {
36499 + REPORT_ERROR(MINOR, err, NO_MSG);
36500 + return;
36501 + }
36502 + if (replyLength != sizeof(uint32_t))
36503 + {
36504 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36505 + return;
36506 + }
36507 + if ((t_Error)reply.error != E_OK)
36508 + {
36509 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
36510 + return;
36511 + }
36512 + }
36513 +
36514 + /* clear clsPlan driver structure */
36515 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
36516 +}
36517 +
36518 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
36519 +{
36520 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36521 + uint32_t j, schemesPerPortVector = 0;
36522 + t_FmPcdKgScheme *p_Scheme;
36523 + uint8_t i, relativeSchemeId;
36524 + uint32_t tmp, walking1Mask;
36525 + uint8_t swPortIndex = 0;
36526 +
36527 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36528 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36529 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
36530 +
36531 + /* for each scheme */
36532 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
36533 + {
36534 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36535 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
36536 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
36537 +
36538 + if (add)
36539 + {
36540 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
36541 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
36542 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
36543 + /* check netEnvId of the port against the scheme netEnvId */
36544 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
36545 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
36546 +
36547 + /* if next engine is private port policer profile, we need to check that it is valid */
36548 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
36549 + if (p_Scheme->nextRelativePlcrProfile)
36550 + {
36551 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
36552 + {
36553 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
36554 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
36555 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
36556 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
36557 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
36558 + }
36559 + }
36560 + if (!p_BindPort->useClsPlan)
36561 + {
36562 + /* This check may be redundant as port is a assigned to the whole NetEnv */
36563 +
36564 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
36565 + cls plan options. Schemes that are used only directly, should not be checked.
36566 + it also may not be bound to schemes that go to CC with units that are options - so we OR
36567 + the match vector and the grpBits (= ccUnits) */
36568 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
36569 + {
36570 + uint8_t netEnvId;
36571 + walking1Mask = 0x80000000;
36572 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
36573 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
36574 + tmp |= p_Scheme->ccUnits;
36575 + while (tmp)
36576 + {
36577 + if (tmp & walking1Mask)
36578 + {
36579 + tmp &= ~walking1Mask;
36580 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
36581 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
36582 + }
36583 + walking1Mask >>= 1;
36584 + }
36585 + }
36586 + }
36587 + }
36588 + /* build vector */
36589 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
36590 + }
36591 +
36592 + *p_SpReg = schemesPerPortVector;
36593 +
36594 + return E_OK;
36595 +}
36596 +
36597 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36598 +{
36599 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36600 + uint32_t spReg;
36601 + t_Error err = E_OK;
36602 +
36603 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
36604 + if (err)
36605 + RETURN_ERROR(MAJOR, err, NO_MSG);
36606 +
36607 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
36608 + if (err)
36609 + RETURN_ERROR(MAJOR, err, NO_MSG);
36610 +
36611 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
36612 +
36613 + return E_OK;
36614 +}
36615 +
36616 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
36617 +{
36618 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36619 + uint32_t spReg;
36620 + t_Error err = E_OK;
36621 +
36622 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
36623 + if (err)
36624 + RETURN_ERROR(MAJOR, err, NO_MSG);
36625 +
36626 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
36627 + if (err)
36628 + RETURN_ERROR(MAJOR, err, NO_MSG);
36629 +
36630 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
36631 +
36632 + return E_OK;
36633 +}
36634 +
36635 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
36636 +{
36637 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
36638 +
36639 + return p_Scheme->valid;
36640 +}
36641 +
36642 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
36643 +{
36644 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36645 +
36646 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
36647 + return TRUE;
36648 + else
36649 + return FALSE;
36650 +}
36651 +
36652 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36653 +{
36654 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36655 + uint8_t i, j;
36656 +
36657 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36658 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36659 +
36660 + /* This routine is issued only on master core of master partition -
36661 + either directly or through IPC, so no need for lock */
36662 +
36663 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
36664 + {
36665 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
36666 + {
36667 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
36668 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
36669 + p_SchemesIds[j] = i;
36670 + j++;
36671 + }
36672 + }
36673 +
36674 + if (j != numOfSchemes)
36675 + {
36676 + /* roll back */
36677 + for (j--; j; j--)
36678 + {
36679 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
36680 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
36681 + p_SchemesIds[j] = 0;
36682 + }
36683 +
36684 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
36685 + }
36686 +
36687 + return E_OK;
36688 +}
36689 +
36690 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
36691 +{
36692 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36693 + uint8_t i;
36694 +
36695 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
36696 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
36697 +
36698 + /* This routine is issued only on master core of master partition -
36699 + either directly or through IPC */
36700 +
36701 + for (i = 0; i < numOfSchemes; i++)
36702 + {
36703 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
36704 + {
36705 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
36706 + }
36707 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
36708 + {
36709 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
36710 + }
36711 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
36712 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
36713 + }
36714 +
36715 + return E_OK;
36716 +}
36717 +
36718 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
36719 +{
36720 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36721 + uint8_t numOfBlocks, blocksFound=0, first=0;
36722 + uint8_t i, j;
36723 +
36724 + /* This routine is issued only on master core of master partition -
36725 + either directly or through IPC, so no need for lock */
36726 +
36727 + if (!numOfClsPlanEntries)
36728 + return E_OK;
36729 +
36730 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
36731 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
36732 +
36733 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36734 +
36735 + /* try to find consequent blocks */
36736 + first = 0;
36737 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
36738 + {
36739 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
36740 + {
36741 + blocksFound++;
36742 + i++;
36743 + if (blocksFound == numOfBlocks)
36744 + break;
36745 + }
36746 + else
36747 + {
36748 + blocksFound = 0;
36749 + /* advance i to the next aligned address */
36750 + first = i = (uint8_t)(first + numOfBlocks);
36751 + }
36752 + }
36753 +
36754 + if (blocksFound == numOfBlocks)
36755 + {
36756 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
36757 + for (j = first; j < (first + numOfBlocks); j++)
36758 + {
36759 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
36760 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
36761 + }
36762 + return E_OK;
36763 + }
36764 + else
36765 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
36766 +}
36767 +
36768 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
36769 +{
36770 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
36771 + uint8_t numOfBlocks;
36772 + uint8_t i, baseBlock;
36773 +
36774 +#ifdef DISABLE_ASSERTIONS
36775 +UNUSED(guestId);
36776 +#endif /* DISABLE_ASSERTIONS */
36777 +
36778 + /* This routine is issued only on master core of master partition -
36779 + either directly or through IPC, so no need for lock */
36780 +
36781 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
36782 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
36783 +
36784 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
36785 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
36786 + {
36787 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
36788 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
36789 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
36790 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
36791 + }
36792 +}
36793 +
36794 +void KgEnable(t_FmPcd *p_FmPcd)
36795 +{
36796 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36797 +
36798 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36799 + fman_kg_enable(p_Regs);
36800 +}
36801 +
36802 +void KgDisable(t_FmPcd *p_FmPcd)
36803 +{
36804 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36805 +
36806 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36807 + fman_kg_disable(p_Regs);
36808 +}
36809 +
36810 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
36811 +{
36812 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36813 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
36814 + uint32_t tmpKgarReg = 0, intFlags;
36815 + uint16_t i, j;
36816 +
36817 + /* This routine is protected by the calling routine ! */
36818 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
36819 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
36820 +
36821 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36822 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
36823 + {
36824 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
36825 +
36826 + for (j = i; j < i+8; j++)
36827 + {
36828 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
36829 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
36830 + }
36831 +
36832 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
36833 + {
36834 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
36835 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36836 + return;
36837 + }
36838 + }
36839 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36840 +}
36841 +
36842 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
36843 +{
36844 + t_FmPcdKg *p_FmPcdKg;
36845 +
36846 + UNUSED(p_FmPcd);
36847 +
36848 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
36849 + {
36850 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
36851 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
36852 + return NULL;
36853 + }
36854 +
36855 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
36856 + if (!p_FmPcdKg)
36857 + {
36858 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
36859 + return NULL;
36860 + }
36861 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
36862 +
36863 +
36864 + if (FmIsMaster(p_FmPcd->h_Fm))
36865 + {
36866 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
36867 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
36868 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
36869 + }
36870 +
36871 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
36872 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
36873 + {
36874 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
36875 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
36876 + }
36877 +
36878 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
36879 +
36880 + return p_FmPcdKg;
36881 +}
36882 +
36883 +t_Error KgInit(t_FmPcd *p_FmPcd)
36884 +{
36885 + t_Error err = E_OK;
36886 +
36887 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
36888 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36889 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
36890 +
36891 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36892 + err = KgInitMaster(p_FmPcd);
36893 + else
36894 + err = KgInitGuest(p_FmPcd);
36895 +
36896 + if (err != E_OK)
36897 + {
36898 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36899 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36900 + }
36901 +
36902 + return err;
36903 +}
36904 +
36905 +t_Error KgFree(t_FmPcd *p_FmPcd)
36906 +{
36907 + t_FmPcdIpcKgSchemesParams kgAlloc;
36908 + t_Error err = E_OK;
36909 + t_FmPcdIpcMsg msg;
36910 + uint32_t replyLength;
36911 + t_FmPcdIpcReply reply;
36912 +
36913 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
36914 +
36915 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
36916 + {
36917 + err = FmPcdKgFreeSchemes(p_FmPcd,
36918 + p_FmPcd->p_FmPcdKg->numOfSchemes,
36919 + p_FmPcd->guestId,
36920 + p_FmPcd->p_FmPcdKg->schemesIds);
36921 + if (err)
36922 + RETURN_ERROR(MAJOR, err, NO_MSG);
36923 +
36924 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36925 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36926 +
36927 + return E_OK;
36928 + }
36929 +
36930 + /* guest */
36931 + memset(&reply, 0, sizeof(reply));
36932 + memset(&msg, 0, sizeof(msg));
36933 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
36934 + kgAlloc.guestId = p_FmPcd->guestId;
36935 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
36936 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
36937 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
36938 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
36939 + replyLength = sizeof(uint32_t);
36940 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
36941 + (uint8_t*)&msg,
36942 + sizeof(msg.msgId) + sizeof(kgAlloc),
36943 + (uint8_t*)&reply,
36944 + &replyLength,
36945 + NULL,
36946 + NULL)) != E_OK)
36947 + RETURN_ERROR(MAJOR, err, NO_MSG);
36948 + if (replyLength != sizeof(uint32_t))
36949 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
36950 +
36951 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
36952 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
36953 +
36954 + return (t_Error)reply.error;
36955 +}
36956 +
36957 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
36958 +{
36959 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
36960 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
36961 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
36962 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
36963 + t_Error err;
36964 +
36965 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
36966 + so no need for lock here */
36967 +
36968 + memset(&grpParams, 0, sizeof(grpParams));
36969 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
36970 + p_GrpParams = &grpParams;
36971 +
36972 + p_GrpParams->netEnvId = netEnvId;
36973 +
36974 + /* Get from the NetEnv the information of the clsPlan (can be already created,
36975 + * or needs to build) */
36976 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
36977 + if (err)
36978 + RETURN_ERROR(MINOR,err,NO_MSG);
36979 +
36980 + if (p_GrpParams->grpExists)
36981 + {
36982 + /* this group was already updated (at least) in SW */
36983 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36984 + }
36985 + else
36986 + {
36987 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
36988 + if (!p_ClsPlanSet)
36989 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
36990 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
36991 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
36992 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
36993 + if (err)
36994 + {
36995 + XX_Free(p_ClsPlanSet);
36996 + RETURN_ERROR(MINOR, err, NO_MSG);
36997 + }
36998 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
36999 +
37000 + if (p_FmPcd->h_Hc)
37001 + {
37002 + /* write clsPlan entries to memory */
37003 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
37004 + if (err)
37005 + {
37006 + XX_Free(p_ClsPlanSet);
37007 + RETURN_ERROR(MAJOR, err, NO_MSG);
37008 + }
37009 + }
37010 + else
37011 + /* write clsPlan entries to memory */
37012 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
37013 +
37014 + XX_Free(p_ClsPlanSet);
37015 + }
37016 +
37017 + /* Set caller parameters */
37018 +
37019 + /* mark if this is an empty classification group */
37020 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
37021 + *p_IsEmptyClsPlanGrp = TRUE;
37022 + else
37023 + *p_IsEmptyClsPlanGrp = FALSE;
37024 +
37025 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
37026 +
37027 + /* increment owners number */
37028 + p_ClsPlanGrp->owners++;
37029 +
37030 + /* copy options array for port */
37031 + memcpy(p_OptArray, &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId].optArray, FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)*sizeof(protocolOpt_t));
37032 +
37033 + /* bind port to the new or existing group */
37034 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
37035 + if (err)
37036 + RETURN_ERROR(MINOR, err, NO_MSG);
37037 +
37038 + return E_OK;
37039 +}
37040 +
37041 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
37042 +{
37043 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
37044 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
37045 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
37046 + t_Error err;
37047 +
37048 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
37049 + so no need for lock here */
37050 +
37051 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
37052 +
37053 + /* decrement owners number */
37054 + ASSERT_COND(p_ClsPlanGrp->owners);
37055 + p_ClsPlanGrp->owners--;
37056 +
37057 + if (!p_ClsPlanGrp->owners)
37058 + {
37059 + if (p_FmPcd->h_Hc)
37060 + {
37061 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
37062 + return err;
37063 + }
37064 + else
37065 + {
37066 + /* clear clsPlan entries in memory */
37067 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
37068 + if (!p_ClsPlanSet)
37069 + {
37070 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
37071 + }
37072 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
37073 +
37074 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
37075 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
37076 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
37077 + XX_Free(p_ClsPlanSet);
37078 +
37079 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
37080 + }
37081 + }
37082 + return E_OK;
37083 +}
37084 +
37085 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
37086 +{
37087 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37088 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37089 +
37090 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
37091 +}
37092 +
37093 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
37094 +{
37095 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37096 +
37097 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37098 +
37099 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
37100 +}
37101 +
37102 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
37103 +{
37104 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37105 +
37106 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37107 +
37108 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
37109 +}
37110 +
37111 +
37112 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
37113 +{
37114 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37115 +
37116 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37117 +
37118 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
37119 +}
37120 +
37121 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
37122 +{
37123 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37124 +
37125 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37126 +
37127 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
37128 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
37129 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
37130 + return TRUE;
37131 + else
37132 + return FALSE;
37133 +
37134 +}
37135 +
37136 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37137 +{
37138 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37139 +
37140 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
37141 +
37142 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
37143 +}
37144 +
37145 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
37146 +{
37147 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37148 +
37149 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
37150 +
37151 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
37152 +}
37153 +
37154 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
37155 +{
37156 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37157 +
37158 + /* this routine is protected by calling routine */
37159 +
37160 + ASSERT_COND(p_Scheme->valid);
37161 +
37162 + p_Scheme->requiredAction |= requiredAction;
37163 +}
37164 +
37165 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
37166 +{
37167 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
37168 +}
37169 +
37170 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
37171 +{
37172 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37173 + FM_KG_KGAR_GO |
37174 + FM_KG_KGAR_WRITE |
37175 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37176 + DUMMY_PORT_ID |
37177 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
37178 +}
37179 +
37180 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
37181 +{
37182 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37183 + FM_KG_KGAR_GO |
37184 + FM_KG_KGAR_READ |
37185 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
37186 + DUMMY_PORT_ID |
37187 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
37188 +
37189 +}
37190 +
37191 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
37192 +{
37193 + return (uint32_t)(FM_KG_KGAR_GO |
37194 + FM_KG_KGAR_WRITE |
37195 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
37196 + DUMMY_PORT_ID |
37197 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37198 + FM_PCD_KG_KGAR_WSEL_MASK);
37199 +
37200 + /* if we ever want to write 1 by 1, use:
37201 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
37202 + */
37203 +}
37204 +
37205 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
37206 +{
37207 +
37208 + return (uint32_t)(FM_KG_KGAR_GO |
37209 + FM_KG_KGAR_WRITE |
37210 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37211 + hardwarePortId |
37212 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37213 +}
37214 +
37215 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
37216 +{
37217 +
37218 + return (uint32_t)(FM_KG_KGAR_GO |
37219 + FM_KG_KGAR_READ |
37220 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37221 + hardwarePortId |
37222 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
37223 +}
37224 +
37225 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
37226 +{
37227 +
37228 + return (uint32_t)(FM_KG_KGAR_GO |
37229 + FM_KG_KGAR_WRITE |
37230 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
37231 + hardwarePortId |
37232 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
37233 +}
37234 +
37235 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37236 +{
37237 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37238 +
37239 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
37240 +}
37241 +
37242 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
37243 +{
37244 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37245 +
37246 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
37247 +}
37248 +
37249 +
37250 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
37251 +{
37252 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
37253 +
37254 +}
37255 +
37256 +#if (DPAA_VERSION >= 11)
37257 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
37258 +{
37259 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
37260 +
37261 +}
37262 +#endif /* (DPAA_VERSION >= 11) */
37263 +
37264 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
37265 +{
37266 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37267 + uint8_t i;
37268 +
37269 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
37270 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
37271 + return i;
37272 +
37273 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
37274 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
37275 +
37276 + return FM_PCD_KG_NUM_OF_SCHEMES;
37277 +}
37278 +
37279 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
37280 +{
37281 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37282 +
37283 + ASSERT_COND(p_FmPcd);
37284 +
37285 + /* check that schemeId is in range */
37286 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37287 + {
37288 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37289 + return NULL;
37290 + }
37291 +
37292 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
37293 + return NULL;
37294 +
37295 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37296 +}
37297 +
37298 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
37299 +{
37300 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
37301 +}
37302 +
37303 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
37304 +{
37305 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37306 + uint8_t relativeSchemeId, physicalSchemeId;
37307 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
37308 + t_Error err;
37309 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
37310 +
37311 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
37312 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
37313 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
37314 +
37315 + /* Calling function locked all PCD modules, so no need to lock here */
37316 +
37317 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37318 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37319 +
37320 + if (p_FmPcd->h_Hc)
37321 + {
37322 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
37323 +
37324 + UpdateRequiredActionFlag(h_Scheme,TRUE);
37325 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
37326 + return err;
37327 + }
37328 +
37329 + physicalSchemeId = p_Scheme->schemeId;
37330 +
37331 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
37332 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
37333 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37334 +
37335 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
37336 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
37337 + {
37338 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
37339 + {
37340 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
37341 + {
37342 + case (e_FM_PCD_DONE):
37343 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
37344 + {
37345 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37346 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37347 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37348 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37349 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
37350 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
37351 + /* call indirect command for scheme write */
37352 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37353 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37354 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37355 + }
37356 + break;
37357 + case (e_FM_PCD_PLCR):
37358 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
37359 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
37360 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
37361 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
37362 + {
37363 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
37364 + }
37365 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
37366 + if (err)
37367 + {
37368 + RETURN_ERROR(MAJOR, err, NO_MSG);
37369 + }
37370 + break;
37371 + default:
37372 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
37373 + }
37374 + }
37375 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
37376 + {
37377 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
37378 + {
37379 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37380 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37381 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37382 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37383 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
37384 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
37385 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
37386 + /* call indirect command for scheme write */
37387 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37388 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37389 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37390 + }
37391 + }
37392 + if (requiredAction & UPDATE_KG_OPT_MODE)
37393 + {
37394 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37395 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37396 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37397 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
37398 + /* call indirect command for scheme write */
37399 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37400 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37401 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37402 + }
37403 + if (requiredAction & UPDATE_KG_NIA)
37404 + {
37405 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37406 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37407 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37408 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
37409 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
37410 + tmpReg32 |= value;
37411 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
37412 + /* call indirect command for scheme write */
37413 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37414 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37415 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37416 + }
37417 + }
37418 +
37419 + UpdateRequiredActionFlag(h_Scheme, TRUE);
37420 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
37421 +
37422 + return E_OK;
37423 +}
37424 +/*********************** End of inter-module routines ************************/
37425 +
37426 +
37427 +/****************************************/
37428 +/* API routines */
37429 +/****************************************/
37430 +
37431 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
37432 +{
37433 + t_FmPcd *p_FmPcd;
37434 + struct fman_kg_scheme_regs schemeRegs;
37435 + struct fman_kg_scheme_regs *p_MemRegs;
37436 + uint8_t i;
37437 + t_Error err = E_OK;
37438 + uint32_t tmpKgarReg;
37439 + uint32_t intFlags;
37440 + uint8_t physicalSchemeId, relativeSchemeId = 0;
37441 + t_FmPcdKgScheme *p_Scheme;
37442 +
37443 + if (p_SchemeParams->modify)
37444 + {
37445 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
37446 + p_FmPcd = p_Scheme->h_FmPcd;
37447 +
37448 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37449 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37450 +
37451 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
37452 + {
37453 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37454 + ("Scheme is invalid"));
37455 + return NULL;
37456 + }
37457 +
37458 + if (!KgSchemeFlagTryLock(p_Scheme))
37459 + {
37460 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
37461 + /* Signal to caller BUSY condition */
37462 + p_SchemeParams->id.h_Scheme = NULL;
37463 + return NULL;
37464 + }
37465 + }
37466 + else
37467 + {
37468 + p_FmPcd = (t_FmPcd*)h_FmPcd;
37469 +
37470 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
37471 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
37472 +
37473 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
37474 + /* check that schemeId is in range */
37475 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
37476 + {
37477 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
37478 + return NULL;
37479 + }
37480 +
37481 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
37482 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
37483 + {
37484 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
37485 + ("Scheme id (%d)!", relativeSchemeId));
37486 + return NULL;
37487 + }
37488 + /* Clear all fields, scheme may have beed previously used */
37489 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
37490 +
37491 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
37492 + p_Scheme->h_FmPcd = p_FmPcd;
37493 +
37494 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
37495 + if (!p_Scheme->p_Lock)
37496 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
37497 + }
37498 +
37499 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
37500 + if (err)
37501 + {
37502 + REPORT_ERROR(MAJOR, err, NO_MSG);
37503 + if (p_SchemeParams->modify)
37504 + KgSchemeFlagUnlock(p_Scheme);
37505 + if (!p_SchemeParams->modify &&
37506 + p_Scheme->p_Lock)
37507 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37508 + return NULL;
37509 + }
37510 +
37511 + if (p_FmPcd->h_Hc)
37512 + {
37513 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
37514 + (t_Handle)p_Scheme,
37515 + &schemeRegs,
37516 + p_SchemeParams->schemeCounter.update);
37517 + if (p_SchemeParams->modify)
37518 + KgSchemeFlagUnlock(p_Scheme);
37519 + if (err)
37520 + {
37521 + if (!p_SchemeParams->modify &&
37522 + p_Scheme->p_Lock)
37523 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37524 + return NULL;
37525 + }
37526 + if (!p_SchemeParams->modify)
37527 + ValidateSchemeSw(p_Scheme);
37528 + return (t_Handle)p_Scheme;
37529 + }
37530 +
37531 + physicalSchemeId = p_Scheme->schemeId;
37532 +
37533 + /* configure all 21 scheme registers */
37534 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
37535 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37536 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
37537 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
37538 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
37539 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
37540 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
37541 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
37542 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
37543 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
37544 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
37545 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
37546 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
37547 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
37548 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
37549 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
37550 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
37551 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37552 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
37553 +
37554 + /* call indirect command for scheme write */
37555 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
37556 +
37557 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37558 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37559 +
37560 + if (!p_SchemeParams->modify)
37561 + ValidateSchemeSw(p_Scheme);
37562 + else
37563 + KgSchemeFlagUnlock(p_Scheme);
37564 +
37565 + return (t_Handle)p_Scheme;
37566 +}
37567 +
37568 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
37569 +{
37570 + t_FmPcd *p_FmPcd;
37571 + uint8_t physicalSchemeId;
37572 + uint32_t tmpKgarReg, intFlags;
37573 + t_Error err = E_OK;
37574 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
37575 +
37576 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
37577 +
37578 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
37579 +
37580 + UpdateRequiredActionFlag(h_Scheme, FALSE);
37581 +
37582 + /* check that no port is bound to this scheme */
37583 + err = InvalidateSchemeSw(h_Scheme);
37584 + if (err)
37585 + RETURN_ERROR(MINOR, err, NO_MSG);
37586 +
37587 + if (p_FmPcd->h_Hc)
37588 + {
37589 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
37590 + if (p_Scheme->p_Lock)
37591 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37592 + return err;
37593 + }
37594 +
37595 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37596 +
37597 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37598 + /* clear mode register, including enable bit */
37599 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
37600 +
37601 + /* call indirect command for scheme write */
37602 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
37603 +
37604 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37605 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37606 +
37607 + if (p_Scheme->p_Lock)
37608 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
37609 +
37610 + return E_OK;
37611 +}
37612 +
37613 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
37614 +{
37615 + t_FmPcd *p_FmPcd;
37616 + uint32_t tmpKgarReg, spc, intFlags;
37617 + uint8_t physicalSchemeId;
37618 +
37619 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37620 +
37621 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37622 + if (p_FmPcd->h_Hc)
37623 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
37624 +
37625 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37626 +
37627 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37628 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37629 +
37630 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37631 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37632 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37633 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37634 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37635 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
37636 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37637 +
37638 + return spc;
37639 +}
37640 +
37641 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
37642 +{
37643 + t_FmPcd *p_FmPcd;
37644 + uint32_t tmpKgarReg, intFlags;
37645 + uint8_t physicalSchemeId;
37646 +
37647 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
37648 +
37649 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
37650 +
37651 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
37652 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
37653 +
37654 + if (p_FmPcd->h_Hc)
37655 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
37656 +
37657 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
37658 + /* check that schemeId is in range */
37659 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
37660 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
37661 +
37662 + /* read specified scheme into scheme registers */
37663 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
37664 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
37665 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37666 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
37667 + {
37668 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37669 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
37670 + }
37671 +
37672 + /* change counter value */
37673 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
37674 +
37675 + /* call indirect command for scheme write */
37676 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
37677 +
37678 + WriteKgarWait(p_FmPcd, tmpKgarReg);
37679 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37680 +
37681 + return E_OK;
37682 +}
37683 +
37684 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
37685 +{
37686 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37687 + struct fman_kg_regs *p_Regs;
37688 +
37689 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37690 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37691 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37692 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37693 +
37694 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37695 + if (!FmIsMaster(p_FmPcd->h_Fm))
37696 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
37697 +
37698 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
37699 +
37700 + return E_OK;
37701 +}
37702 +
37703 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
37704 +{
37705 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37706 + struct fman_kg_regs *p_Regs;
37707 +
37708 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
37709 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
37710 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
37711 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
37712 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
37713 +
37714 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37715 +
37716 + if (!FmIsMaster(p_FmPcd->h_Fm))
37717 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
37718 +
37719 + if (valueId == 0)
37720 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
37721 + else
37722 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
37723 + return E_OK;
37724 +}
37725 --- /dev/null
37726 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
37727 @@ -0,0 +1,206 @@
37728 +/*
37729 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37730 + *
37731 + * Redistribution and use in source and binary forms, with or without
37732 + * modification, are permitted provided that the following conditions are met:
37733 + * * Redistributions of source code must retain the above copyright
37734 + * notice, this list of conditions and the following disclaimer.
37735 + * * Redistributions in binary form must reproduce the above copyright
37736 + * notice, this list of conditions and the following disclaimer in the
37737 + * documentation and/or other materials provided with the distribution.
37738 + * * Neither the name of Freescale Semiconductor nor the
37739 + * names of its contributors may be used to endorse or promote products
37740 + * derived from this software without specific prior written permission.
37741 + *
37742 + *
37743 + * ALTERNATIVELY, this software may be distributed under the terms of the
37744 + * GNU General Public License ("GPL") as published by the Free Software
37745 + * Foundation, either version 2 of that License or (at your option) any
37746 + * later version.
37747 + *
37748 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37749 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37750 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37751 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37752 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37753 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37754 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37755 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37756 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37757 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37758 + */
37759 +
37760 +
37761 +/******************************************************************************
37762 + @File fm_kg.h
37763 +
37764 + @Description FM KG private header
37765 +*//***************************************************************************/
37766 +#ifndef __FM_KG_H
37767 +#define __FM_KG_H
37768 +
37769 +#include "std_ext.h"
37770 +
37771 +/***********************************************************************/
37772 +/* Keygen defines */
37773 +/***********************************************************************/
37774 +/* maskes */
37775 +#if (DPAA_VERSION >= 11)
37776 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
37777 +#define KG_SCH_OM_VSPE 0x00000001
37778 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
37779 +
37780 +#define MAX_SP_SHIFT 23
37781 +#define KG_SCH_VSP_MASK_SHIFT 12
37782 +#define KG_SCH_VSP_SHIFT 24
37783 +#endif /* (DPAA_VERSION >= 11) */
37784 +
37785 +typedef uint32_t t_KnownFieldsMasks;
37786 +#define KG_SCH_KN_PORT_ID 0x80000000
37787 +#define KG_SCH_KN_MACDST 0x40000000
37788 +#define KG_SCH_KN_MACSRC 0x20000000
37789 +#define KG_SCH_KN_TCI1 0x10000000
37790 +#define KG_SCH_KN_TCI2 0x08000000
37791 +#define KG_SCH_KN_ETYPE 0x04000000
37792 +#define KG_SCH_KN_PPPSID 0x02000000
37793 +#define KG_SCH_KN_PPPID 0x01000000
37794 +#define KG_SCH_KN_MPLS1 0x00800000
37795 +#define KG_SCH_KN_MPLS2 0x00400000
37796 +#define KG_SCH_KN_MPLS_LAST 0x00200000
37797 +#define KG_SCH_KN_IPSRC1 0x00100000
37798 +#define KG_SCH_KN_IPDST1 0x00080000
37799 +#define KG_SCH_KN_PTYPE1 0x00040000
37800 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
37801 +#define KG_SCH_KN_IPV6FL1 0x00010000
37802 +#define KG_SCH_KN_IPSRC2 0x00008000
37803 +#define KG_SCH_KN_IPDST2 0x00004000
37804 +#define KG_SCH_KN_PTYPE2 0x00002000
37805 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
37806 +#define KG_SCH_KN_IPV6FL2 0x00000800
37807 +#define KG_SCH_KN_GREPTYPE 0x00000400
37808 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
37809 +#define KG_SCH_KN_IPSEC_NH 0x00000100
37810 +#define KG_SCH_KN_IPPID 0x00000080
37811 +#define KG_SCH_KN_L4PSRC 0x00000004
37812 +#define KG_SCH_KN_L4PDST 0x00000002
37813 +#define KG_SCH_KN_TFLG 0x00000001
37814 +
37815 +typedef uint8_t t_GenericCodes;
37816 +#define KG_SCH_GEN_SHIM1 0x70
37817 +#define KG_SCH_GEN_DEFAULT 0x10
37818 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
37819 +#define KG_SCH_GEN_START_OF_FRM 0x40
37820 +#define KG_SCH_GEN_SHIM2 0x71
37821 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
37822 +#define KG_SCH_GEN_ETH 0x03
37823 +#define KG_SCH_GEN_ETH_NO_V 0x73
37824 +#define KG_SCH_GEN_SNAP 0x04
37825 +#define KG_SCH_GEN_SNAP_NO_V 0x74
37826 +#define KG_SCH_GEN_VLAN1 0x05
37827 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
37828 +#define KG_SCH_GEN_VLAN2 0x06
37829 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
37830 +#define KG_SCH_GEN_ETH_TYPE 0x07
37831 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
37832 +#define KG_SCH_GEN_PPP 0x08
37833 +#define KG_SCH_GEN_PPP_NO_V 0x78
37834 +#define KG_SCH_GEN_MPLS1 0x09
37835 +#define KG_SCH_GEN_MPLS2 0x19
37836 +#define KG_SCH_GEN_MPLS3 0x29
37837 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
37838 +#define KG_SCH_GEN_MPLS_LAST 0x0a
37839 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
37840 +#define KG_SCH_GEN_IPV4 0x0b
37841 +#define KG_SCH_GEN_IPV6 0x1b
37842 +#define KG_SCH_GEN_L3_NO_V 0x7b
37843 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
37844 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
37845 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
37846 +#define KG_SCH_GEN_IP2_NO_V 0x7c
37847 +#define KG_SCH_GEN_GRE 0x0d
37848 +#define KG_SCH_GEN_GRE_NO_V 0x7d
37849 +#define KG_SCH_GEN_TCP 0x0e
37850 +#define KG_SCH_GEN_UDP 0x1e
37851 +#define KG_SCH_GEN_IPSEC_AH 0x2e
37852 +#define KG_SCH_GEN_SCTP 0x3e
37853 +#define KG_SCH_GEN_DCCP 0x4e
37854 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
37855 +#define KG_SCH_GEN_L4_NO_V 0x7e
37856 +#define KG_SCH_GEN_NEXTHDR 0x7f
37857 +/* shifts */
37858 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
37859 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
37860 +#define KG_SCH_PP_MASK_SHIFT 16
37861 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
37862 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
37863 +#define KG_SCH_DEF_TCI_SHIFT 28
37864 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
37865 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
37866 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
37867 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
37868 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
37869 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
37870 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
37871 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
37872 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
37873 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
37874 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
37875 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
37876 +#define KG_SCH_GEN_MASK_SHIFT 16
37877 +#define KG_SCH_GEN_HT_SHIFT 8
37878 +#define KG_SCH_GEN_SIZE_SHIFT 24
37879 +#define KG_SCH_GEN_DEF_SHIFT 29
37880 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
37881 +
37882 +/* others */
37883 +#define NUM_OF_SW_DEFAULTS 3
37884 +#define MAX_PP_SHIFT 23
37885 +#define MAX_KG_SCH_SIZE 16
37886 +#define MASK_FOR_GENERIC_BASE_ID 0x20
37887 +#define MAX_HASH_SHIFT 40
37888 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
37889 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
37890 +#define MAX_DIST_FQID_SHIFT 23
37891 +
37892 +#define GET_MASK_SEL_SHIFT(shift,i) \
37893 +switch (i) { \
37894 + case (0):shift = 26;break; \
37895 + case (1):shift = 20;break; \
37896 + case (2):shift = 10;break; \
37897 + case (3):shift = 4;break; \
37898 + default: \
37899 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37900 +}
37901 +
37902 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
37903 +switch (i) { \
37904 + case (0):shift = 16;break; \
37905 + case (1):shift = 0;break; \
37906 + case (2):shift = 28;break; \
37907 + case (3):shift = 24;break; \
37908 + default: \
37909 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37910 +}
37911 +
37912 +#define GET_MASK_SHIFT(shift,i) \
37913 +switch (i) { \
37914 + case (0):shift = 24;break; \
37915 + case (1):shift = 16;break; \
37916 + case (2):shift = 8;break; \
37917 + case (3):shift = 0;break; \
37918 + default: \
37919 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
37920 +}
37921 +
37922 +/***********************************************************************/
37923 +/* Keygen defines */
37924 +/***********************************************************************/
37925 +
37926 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
37927 +#define NO_VALIDATION 0x70
37928 +#define KG_ACTION_REG_TO 1024
37929 +#define KG_MAX_PROFILE 255
37930 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
37931 +
37932 +
37933 +#endif /* __FM_KG_H */
37934 --- /dev/null
37935 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
37936 @@ -0,0 +1,5571 @@
37937 +/*
37938 + * Copyright 2008-2012 Freescale Semiconductor Inc.
37939 + *
37940 + * Redistribution and use in source and binary forms, with or without
37941 + * modification, are permitted provided that the following conditions are met:
37942 + * * Redistributions of source code must retain the above copyright
37943 + * notice, this list of conditions and the following disclaimer.
37944 + * * Redistributions in binary form must reproduce the above copyright
37945 + * notice, this list of conditions and the following disclaimer in the
37946 + * documentation and/or other materials provided with the distribution.
37947 + * * Neither the name of Freescale Semiconductor nor the
37948 + * names of its contributors may be used to endorse or promote products
37949 + * derived from this software without specific prior written permission.
37950 + *
37951 + *
37952 + * ALTERNATIVELY, this software may be distributed under the terms of the
37953 + * GNU General Public License ("GPL") as published by the Free Software
37954 + * Foundation, either version 2 of that License or (at your option) any
37955 + * later version.
37956 + *
37957 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
37958 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
37959 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37960 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
37961 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37962 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37963 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
37964 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37965 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37966 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37967 + */
37968 +
37969 +
37970 +/******************************************************************************
37971 + @File fm_manip.c
37972 +
37973 + @Description FM PCD manip ...
37974 + *//***************************************************************************/
37975 +#include "std_ext.h"
37976 +#include "error_ext.h"
37977 +#include "string_ext.h"
37978 +#include "debug_ext.h"
37979 +#include "fm_pcd_ext.h"
37980 +#include "fm_port_ext.h"
37981 +#include "fm_muram_ext.h"
37982 +#include "memcpy_ext.h"
37983 +
37984 +#include "fm_common.h"
37985 +#include "fm_hc.h"
37986 +#include "fm_manip.h"
37987 +
37988 +/****************************************/
37989 +/* static functions */
37990 +/****************************************/
37991 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
37992 +{
37993 + t_FmPcdManip *p_CurManip = p_Manip;
37994 +
37995 + if (!MANIP_IS_UNIFIED(p_Manip))
37996 + p_CurManip = p_Manip;
37997 + else
37998 + {
37999 + /* go to first unified */
38000 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
38001 + p_CurManip = p_CurManip->h_PrevManip;
38002 + }
38003 +
38004 + switch (manipInfo)
38005 + {
38006 + case (e_MANIP_HMCT):
38007 + return p_CurManip->p_Hmct;
38008 + case (e_MANIP_HMTD):
38009 + return p_CurManip->h_Ad;
38010 + case (e_MANIP_HANDLER_TABLE_OWNER):
38011 + return (t_Handle)p_CurManip;
38012 + default:
38013 + return NULL;
38014 + }
38015 +}
38016 +
38017 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
38018 +{
38019 + uint16_t size = 0;
38020 + t_FmPcdManip *p_CurManip = p_Manip;
38021 +
38022 + if (!MANIP_IS_UNIFIED(p_Manip))
38023 + return p_Manip->tableSize;
38024 +
38025 + /* accumulate sizes, starting with the first node */
38026 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
38027 + p_CurManip = p_CurManip->h_PrevManip;
38028 +
38029 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38030 + {
38031 + size += p_CurManip->tableSize;
38032 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
38033 + }
38034 + size += p_CurManip->tableSize; /* add last size */
38035 +
38036 + return (size);
38037 +}
38038 +
38039 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
38040 +{
38041 + uint16_t size = 0;
38042 + t_FmPcdManip *p_CurManip = p_Manip;
38043 +
38044 + if (!MANIP_IS_UNIFIED(p_Manip))
38045 + return p_Manip->dataSize;
38046 +
38047 + /* accumulate sizes, starting with the first node */
38048 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
38049 + p_CurManip = p_CurManip->h_PrevManip;
38050 +
38051 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
38052 + {
38053 + size += p_CurManip->dataSize;
38054 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
38055 + }
38056 + size += p_CurManip->dataSize; /* add last size */
38057 +
38058 + return (size);
38059 +}
38060 +
38061 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
38062 + uint16_t *p_TableSize, uint8_t *p_DataSize)
38063 +{
38064 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
38065 +
38066 + if (p_FmPcdManipParams->u.hdr.rmv)
38067 + {
38068 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
38069 + {
38070 + case (e_FM_PCD_MANIP_RMV_GENERIC):
38071 + tableSize += HMCD_BASIC_SIZE;
38072 + break;
38073 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
38074 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38075 + {
38076 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38077 +#if (DPAA_VERSION >= 11)
38078 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38079 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38080 +#endif /* (DPAA_VERSION >= 11) */
38081 + tableSize += HMCD_BASIC_SIZE;
38082 + break;
38083 + default:
38084 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38085 + ("Unknown byHdr.type"));
38086 + }
38087 + break;
38088 + default:
38089 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38090 + ("Unknown rmvParams.type"));
38091 + }
38092 + }
38093 +
38094 + if (p_FmPcdManipParams->u.hdr.insrt)
38095 + {
38096 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
38097 + {
38098 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
38099 + remain =
38100 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38101 + % 4);
38102 + if (remain)
38103 + localDataSize =
38104 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38105 + + 4 - remain);
38106 + else
38107 + localDataSize =
38108 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38109 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
38110 + break;
38111 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
38112 + {
38113 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38114 + {
38115 +
38116 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38117 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
38118 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38119 + {
38120 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38121 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38122 + dataSize +=
38123 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38124 + break;
38125 + default:
38126 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38127 + }
38128 + break;
38129 +#if (DPAA_VERSION >= 11)
38130 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38131 + tableSize +=
38132 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
38133 + + HMCD_PARAM_SIZE
38134 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38135 + dataSize += 2;
38136 + break;
38137 +
38138 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38139 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38140 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
38141 +
38142 + break;
38143 +
38144 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38145 + tableSize +=
38146 + (HMCD_BASIC_SIZE
38147 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38148 + break;
38149 +#endif /* (DPAA_VERSION >= 11) */
38150 + default:
38151 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38152 + ("Unknown byHdr.type"));
38153 + }
38154 + }
38155 + break;
38156 + default:
38157 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38158 + ("Unknown insrtParams.type"));
38159 + }
38160 + }
38161 +
38162 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38163 + {
38164 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38165 + {
38166 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38167 + tableSize += HMCD_BASIC_SIZE;
38168 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38169 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38170 + {
38171 + tableSize += HMCD_PTR_SIZE;
38172 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
38173 + }
38174 + break;
38175 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38176 + tableSize += HMCD_BASIC_SIZE;
38177 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38178 + & HDR_MANIP_IPV4_ID)
38179 + {
38180 + tableSize += HMCD_PARAM_SIZE;
38181 + dataSize += 2;
38182 + }
38183 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38184 + & HDR_MANIP_IPV4_SRC)
38185 + tableSize += HMCD_IPV4_ADDR_SIZE;
38186 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38187 + & HDR_MANIP_IPV4_DST)
38188 + tableSize += HMCD_IPV4_ADDR_SIZE;
38189 + break;
38190 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38191 + tableSize += HMCD_BASIC_SIZE;
38192 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38193 + & HDR_MANIP_IPV6_SRC)
38194 + tableSize += HMCD_IPV6_ADDR_SIZE;
38195 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38196 + & HDR_MANIP_IPV6_DST)
38197 + tableSize += HMCD_IPV6_ADDR_SIZE;
38198 + break;
38199 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38200 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38201 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38202 + /* we implement this case with the update-checksum descriptor */
38203 + tableSize += HMCD_BASIC_SIZE;
38204 + else
38205 + /* we implement this case with the TCP/UDP-update descriptor */
38206 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38207 + break;
38208 + default:
38209 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38210 + ("Unknown fieldUpdateParams.type"));
38211 + }
38212 + }
38213 +
38214 + if (p_FmPcdManipParams->u.hdr.custom)
38215 + {
38216 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38217 + {
38218 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38219 + {
38220 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
38221 + dataSize +=
38222 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38223 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38224 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38225 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38226 + dataSize += 2;
38227 + }
38228 + break;
38229 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38230 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
38231 + break;
38232 + default:
38233 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38234 + ("Unknown customParams.type"));
38235 + }
38236 + }
38237 +
38238 + *p_TableSize = tableSize;
38239 + *p_DataSize = dataSize;
38240 +
38241 + return E_OK;
38242 +}
38243 +
38244 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
38245 + uint8_t *parseArrayOffset)
38246 +{
38247 + e_NetHeaderType hdr = p_HdrInfo->hdr;
38248 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
38249 + bool byField = p_HdrInfo->byField;
38250 + t_FmPcdFields field;
38251 +
38252 + if (byField)
38253 + field = p_HdrInfo->fullField;
38254 +
38255 + if (byField)
38256 + {
38257 + switch (hdr)
38258 + {
38259 + case (HEADER_TYPE_ETH):
38260 + switch (field.eth)
38261 + {
38262 + case (NET_HEADER_FIELD_ETH_TYPE):
38263 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
38264 + break;
38265 + default:
38266 + RETURN_ERROR(
38267 + MAJOR,
38268 + E_NOT_SUPPORTED,
38269 + ("Header manipulation of the type Ethernet with this field not supported"));
38270 + }
38271 + break;
38272 + case (HEADER_TYPE_VLAN):
38273 + switch (field.vlan)
38274 + {
38275 + case (NET_HEADER_FIELD_VLAN_TCI):
38276 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38277 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38278 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
38279 + else
38280 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38281 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
38282 + break;
38283 + default:
38284 + RETURN_ERROR(
38285 + MAJOR,
38286 + E_NOT_SUPPORTED,
38287 + ("Header manipulation of the type VLAN with this field not supported"));
38288 + }
38289 + break;
38290 + default:
38291 + RETURN_ERROR(
38292 + MAJOR,
38293 + E_NOT_SUPPORTED,
38294 + ("Header manipulation of this header by field not supported"));
38295 + }
38296 + }
38297 + else
38298 + {
38299 + switch (hdr)
38300 + {
38301 + case (HEADER_TYPE_ETH):
38302 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
38303 + break;
38304 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
38305 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
38306 + break;
38307 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
38308 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
38309 + break;
38310 + case (HEADER_TYPE_LLC_SNAP):
38311 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
38312 + break;
38313 + case (HEADER_TYPE_PPPoE):
38314 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
38315 + break;
38316 + case (HEADER_TYPE_MPLS):
38317 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38318 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38319 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
38320 + else
38321 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
38322 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
38323 + break;
38324 + case (HEADER_TYPE_IPv4):
38325 + case (HEADER_TYPE_IPv6):
38326 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
38327 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
38328 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
38329 + else
38330 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
38331 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
38332 + break;
38333 + case (HEADER_TYPE_MINENCAP):
38334 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
38335 + break;
38336 + case (HEADER_TYPE_GRE):
38337 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
38338 + break;
38339 + case (HEADER_TYPE_TCP):
38340 + case (HEADER_TYPE_UDP):
38341 + case (HEADER_TYPE_IPSEC_AH):
38342 + case (HEADER_TYPE_IPSEC_ESP):
38343 + case (HEADER_TYPE_DCCP):
38344 + case (HEADER_TYPE_SCTP):
38345 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
38346 + break;
38347 + case (HEADER_TYPE_CAPWAP):
38348 + case (HEADER_TYPE_CAPWAP_DTLS):
38349 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
38350 + break;
38351 + default:
38352 + RETURN_ERROR(
38353 + MAJOR,
38354 + E_NOT_SUPPORTED,
38355 + ("Header manipulation of this header is not supported"));
38356 + }
38357 + }
38358 + return E_OK;
38359 +}
38360 +
38361 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
38362 + t_FmPcdManipParams *p_FmPcdManipParams,
38363 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
38364 +{
38365 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
38366 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
38367 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
38368 + p_DestData;
38369 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
38370 + uint8_t j = 0;
38371 +
38372 + if (p_FmPcdManipParams->u.hdr.rmv)
38373 + {
38374 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38375 + == e_FM_PCD_MANIP_RMV_GENERIC)
38376 + {
38377 + /* initialize HMCD */
38378 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
38379 + /* tmp, should be conditional */
38380 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
38381 + << HMCD_RMV_OFFSET_SHIFT;
38382 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
38383 + << HMCD_RMV_SIZE_SHIFT;
38384 + }
38385 + else
38386 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
38387 + == e_FM_PCD_MANIP_RMV_BY_HDR)
38388 + {
38389 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
38390 + {
38391 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
38392 + {
38393 + uint8_t hmcdOpt;
38394 +
38395 + /* initialize HMCD */
38396 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
38397 +
38398 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
38399 + {
38400 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
38401 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
38402 + break;
38403 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
38404 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
38405 + break;
38406 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
38407 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
38408 + break;
38409 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
38410 + hmcdOpt = HMCD_RMV_L2_MPLS;
38411 + break;
38412 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
38413 + hmcdOpt = HMCD_RMV_L2_PPPOE;
38414 + break;
38415 + default:
38416 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38417 + }
38418 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38419 + break;
38420 + }
38421 +#if (DPAA_VERSION >= 11)
38422 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
38423 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
38424 + << HMCD_OC_SHIFT;
38425 + break;
38426 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
38427 + {
38428 + uint8_t prsArrayOffset;
38429 + t_Error err = E_OK;
38430 +
38431 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
38432 + << HMCD_OC_SHIFT;
38433 +
38434 + err =
38435 + GetPrOffsetByHeaderOrField(
38436 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
38437 + &prsArrayOffset);
38438 + ASSERT_COND(!err);
38439 + /* was previously checked */
38440 +
38441 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
38442 + }
38443 + break;
38444 +#endif /* (DPAA_VERSION >= 11) */
38445 + default:
38446 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38447 + ("manip header remove by hdr type!"));
38448 + }
38449 + }
38450 +
38451 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38452 + /* save a pointer to the "last" indication word */
38453 + p_Last = p_TmpHmct;
38454 + /* advance to next command */
38455 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38456 + }
38457 +
38458 + if (p_FmPcdManipParams->u.hdr.insrt)
38459 + {
38460 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38461 + == e_FM_PCD_MANIP_INSRT_GENERIC)
38462 + {
38463 + /* initialize HMCD */
38464 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
38465 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
38466 + << HMCD_OC_SHIFT;
38467 + else
38468 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
38469 +
38470 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
38471 + << HMCD_INSRT_OFFSET_SHIFT;
38472 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
38473 + << HMCD_INSRT_SIZE_SHIFT;
38474 +
38475 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
38476 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
38477 +
38478 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38479 + /* save a pointer to the "last" indication word */
38480 + p_Last = p_TmpHmct;
38481 +
38482 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38483 +
38484 + /* initialize data to be inserted */
38485 + /* if size is not a multiple of 4, padd with 0's */
38486 + origSize = size;
38487 + remain = (uint8_t)(size % 4);
38488 + if (remain)
38489 + {
38490 + size += (uint8_t)(4 - remain);
38491 + p_LocalData = (uint32_t *)XX_Malloc(size);
38492 + memset((uint8_t *)p_LocalData, 0, size);
38493 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
38494 + }
38495 + else
38496 + p_LocalData = (uint32_t*)p_UsrData;
38497 +
38498 + /* initialize data and advance pointer to next command */
38499 + MemCpy8(p_TmpHmct, p_LocalData, size);
38500 + p_TmpHmct += size / sizeof(uint32_t);
38501 +
38502 + if (remain)
38503 + XX_Free(p_LocalData);
38504 + }
38505 +
38506 + else
38507 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
38508 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
38509 + {
38510 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
38511 + {
38512 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
38513 + {
38514 + uint8_t hmcdOpt;
38515 +
38516 + /* initialize HMCD */
38517 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
38518 + << HMCD_OC_SHIFT;
38519 +
38520 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
38521 + {
38522 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
38523 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
38524 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
38525 + else
38526 + hmcdOpt = HMCD_INSRT_L2_MPLS;
38527 + break;
38528 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
38529 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
38530 + break;
38531 + default:
38532 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
38533 + }
38534 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
38535 +
38536 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38537 + /* save a pointer to the "last" indication word */
38538 + p_Last = p_TmpHmct;
38539 +
38540 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38541 +
38542 + /* set size and pointer of user's data */
38543 + size =
38544 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
38545 +
38546 + ASSERT_COND(p_TmpData);
38547 + MemCpy8(
38548 + p_TmpData,
38549 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
38550 + size);
38551 + tmpReg =
38552 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
38553 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
38554 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38555 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38556 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38557 + p_TmpData += size;
38558 + }
38559 + break;
38560 +#if (DPAA_VERSION >= 11)
38561 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
38562 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
38563 + << HMCD_OC_SHIFT;
38564 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
38565 + tmpReg |= HMCD_IP_L4_CS_CALC;
38566 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
38567 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
38568 + tmpReg |= HMCD_IP_OR_QOS;
38569 + tmpReg |=
38570 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
38571 + & HMCD_IP_LAST_PID_MASK;
38572 + tmpReg |=
38573 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38574 + << HMCD_IP_SIZE_SHIFT)
38575 + & HMCD_IP_SIZE_MASK);
38576 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
38577 + tmpReg |= HMCD_IP_DF_MODE;
38578 +
38579 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38580 +
38581 + /* save a pointer to the "last" indication word */
38582 + p_Last = p_TmpHmct;
38583 +
38584 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38585 +
38586 + /* set IP id */
38587 + ASSERT_COND(p_TmpData);
38588 + WRITE_UINT16(
38589 + *(uint16_t*)p_TmpData,
38590 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
38591 + WRITE_UINT32(
38592 + *p_TmpHmct,
38593 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38594 + p_TmpData += 2;
38595 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38596 +
38597 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
38598 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
38599 +
38600 + MemCpy8(
38601 + p_TmpHmct,
38602 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
38603 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
38604 + p_TmpHmct +=
38605 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
38606 + / 4;
38607 + break;
38608 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
38609 + tmpReg = HMCD_INSRT_UDP_LITE;
38610 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
38611 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
38612 + << HMCD_OC_SHIFT;
38613 +
38614 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38615 +
38616 + /* save a pointer to the "last" indication word */
38617 + p_Last = p_TmpHmct;
38618 +
38619 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38620 +
38621 + MemCpy8(
38622 + p_TmpHmct,
38623 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38624 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38625 + p_TmpHmct +=
38626 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38627 + / 4;
38628 + break;
38629 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
38630 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
38631 + << HMCD_OC_SHIFT;
38632 + tmpReg |= HMCD_CAPWAP_INSRT;
38633 +
38634 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38635 +
38636 + /* save a pointer to the "last" indication word */
38637 + p_Last = p_TmpHmct;
38638 +
38639 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38640 +
38641 + MemCpy8(
38642 + p_TmpHmct,
38643 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
38644 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
38645 + p_TmpHmct +=
38646 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
38647 + / 4;
38648 + break;
38649 +#endif /* (DPAA_VERSION >= 11) */
38650 + default:
38651 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
38652 + ("manip header insert by header type!"));
38653 +
38654 + }
38655 + }
38656 + }
38657 +
38658 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
38659 + {
38660 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
38661 + {
38662 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
38663 + /* set opcode */
38664 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
38665 + << HMCD_OC_SHIFT;
38666 +
38667 + /* set mode & table pointer */
38668 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38669 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
38670 + {
38671 + /* set Mode */
38672 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
38673 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
38674 + /* set VPRI default */
38675 + tmpReg |=
38676 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
38677 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38678 + /* save a pointer to the "last" indication word */
38679 + p_Last = p_TmpHmct;
38680 + /* write the table pointer into the Manip descriptor */
38681 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38682 +
38683 + tmpReg = 0;
38684 + ASSERT_COND(p_TmpData);
38685 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
38686 + {
38687 + /* first we build from each 8 values a 32bit register */
38688 + tmpReg |=
38689 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
38690 + << (32 - 4 * (j + 1));
38691 + j++;
38692 + /* Than we write this register to the next table word
38693 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
38694 + if ((i % 8) == 7)
38695 + {
38696 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
38697 + tmpReg);
38698 + tmpReg = 0;
38699 + j = 0;
38700 + }
38701 + }
38702 +
38703 + WRITE_UINT32(
38704 + *p_TmpHmct,
38705 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38706 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38707 +
38708 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
38709 + }
38710 + else
38711 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
38712 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
38713 + {
38714 + /* set Mode */
38715 + /* line commented out as it has no-side-effect ('0' value). */
38716 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
38717 + /* set VPRI parameter */
38718 + tmpReg |=
38719 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
38720 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38721 + /* save a pointer to the "last" indication word */
38722 + p_Last = p_TmpHmct;
38723 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38724 + }
38725 + break;
38726 +
38727 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
38728 + /* set opcode */
38729 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
38730 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38731 + & HDR_MANIP_IPV4_TTL)
38732 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
38733 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38734 + & HDR_MANIP_IPV4_TOS)
38735 + {
38736 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
38737 + tmpReg |=
38738 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
38739 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
38740 + }
38741 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38742 + & HDR_MANIP_IPV4_ID)
38743 + tmpReg |= HMCD_IPV4_UPDATE_ID;
38744 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38745 + & HDR_MANIP_IPV4_SRC)
38746 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
38747 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38748 + & HDR_MANIP_IPV4_DST)
38749 + tmpReg |= HMCD_IPV4_UPDATE_DST;
38750 + /* write the first 4 bytes of the descriptor */
38751 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38752 + /* save a pointer to the "last" indication word */
38753 + p_Last = p_TmpHmct;
38754 +
38755 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38756 +
38757 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38758 + & HDR_MANIP_IPV4_ID)
38759 + {
38760 + ASSERT_COND(p_TmpData);
38761 + WRITE_UINT16(
38762 + *(uint16_t*)p_TmpData,
38763 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
38764 + WRITE_UINT32(
38765 + *p_TmpHmct,
38766 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
38767 + p_TmpData += 2;
38768 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38769 + }
38770 +
38771 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38772 + & HDR_MANIP_IPV4_SRC)
38773 + {
38774 + WRITE_UINT32(
38775 + *p_TmpHmct,
38776 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
38777 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38778 + }
38779 +
38780 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
38781 + & HDR_MANIP_IPV4_DST)
38782 + {
38783 + WRITE_UINT32(
38784 + *p_TmpHmct,
38785 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
38786 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
38787 + }
38788 + break;
38789 +
38790 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
38791 + /* set opcode */
38792 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
38793 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38794 + & HDR_MANIP_IPV6_HL)
38795 + tmpReg |= HMCD_IPV6_UPDATE_HL;
38796 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38797 + & HDR_MANIP_IPV6_TC)
38798 + {
38799 + tmpReg |= HMCD_IPV6_UPDATE_TC;
38800 + tmpReg |=
38801 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
38802 + << HMCD_IPV6_UPDATE_TC_SHIFT;
38803 + }
38804 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38805 + & HDR_MANIP_IPV6_SRC)
38806 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
38807 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38808 + & HDR_MANIP_IPV6_DST)
38809 + tmpReg |= HMCD_IPV6_UPDATE_DST;
38810 + /* write the first 4 bytes of the descriptor */
38811 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38812 + /* save a pointer to the "last" indication word */
38813 + p_Last = p_TmpHmct;
38814 +
38815 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38816 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38817 + & HDR_MANIP_IPV6_SRC)
38818 + {
38819 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38820 + {
38821 + memcpy(&tmp_ipv6_addr,
38822 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
38823 + sizeof(uint32_t));
38824 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38825 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38826 + }
38827 + }
38828 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
38829 + & HDR_MANIP_IPV6_DST)
38830 + {
38831 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
38832 + {
38833 + memcpy(&tmp_ipv6_addr,
38834 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
38835 + sizeof(uint32_t));
38836 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
38837 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38838 + }
38839 + }
38840 + break;
38841 +
38842 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
38843 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38844 + == HDR_MANIP_TCP_UDP_CHECKSUM)
38845 + {
38846 + /* we implement this case with the update-checksum descriptor */
38847 + /* set opcode */
38848 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
38849 + << HMCD_OC_SHIFT;
38850 + /* write the first 4 bytes of the descriptor */
38851 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38852 + /* save a pointer to the "last" indication word */
38853 + p_Last = p_TmpHmct;
38854 +
38855 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38856 + }
38857 + else
38858 + {
38859 + /* we implement this case with the TCP/UDP update descriptor */
38860 + /* set opcode */
38861 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
38862 + << HMCD_OC_SHIFT;
38863 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38864 + & HDR_MANIP_TCP_UDP_DST)
38865 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
38866 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38867 + & HDR_MANIP_TCP_UDP_SRC)
38868 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
38869 + /* write the first 4 bytes of the descriptor */
38870 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38871 + /* save a pointer to the "last" indication word */
38872 + p_Last = p_TmpHmct;
38873 +
38874 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38875 +
38876 + tmpReg = 0;
38877 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38878 + & HDR_MANIP_TCP_UDP_SRC)
38879 + tmpReg |=
38880 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
38881 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
38882 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
38883 + & HDR_MANIP_TCP_UDP_DST)
38884 + tmpReg |=
38885 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
38886 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38887 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38888 + }
38889 + break;
38890 +
38891 + default:
38892 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38893 + ("Unknown fieldUpdateParams.type"));
38894 + }
38895 + }
38896 +
38897 + if (p_FmPcdManipParams->u.hdr.custom)
38898 + {
38899 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
38900 + {
38901 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
38902 + /* set opcode */
38903 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
38904 +
38905 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
38906 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
38907 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38908 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
38909 + /* line commented out as it has no-side-effect ('0' value). */
38910 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
38911 + else
38912 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38913 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38914 + {
38915 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
38916 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
38917 + tmpReg |= HMCD_IP_REPLACE_ID;
38918 + }
38919 + else
38920 + RETURN_ERROR(
38921 + MINOR,
38922 + E_NOT_SUPPORTED,
38923 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
38924 +
38925 + /* write the first 4 bytes of the descriptor */
38926 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38927 + /* save a pointer to the "last" indication word */
38928 + p_Last = p_TmpHmct;
38929 +
38930 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
38931 +
38932 + size =
38933 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
38934 + ASSERT_COND(p_TmpData);
38935 + MemCpy8(
38936 + p_TmpData,
38937 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
38938 + size);
38939 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
38940 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
38941 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
38942 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38943 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38944 + p_TmpData += size;
38945 +
38946 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
38947 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
38948 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
38949 + {
38950 + WRITE_UINT16(
38951 + *(uint16_t*)p_TmpData,
38952 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
38953 + WRITE_UINT32(
38954 + *p_TmpHmct,
38955 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
38956 + p_TmpData += 2;
38957 + }
38958 + p_TmpHmct += HMCD_PTR_SIZE / 4;
38959 + break;
38960 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
38961 + /* set opcode */
38962 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
38963 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
38964 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
38965 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
38966 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38967 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
38968 +
38969 + /* write the first 4 bytes of the descriptor */
38970 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38971 + /* save a pointer to the "last" indication word */
38972 + p_Last = p_TmpHmct;
38973 +
38974 + p_TmpHmct += HMCD_BASIC_SIZE/4;
38975 +
38976 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
38977 + {
38978 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
38979 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
38980 + /* write the next 4 bytes of the descriptor */
38981 + WRITE_UINT32(*p_TmpHmct, tmpReg);
38982 + }
38983 + p_TmpHmct += HMCD_PARAM_SIZE/4;
38984 + break;
38985 + default:
38986 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
38987 + ("Unknown customParams.type"));
38988 + }
38989 + }
38990 +
38991 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
38992 + the old table and should be freed */
38993 + if (p_FmPcdManipParams->h_NextManip
38994 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
38995 + && (MANIP_DONT_REPARSE(p_Manip)))
38996 + {
38997 + if (new)
38998 + {
38999 + /* If this is the first time this manip is created we need to free unused memory. If it
39000 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
39001 + * table - no allocation, no free */
39002 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
39003 +
39004 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
39005 + }
39006 + }
39007 + else
39008 + {
39009 + ASSERT_COND(p_Last);
39010 + /* set the "last" indication on the last command of the current table */
39011 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
39012 + }
39013 +
39014 + return E_OK;
39015 +}
39016 +
39017 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
39018 + t_FmPcdManipParams *p_FmPcdManipParams)
39019 +{
39020 + t_FmPcdManip *p_CurManip;
39021 + t_Error err;
39022 + uint32_t nextSize = 0, totalSize;
39023 + uint16_t tmpReg;
39024 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
39025 +
39026 + /* set Manip structure */
39027 +
39028 + p_Manip->dontParseAfterManip =
39029 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
39030 +
39031 + if (p_FmPcdManipParams->h_NextManip)
39032 + { /* Next Header manipulation exists */
39033 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
39034 +
39035 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
39036 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
39037 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
39038 + else /* either parsing is required or next manip is Frag; no table merging. */
39039 + p_Manip->cascaded = TRUE;
39040 + /* pass up the "cascaded" attribute. The whole chain is cascaded
39041 + * if something is cascaded along the way. */
39042 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
39043 + p_Manip->cascaded = TRUE;
39044 + }
39045 +
39046 + /* Allocate new table */
39047 + /* calculate table size according to manip parameters */
39048 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
39049 + &p_Manip->dataSize);
39050 + if (err)
39051 + RETURN_ERROR(MINOR, err, NO_MSG);
39052 +
39053 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
39054 +
39055 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
39056 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
39057 + if (!p_Manip->p_Hmct)
39058 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
39059 +
39060 + if (p_Manip->dataSize)
39061 + p_Manip->p_Data =
39062 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
39063 +
39064 + /* update shadow size to allow runtime replacement of Header manipulation */
39065 + /* The allocated shadow is divided as follows:
39066 + 0 . . . 16 . . .
39067 + --------------------------------
39068 + | Shadow | Shadow HMTD |
39069 + | HMTD | Match Table |
39070 + | (16 bytes) | (maximal size) |
39071 + --------------------------------
39072 + */
39073 +
39074 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
39075 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
39076 + if (err != E_OK)
39077 + {
39078 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
39079 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39080 + ("MURAM allocation for HdrManip node shadow"));
39081 + }
39082 +
39083 + if (p_FmPcdManipParams->h_NextManip
39084 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
39085 + && (MANIP_DONT_REPARSE(p_Manip)))
39086 + {
39087 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
39088 + e_MANIP_HMCT);
39089 + p_CurManip = p_FmPcdManipParams->h_NextManip;
39090 + /* Run till the last Manip (which is the first to configure) */
39091 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39092 + p_CurManip = p_CurManip->h_NextManip;
39093 +
39094 + while (p_CurManip)
39095 + {
39096 + /* If this is a unified table, point to the part of the table
39097 + * which is the relative offset in HMCT.
39098 + */
39099 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
39100 + (p_Manip->tableSize +
39101 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
39102 + PTR_TO_UINT(p_OldHmct))));
39103 + if (p_CurManip->p_Data)
39104 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
39105 + (p_Manip->tableSize +
39106 + (PTR_TO_UINT(p_CurManip->p_Data) -
39107 + PTR_TO_UINT(p_OldHmct))));
39108 + else
39109 + p_TmpDataPtr = NULL;
39110 +
39111 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39112 + p_TmpDataPtr, FALSE);
39113 + /* update old manip table pointer */
39114 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
39115 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
39116 +
39117 + p_CurManip = p_CurManip->h_PrevManip;
39118 + }
39119 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
39120 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
39121 + p_OldHmct);
39122 + }
39123 +
39124 + /* Fill table */
39125 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
39126 + p_Manip->p_Data, TRUE);
39127 + if (err)
39128 + {
39129 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
39130 + RETURN_ERROR(MINOR, err, NO_MSG);
39131 + }
39132 +
39133 + /* Build HMTD (table descriptor) */
39134 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
39135 +
39136 + /* add parseAfterManip */
39137 + if (!p_Manip->dontParseAfterManip)
39138 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
39139 +
39140 + /* create cascade */
39141 + /*if (p_FmPcdManipParams->h_NextManip
39142 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
39143 + if (p_Manip->cascaded)
39144 + {
39145 + uint16_t nextAd;
39146 + /* indicate that there's another HM table descriptor */
39147 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
39148 + /* get address of next HMTD (table descriptor; h_Ad).
39149 + * If the next HMTD was removed due to table unifing, get the address
39150 + * of the "next next" as written in the h_Ad of the next h_Manip node.
39151 + */
39152 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
39153 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
39154 + else
39155 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
39156 +
39157 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
39158 + }
39159 +
39160 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
39161 + WRITE_UINT32(
39162 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
39163 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
39164 +
39165 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
39166 +
39167 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
39168 + {
39169 + /* The HMTD of the next Manip is never going to be used */
39170 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
39171 + FM_MURAM_FreeMem(
39172 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
39173 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39174 + else
39175 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
39176 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
39177 + }
39178 +
39179 + return E_OK;
39180 +}
39181 +
39182 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
39183 + t_FmPcdManipParams *p_FmPcdManipParams)
39184 +{
39185 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
39186 + uint16_t newSize;
39187 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39188 + t_Error err;
39189 + t_FmPcdManip *p_CurManip = p_Manip;
39190 +
39191 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
39192 + if (err)
39193 + RETURN_ERROR(MINOR, err, NO_MSG);
39194 +
39195 + /* check coherency of new table parameters */
39196 + if (newSize > p_Manip->tableSize)
39197 + RETURN_ERROR(
39198 + MINOR,
39199 + E_INVALID_VALUE,
39200 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
39201 + if (newDataSize > p_Manip->dataSize)
39202 + RETURN_ERROR(
39203 + MINOR,
39204 + E_INVALID_VALUE,
39205 + ("New Hdr Manip configuration requires larger size than current one (data)."));
39206 + if (p_FmPcdManipParams->h_NextManip)
39207 + RETURN_ERROR(
39208 + MINOR, E_INVALID_VALUE,
39209 + ("New Hdr Manip configuration can not contain h_NextManip."));
39210 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
39211 + RETURN_ERROR(
39212 + MINOR,
39213 + E_INVALID_VALUE,
39214 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
39215 + if (p_Manip->dontParseAfterManip
39216 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
39217 + RETURN_ERROR(
39218 + MINOR,
39219 + E_INVALID_VALUE,
39220 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
39221 +
39222 + p_Manip->tableSize = newSize;
39223 + p_Manip->dataSize = newDataSize;
39224 +
39225 + /* Build the new table in the shadow */
39226 + if (!MANIP_IS_UNIFIED(p_Manip))
39227 + {
39228 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
39229 + if (p_Manip->p_Data)
39230 + p_TmpDataPtr =
39231 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
39232 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
39233 +
39234 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
39235 + FALSE);
39236 + }
39237 + else
39238 + {
39239 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39240 + ASSERT_COND(p_WholeHmct);
39241 +
39242 + /* Run till the last Manip (which is the first to configure) */
39243 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39244 + p_CurManip = p_CurManip->h_NextManip;
39245 +
39246 + while (p_CurManip)
39247 + {
39248 + /* If this is a non-head node in a unified table, point to the part of the shadow
39249 + * which is the relative offset in HMCT.
39250 + * else, point to the beginning of the
39251 + * shadow table (we save 16 for the HMTD.
39252 + */
39253 + p_TmpHmctPtr =
39254 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39255 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
39256 + if (p_CurManip->p_Data)
39257 + p_TmpDataPtr =
39258 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
39259 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
39260 +
39261 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39262 + p_TmpDataPtr, FALSE);
39263 + p_CurManip = p_CurManip->h_PrevManip;
39264 + }
39265 + }
39266 +
39267 + return E_OK;
39268 +}
39269 +
39270 +static t_Error CreateManipActionBackToOrig(
39271 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
39272 +{
39273 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
39274 + t_FmPcdManip *p_CurManip = p_Manip;
39275 +
39276 + /* Build the new table in the shadow */
39277 + if (!MANIP_IS_UNIFIED(p_Manip))
39278 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
39279 + FALSE);
39280 + else
39281 + {
39282 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
39283 + ASSERT_COND(p_WholeHmct);
39284 +
39285 + /* Run till the last Manip (which is the first to configure) */
39286 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39287 + p_CurManip = p_CurManip->h_NextManip;
39288 +
39289 + while (p_CurManip)
39290 + {
39291 + /* If this is a unified table, point to the part of the table
39292 + * which is the relative offset in HMCT.
39293 + */
39294 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
39295 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
39296 +
39297 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
39298 + p_TmpDataPtr, FALSE);
39299 +
39300 + p_CurManip = p_CurManip->h_PrevManip;
39301 + }
39302 + }
39303 +
39304 + return E_OK;
39305 +}
39306 +
39307 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
39308 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
39309 +{
39310 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
39311 + t_Handle p_Ad;
39312 + uint32_t tmpReg32 = 0;
39313 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
39314 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
39315 +
39316 + switch (p_Manip->opcode)
39317 + {
39318 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
39319 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39320 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39321 + {
39322 + tmpReg32 =
39323 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
39324 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39325 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
39326 + tmpReg32;
39327 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39328 + p_Manip->icOffset = icOffset;
39329 + }
39330 + else
39331 + {
39332 + if (p_Manip->icOffset != icOffset)
39333 + RETURN_ERROR(
39334 + MAJOR,
39335 + E_INVALID_VALUE,
39336 + ("this manipulation was updated previously by different value"););
39337 + }
39338 + break;
39339 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
39340 + if (p_Manip->h_Frag)
39341 + {
39342 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
39343 + {
39344 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
39345 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
39346 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
39347 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
39348 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
39349 + p_Manip->icOffset = icOffset;
39350 + }
39351 + else
39352 + {
39353 + if (p_Manip->icOffset != icOffset)
39354 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
39355 + }
39356 + }
39357 + break;
39358 + }
39359 +
39360 + return E_OK;
39361 +}
39362 +
39363 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
39364 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
39365 +{
39366 +
39367 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39368 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39369 + t_Error err;
39370 + uint32_t tmpReg32;
39371 +
39372 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39373 +
39374 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
39375 + SANITY_CHECK_RETURN_ERROR(
39376 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
39377 + E_INVALID_STATE);
39378 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
39379 +
39380 + if (p_Manip->updateParams)
39381 + {
39382 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
39383 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39384 + RETURN_ERROR(
39385 + MAJOR, E_INVALID_STATE,
39386 + ("in this stage parameters from Port has not be updated"));
39387 +
39388 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39389 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39390 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39391 +
39392 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39393 + if (err)
39394 + RETURN_ERROR(MAJOR, err, NO_MSG);
39395 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39396 + RETURN_ERROR(
39397 + MAJOR, E_INVALID_STATE,
39398 + ("Parser result offset wasn't configured previousely"));
39399 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39400 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
39401 +#endif
39402 + }
39403 + else
39404 + if (validate)
39405 + {
39406 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
39407 + || (p_Manip->updateParams & OFFSET_OF_PR))
39408 + RETURN_ERROR(
39409 + MAJOR, E_INVALID_STATE,
39410 + ("in this stage parameters from Port has be updated"));
39411 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39412 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
39413 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
39414 +
39415 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39416 + if (err)
39417 + RETURN_ERROR(MAJOR, err, NO_MSG);
39418 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
39419 + RETURN_ERROR(
39420 + MAJOR, E_INVALID_STATE,
39421 + ("Parser result offset wasn't configured previousely"));
39422 +
39423 + }
39424 +
39425 + ASSERT_COND(p_Ad);
39426 +
39427 + if (p_Manip->updateParams & OFFSET_OF_PR)
39428 + {
39429 + tmpReg32 = 0;
39430 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
39431 + WRITE_UINT32(p_Ad->matchTblPtr,
39432 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
39433 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39434 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39435 + }
39436 + else
39437 + if (validate)
39438 + {
39439 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
39440 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
39441 + RETURN_ERROR(
39442 + MAJOR,
39443 + E_INVALID_STATE,
39444 + ("this manipulation was updated previousely by different value"););
39445 + }
39446 +
39447 + return E_OK;
39448 +}
39449 +
39450 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
39451 +{
39452 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
39453 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
39454 + uint32_t tmpReg32 = 0;
39455 +
39456 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39457 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39458 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39459 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) || (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39460 +
39461 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39462 +
39463 + if (p_Manip->updateParams)
39464 + {
39465 +
39466 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39467 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39468 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39469 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39470 + if (!p_SavedManipParams)
39471 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39472 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
39473 +
39474 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39475 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
39476 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39477 +
39478 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39479 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39480 + }
39481 + else if (validate)
39482 + {
39483 +
39484 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
39485 + if (!p_SavedManipParams)
39486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
39487 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
39488 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39489 + }
39490 +
39491 + return E_OK;
39492 +}
39493 +
39494 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
39495 + t_FmPcdManip *p_Manip,
39496 + t_Handle h_Ad,
39497 + bool validate,
39498 + t_Handle h_FmTree)
39499 +{
39500 + t_AdOfTypeContLookup *p_Ad;
39501 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39502 + t_Error err;
39503 + uint32_t tmpReg32 = 0;
39504 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
39505 +
39506 + UNUSED(h_Ad);
39507 +
39508 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39509 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39510 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
39511 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
39512 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
39513 +
39514 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
39515 +
39516 + if (p_Manip->updateParams)
39517 + {
39518 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
39519 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
39520 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39521 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39522 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39523 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39524 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
39525 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
39526 +
39527 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39528 + if (err)
39529 + RETURN_ERROR(MAJOR, err, NO_MSG);
39530 +
39531 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39532 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39533 +
39534 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
39535 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39536 +
39537 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39538 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
39539 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39540 +
39541 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
39542 + }
39543 + else if (validate)
39544 + {
39545 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
39546 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
39547 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39548 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39549 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
39550 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39551 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39552 + if (err)
39553 + RETURN_ERROR(MAJOR, err, NO_MSG);
39554 +
39555 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39556 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
39557 + }
39558 +
39559 + if (p_Manip->updateParams)
39560 + {
39561 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
39562 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
39563 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
39564 +
39565 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39566 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39567 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39568 + }
39569 + else if (validate)
39570 + {
39571 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
39572 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
39573 + }
39574 +
39575 + return E_OK;
39576 +}
39577 +
39578 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
39579 + t_Handle h_FmPort,
39580 + t_FmPcdManip *p_Manip,
39581 + t_Handle h_Ad,
39582 + bool validate)
39583 +{
39584 + t_CapwapReasmPram *p_ReassmTbl;
39585 + t_Error err;
39586 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
39587 + uint8_t i = 0;
39588 + uint16_t size;
39589 + uint32_t tmpReg32;
39590 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
39591 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
39592 +
39593 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
39594 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
39595 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
39596 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
39597 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
39598 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
39599 +
39600 + if (p_Manip->h_FmPcd != h_FmPcd)
39601 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
39602 + ("handler of PCD previously was initiated by different value"));
39603 +
39604 + UNUSED(h_Ad);
39605 +
39606 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
39607 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
39608 +
39609 + if (p_Manip->updateParams)
39610 + {
39611 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
39612 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
39613 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
39614 + !(p_Manip->updateParams & HW_PORT_ID)) ||
39615 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
39616 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
39617 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
39618 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
39619 +
39620 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
39621 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39622 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39623 +
39624 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39625 + if (err)
39626 + RETURN_ERROR(MAJOR, err, NO_MSG);
39627 +
39628 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39629 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
39630 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39631 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
39632 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39633 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39634 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
39635 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
39636 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
39637 + }
39638 + else if (validate)
39639 + {
39640 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
39641 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
39642 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
39643 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
39644 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
39645 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
39646 + (p_Manip->updateParams & HW_PORT_ID)))
39647 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
39648 +
39649 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
39650 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
39651 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
39652 +
39653 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
39654 + if (err)
39655 + RETURN_ERROR(MAJOR, err, NO_MSG);
39656 +
39657 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
39658 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
39659 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
39660 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
39661 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
39662 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
39663 + }
39664 +
39665 + if (p_Manip->updateParams)
39666 + {
39667 + if (p_Manip->updateParams & NUM_OF_TASKS)
39668 + {
39669 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
39670 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
39671 + if (size > 255)
39672 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
39673 +
39674 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
39675 +
39676 + /*p_ReassmFrmDescrIndxPoolTbl*/
39677 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
39678 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39679 + (uint32_t)(size + 1),
39680 + 4);
39681 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
39682 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
39683 +
39684 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
39685 +
39686 + for ( i = 0; i < size; i++)
39687 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
39688 +
39689 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
39690 +
39691 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
39692 +
39693 + /*p_ReassmFrmDescrPoolTbl*/
39694 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
39695 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39696 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
39697 + 4);
39698 +
39699 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
39700 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
39701 +
39702 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
39703 +
39704 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
39705 +
39706 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
39707 +
39708 + /*p_TimeOutTbl*/
39709 +
39710 + p_Manip->capwapFragParams.p_TimeOutTbl =
39711 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39712 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
39713 + 4);
39714 +
39715 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
39716 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
39717 +
39718 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
39719 +
39720 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
39721 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
39722 +
39723 + p_Manip->updateParams &= ~NUM_OF_TASKS;
39724 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
39725 + }
39726 +
39727 + if (p_Manip->updateParams & OFFSET_OF_DATA)
39728 + {
39729 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
39730 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39731 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
39732 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39733 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
39734 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
39735 + }
39736 +
39737 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39738 + {
39739 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
39740 +
39741 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
39742 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
39743 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
39744 +
39745 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
39746 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
39747 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
39748 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39749 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39750 + }
39751 + else
39752 + {
39753 + p_Manip->capwapFragParams.prOffset = 0xff;
39754 + p_Manip->updateParams &= ~OFFSET_OF_PR;
39755 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
39756 + }
39757 +
39758 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
39759 + p_Manip->updateParams &= ~HW_PORT_ID;
39760 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
39761 +
39762 + /*timeout hc */
39763 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
39764 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
39765 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
39766 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
39767 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
39768 + }
39769 +
39770 + else if (validate)
39771 + {
39772 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
39773 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
39774 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
39775 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
39776 +
39777 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
39778 + {
39779 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
39780 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39781 + }
39782 + else
39783 + {
39784 + if (p_Manip->capwapFragParams.prOffset != 0xff)
39785 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
39786 + }
39787 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
39788 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
39789 + }
39790 +
39791 + return E_OK;
39792 +}
39793 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
39794 +
39795 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
39796 +{
39797 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39798 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
39799 + t_Error err = E_OK;
39800 + uint8_t result;
39801 + uint32_t bitFor1Micro, tsbs, log2num;
39802 +
39803 + ASSERT_COND(p_FmPcd);
39804 + ASSERT_COND(h_ReasmCommonPramTbl);
39805 +
39806 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39807 + if (bitFor1Micro == 0)
39808 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39809 +
39810 + bitFor1Micro = 32 - bitFor1Micro;
39811 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
39812 + tsbs = bitFor1Micro - log2num;
39813 +
39814 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
39815 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
39816 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
39817 + ccReassmTimeoutParams.activate = TRUE;
39818 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
39819 + &result)) != E_OK)
39820 + RETURN_ERROR(MAJOR, err, NO_MSG);
39821 +
39822 + switch (result)
39823 + {
39824 + case (0):
39825 + return E_OK;
39826 + case (1):
39827 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
39828 + case (2):
39829 + RETURN_ERROR(
39830 + MAJOR, E_NO_MEMORY,
39831 + ("failed to allocate internal buffer from the HC-Port"));
39832 + case (3):
39833 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
39834 + ("'Disable Timeout Task' with invalid IPRCPT"));
39835 + case (4):
39836 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
39837 + case (5):
39838 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
39839 + default:
39840 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
39841 + }
39842 + return E_OK;
39843 +}
39844 +
39845 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
39846 +{
39847 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
39848 + uint64_t tmpReg64, size;
39849 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
39850 + t_Error err = E_OK;
39851 +
39852 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
39853 + if (bitFor1Micro == 0)
39854 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
39855 +
39856 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
39857 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
39858 + p_Manip->reassmParams.p_ReassCommonTbl =
39859 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
39860 + p_FmPcd->h_FmMuram,
39861 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
39862 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
39863 +
39864 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
39865 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39866 + ("MURAM alloc for Reassembly common parameters table"));
39867 +
39868 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
39869 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
39870 +
39871 + /* Setting the TimeOut Mode.*/
39872 + tmpReg32 = 0;
39873 + if (p_Manip->reassmParams.timeOutMode
39874 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
39875 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
39876 +
39877 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
39878 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
39879 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
39880 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
39881 + tmpReg32);
39882 +
39883 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
39884 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
39885 +
39886 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
39887 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
39888 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
39889 + (uint32_t)(size * 2),
39890 + 256));
39891 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
39892 + RETURN_ERROR(
39893 + MAJOR, E_NO_MEMORY,
39894 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
39895 +
39896 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
39897 + 0, (uint32_t)(size * 2));
39898 +
39899 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
39900 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
39901 + The last entry in this pool must contain the index zero*/
39902 + for (i = 0; i < (size - 1); i++)
39903 + WRITE_UINT16(
39904 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
39905 + (uint16_t)(i+1));
39906 +
39907 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
39908 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39909 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
39910 + - p_FmPcd->physicalMuramBase);
39911 + WRITE_UINT32(
39912 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
39913 + tmpReg32);
39914 +
39915 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
39916 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
39917 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
39918 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
39919 +
39920 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
39921 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
39922 +
39923 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
39924 + (uint32_t)(size * 64));
39925 +
39926 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
39927 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
39928 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
39929 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39930 + & FM_PCD_MANIP_REASM_LIODN_MASK)
39931 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
39932 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
39933 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
39934 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
39935 + WRITE_UINT32(
39936 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
39937 + (uint32_t)(tmpReg64 >> 32));
39938 + WRITE_UINT32(
39939 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
39940 + (uint32_t)tmpReg64);
39941 +
39942 + /*Allocation of the TimeOut table - This table resides in the MURAM.
39943 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
39944 + p_Manip->reassmParams.timeOutTblAddr =
39945 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
39946 +
39947 + if (!p_Manip->reassmParams.timeOutTblAddr)
39948 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
39949 + ("MURAM alloc for Reassembly timeout table"));
39950 +
39951 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
39952 + (uint16_t)(size * 8));
39953 +
39954 + /* Sets the TimeOut table offset from MURAM */
39955 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
39956 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
39957 + - p_FmPcd->physicalMuramBase);
39958 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
39959 + tmpReg32);
39960 +
39961 + /* Sets the Expiration Delay */
39962 + tmpReg32 = 0;
39963 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
39964 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
39965 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
39966 + tmpReg32);
39967 +
39968 + err = FmPcdRegisterReassmPort(p_FmPcd,
39969 + p_Manip->reassmParams.p_ReassCommonTbl);
39970 + if (err != E_OK)
39971 + {
39972 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
39973 + p_Manip->reassmParams.p_ReassCommonTbl);
39974 + RETURN_ERROR(MAJOR, err, ("port registration"));
39975 + }
39976 +
39977 + return err;
39978 +}
39979 +
39980 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
39981 +{
39982 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
39983 + uint32_t tmpReg32, autoLearnHashTblSize;
39984 + uint32_t numOfWays, setSize, setSizeCode, keySize;
39985 + uint32_t waySize, numOfSets, numOfEntries;
39986 + uint64_t tmpReg64;
39987 + uint16_t minFragSize;
39988 + uint16_t maxReassemSize;
39989 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
39990 + t_ReassTbl **p_ReassTbl;
39991 +
39992 + switch (hdr)
39993 + {
39994 + case HEADER_TYPE_IPv4:
39995 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
39996 + p_AutoLearnHashTblAddr =
39997 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
39998 + p_AutoLearnSetLockTblAddr =
39999 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
40000 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
40001 + maxReassemSize = 0;
40002 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
40003 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
40004 + break;
40005 + case HEADER_TYPE_IPv6:
40006 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
40007 + p_AutoLearnHashTblAddr =
40008 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
40009 + p_AutoLearnSetLockTblAddr =
40010 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
40011 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
40012 + maxReassemSize = 0;
40013 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
40014 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
40015 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
40016 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
40017 + break;
40018 + case HEADER_TYPE_CAPWAP:
40019 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
40020 + p_AutoLearnHashTblAddr =
40021 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
40022 + p_AutoLearnSetLockTblAddr =
40023 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
40024 + minFragSize = 0;
40025 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
40026 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
40027 + keySize = 4;
40028 + break;
40029 + default:
40030 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
40031 + }
40032 + keySize += 2; /* 2 bytes reserved for RFDIndex */
40033 +#if (DPAA_VERSION >= 11)
40034 + keySize += 2; /* 2 bytes reserved */
40035 +#endif /* (DPAA_VERSION >= 11) */
40036 + waySize = ROUND_UP(keySize, 8);
40037 +
40038 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
40039 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
40040 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
40041 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
40042 + if (!*p_ReassTbl)
40043 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
40044 + ("MURAM alloc for Reassembly specific parameters table"));
40045 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
40046 +
40047 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
40048 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
40049 + - p_FmPcd->physicalMuramBase);
40050 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
40051 +
40052 + /* Calculate set size (set size is rounded-up to next power of 2) */
40053 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
40054 +
40055 + /* Get set size code */
40056 + LOG2(setSize, setSizeCode);
40057 +
40058 + /* Sets ways number and set size code */
40059 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
40060 + (uint16_t)((numOfWays << 8) | setSizeCode));
40061 +
40062 + /* It is recommended that the total number of entries in this table
40063 + (number of sets * number of ways) will be twice the number of frames that
40064 + are expected to be reassembled simultaneously.*/
40065 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
40066 +
40067 + /* sets number calculation - number of entries = number of sets * number of ways */
40068 + numOfSets = numOfEntries / numOfWays;
40069 +
40070 + /* Sets AutoLearnHashKeyMask*/
40071 + NEXT_POWER_OF_2(numOfSets, numOfSets);
40072 +
40073 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
40074 + (uint16_t)(numOfSets - 1));
40075 +
40076 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
40077 + The size of this table is determined by the number of sets and the set size.
40078 + Table size = set size * number of sets
40079 + This table base address should be aligned to SetSize.*/
40080 + autoLearnHashTblSize = numOfSets * setSize;
40081 +
40082 + *p_AutoLearnHashTblAddr =
40083 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
40084 + if (!*p_AutoLearnHashTblAddr)
40085 + {
40086 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
40087 + *p_ReassTbl = NULL;
40088 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
40089 + }
40090 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
40091 +
40092 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
40093 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40094 + & FM_PCD_MANIP_REASM_LIODN_MASK)
40095 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
40096 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40097 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
40098 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
40099 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
40100 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
40101 + (uint32_t)(tmpReg64 >> 32));
40102 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
40103 +
40104 + /* Allocation of the Set Lock table - This table resides in external memory
40105 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
40106 + This table resides in external memory and its base address should be 4-byte aligned */
40107 + *p_AutoLearnSetLockTblAddr =
40108 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
40109 + if (!*p_AutoLearnSetLockTblAddr)
40110 + {
40111 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
40112 + *p_ReassTbl = NULL;
40113 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
40114 + *p_AutoLearnHashTblAddr = 0;
40115 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
40116 + }
40117 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
40118 +
40119 + /* sets Set Lock table pointer and liodn offset*/
40120 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40121 + & FM_PCD_MANIP_REASM_LIODN_MASK)
40122 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
40123 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
40124 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
40125 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
40126 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
40127 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
40128 + (uint32_t)(tmpReg64 >> 32));
40129 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
40130 +
40131 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
40132 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
40133 +
40134 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
40135 +
40136 + return E_OK;
40137 +}
40138 +
40139 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
40140 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
40141 + t_Handle h_Ad, bool validate)
40142 +{
40143 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40144 + uint32_t tmpReg32;
40145 + t_Error err;
40146 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
40147 +#if (DPAA_VERSION >= 11)
40148 + t_FmPcdCtrlParamsPage *p_ParamsPage;
40149 +#endif /* (DPAA_VERSION >= 11) */
40150 +
40151 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
40152 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
40153 + SANITY_CHECK_RETURN_ERROR(
40154 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
40155 + E_INVALID_STATE);
40156 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
40157 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
40158 + E_INVALID_HANDLE);
40159 +
40160 + UNUSED(h_Ad);
40161 +
40162 + if (!p_Manip->updateParams)
40163 + return E_OK;
40164 +
40165 + if (p_Manip->h_FmPcd != h_FmPcd)
40166 + RETURN_ERROR(
40167 + MAJOR, E_INVALID_STATE,
40168 + ("handler of PCD previously was initiated by different value"));
40169 +
40170 + if (p_Manip->updateParams)
40171 + {
40172 + if ((!(p_Manip->updateParams
40173 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
40174 + || ((p_Manip->shadowUpdateParams
40175 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
40176 + RETURN_ERROR(
40177 + MAJOR, E_INVALID_STATE,
40178 + ("in this stage parameters from Port has not be updated"));
40179 +
40180 + fmPortGetSetCcParams.setCcParams.type = 0;
40181 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40182 + {
40183 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
40184 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
40185 + }
40186 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
40187 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
40188 + != E_OK)
40189 + RETURN_ERROR(MAJOR, err, NO_MSG);
40190 + if (fmPortGetSetCcParams.getCcParams.type
40191 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
40192 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40193 + ("offset of the data wasn't configured previously"));
40194 + if (p_Manip->updateParams
40195 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
40196 + {
40197 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40198 + uint8_t *p_Ptr, i, totalNumOfTnums;
40199 +
40200 + totalNumOfTnums =
40201 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
40202 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
40203 +
40204 + p_Manip->reassmParams.internalBufferPoolAddr =
40205 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40206 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
40207 + BMI_FIFO_UNITS));
40208 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
40209 + RETURN_ERROR(
40210 + MAJOR, E_NO_MEMORY,
40211 + ("MURAM alloc for Reassembly internal buffers pool"));
40212 + MemSet8(
40213 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
40214 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
40215 +
40216 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
40217 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40218 + (uint32_t)(5 + totalNumOfTnums),
40219 + 4));
40220 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40221 + RETURN_ERROR(
40222 + MAJOR,
40223 + E_NO_MEMORY,
40224 + ("MURAM alloc for Reassembly internal buffers management"));
40225 +
40226 + p_Ptr =
40227 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
40228 + WRITE_UINT32(
40229 + *(uint32_t*)p_Ptr,
40230 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
40231 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
40232 + WRITE_UINT8(*p_Ptr, i);
40233 + WRITE_UINT8(*p_Ptr, 0xFF);
40234 +
40235 + tmpReg32 =
40236 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
40237 + | ((uint32_t)(XX_VirtToPhys(
40238 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
40239 + - p_FmPcd->physicalMuramBase));
40240 + WRITE_UINT32(
40241 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
40242 + tmpReg32);
40243 +
40244 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40245 + | DISCARD_MASK);
40246 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
40247 + | DISCARD_MASK);
40248 + }
40249 + }
40250 +
40251 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
40252 + {
40253 + if (p_Manip->reassmParams.capwap.h_Scheme)
40254 + {
40255 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40256 + p_Manip->reassmParams.capwap.h_Scheme;
40257 + p_PcdParams->p_KgParams->numOfSchemes++;
40258 + }
40259 +
40260 + }
40261 + else
40262 + {
40263 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40264 + {
40265 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40266 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
40267 + p_PcdParams->p_KgParams->numOfSchemes++;
40268 + }
40269 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40270 + {
40271 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
40272 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
40273 + p_PcdParams->p_KgParams->numOfSchemes++;
40274 + }
40275 +#if (DPAA_VERSION >= 11)
40276 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
40277 + {
40278 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
40279 + (void**)&p_ParamsPage)) != E_OK)
40280 + RETURN_ERROR(MAJOR, err, NO_MSG);
40281 +
40282 + tmpReg32 = NIA_ENG_KG;
40283 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
40284 + {
40285 + tmpReg32 |= NIA_KG_DIRECT;
40286 + tmpReg32 |= NIA_KG_CC_EN;
40287 + tmpReg32 |= FmPcdKgGetSchemeId(
40288 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
40289 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
40290 + }
40291 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
40292 + {
40293 + tmpReg32 &= ~NIA_AC_MASK;
40294 + tmpReg32 |= NIA_KG_DIRECT;
40295 + tmpReg32 |= NIA_KG_CC_EN;
40296 + tmpReg32 |= FmPcdKgGetSchemeId(
40297 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
40298 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
40299 + }
40300 + }
40301 +#else
40302 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
40303 + {
40304 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
40305 + fmPortGetSetCcParams.getCcParams.discardMask);
40306 + }
40307 +#endif /* (DPAA_VERSION >= 11) */
40308 + }
40309 + return E_OK;
40310 +}
40311 +
40312 +#if (DPAA_VERSION == 10)
40313 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
40314 +{
40315 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40316 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40317 + t_Error err;
40318 +
40319 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40320 +
40321 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40322 +
40323 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
40324 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40325 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40326 + RETURN_ERROR(MAJOR, err, NO_MSG);
40327 +
40328 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
40329 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
40330 + "Failed to release %d buffers to the BM (missing FBPRs)",
40331 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
40332 +
40333 + return E_OK;
40334 +}
40335 +
40336 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
40337 +{
40338 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
40339 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
40340 + t_Error err;
40341 +
40342 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
40343 +
40344 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
40345 +
40346 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
40347 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
40348 + RETURN_ERROR(MAJOR, err, NO_MSG);
40349 +
40350 + return E_OK;
40351 +}
40352 +#endif /* (DPAA_VERSION == 10) */
40353 +
40354 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
40355 +{
40356 + if (p_Manip->h_Ad)
40357 + {
40358 + if (p_Manip->muramAllocate)
40359 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
40360 + else
40361 + XX_Free(p_Manip->h_Ad);
40362 + p_Manip->h_Ad = NULL;
40363 + }
40364 + if (p_Manip->p_Template)
40365 + {
40366 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
40367 + p_Manip->p_Template = NULL;
40368 + }
40369 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40370 + if (p_Manip->h_Frag)
40371 + {
40372 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
40373 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40374 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
40375 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
40376 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40377 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
40378 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
40379 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40380 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
40381 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
40382 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40383 + p_Manip->capwapFragParams.p_TimeOutTbl);
40384 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
40385 +
40386 + }
40387 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40388 + if (p_Manip->frag)
40389 + {
40390 + if (p_Manip->fragParams.p_Frag)
40391 + {
40392 +#if (DPAA_VERSION == 10)
40393 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
40394 +#endif /* (DPAA_VERSION == 10) */
40395 +
40396 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
40397 + }
40398 + }
40399 + else
40400 + if (p_Manip->reassm)
40401 + {
40402 + FmPcdUnregisterReassmPort(p_FmPcd,
40403 + p_Manip->reassmParams.p_ReassCommonTbl);
40404 +
40405 + if (p_Manip->reassmParams.timeOutTblAddr)
40406 + FM_MURAM_FreeMem(
40407 + p_FmPcd->h_FmMuram,
40408 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
40409 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
40410 + XX_FreeSmart(
40411 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
40412 + if (p_Manip->reassmParams.p_ReassCommonTbl)
40413 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40414 + p_Manip->reassmParams.p_ReassCommonTbl);
40415 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
40416 + FM_MURAM_FreeMem(
40417 + p_FmPcd->h_FmMuram,
40418 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
40419 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
40420 + FM_MURAM_FreeMem(
40421 + p_FmPcd->h_FmMuram,
40422 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
40423 + if (p_Manip->reassmParams.internalBufferPoolAddr)
40424 + FM_MURAM_FreeMem(
40425 + p_FmPcd->h_FmMuram,
40426 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
40427 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
40428 + {
40429 +
40430 + }
40431 + else
40432 + {
40433 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
40434 + XX_FreeSmart(
40435 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
40436 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
40437 + XX_FreeSmart(
40438 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
40439 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
40440 + XX_FreeSmart(
40441 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
40442 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
40443 + XX_FreeSmart(
40444 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
40445 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
40446 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40447 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
40448 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
40449 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
40450 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
40451 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
40452 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
40453 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
40454 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
40455 + }
40456 + }
40457 +
40458 + if (p_Manip->p_StatsTbl)
40459 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
40460 +}
40461 +
40462 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40463 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
40464 +{
40465 + if (p_ManipParams->u.hdr.rmv)
40466 + {
40467 + switch (p_ManipParams->u.hdr.rmvParams.type)
40468 + {
40469 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40470 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40471 + {
40472 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
40473 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
40474 + {
40475 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40476 + {
40477 + case (HEADER_TYPE_CAPWAP_DTLS) :
40478 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
40479 + p_Manip->muramAllocate = TRUE;
40480 + if (p_ManipParams->u.hdr.insrt)
40481 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
40482 + if (p_ManipParams->fragOrReasm)
40483 + {
40484 + if (!p_ManipParams->fragOrReasmParams.frag)
40485 + {
40486 + switch (p_ManipParams->fragOrReasmParams.hdr)
40487 + {
40488 + case (HEADER_TYPE_CAPWAP):
40489 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40490 + break;
40491 + default:
40492 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
40493 + }
40494 + }
40495 + else
40496 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
40497 + }
40498 + break;
40499 + default:
40500 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
40501 + }
40502 + }
40503 + else
40504 + {
40505 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
40506 + {
40507 + case (HEADER_TYPE_CAPWAP_DTLS) :
40508 + case (HEADER_TYPE_CAPWAP) :
40509 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
40510 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for the type of remove e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_TILL_CAPWAP can not be insert or fragOrReasm TRUE"));
40511 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40512 + p_Manip->muramAllocate = TRUE;
40513 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
40514 + break;
40515 + default :
40516 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40517 + }
40518 + }
40519 + break;
40520 + default :
40521 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40522 + }
40523 + break;
40524 + default:
40525 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
40526 + }
40527 + }
40528 + else if (p_ManipParams->u.hdr.insrt)
40529 + {
40530 + switch (p_ManipParams->u.hdr.insrtParams.type)
40531 + {
40532 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
40533 +
40534 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
40535 + p_Manip->muramAllocate = FALSE;
40536 + if (p_ManipParams->fragOrReasm)
40537 + {
40538 + if (p_ManipParams->fragOrReasmParams.frag)
40539 + {
40540 + switch (p_ManipParams->fragOrReasmParams.hdr)
40541 + {
40542 + case (HEADER_TYPE_CAPWAP):
40543 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40544 + break;
40545 + default:
40546 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
40547 + }
40548 + }
40549 + else
40550 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
40551 + }
40552 + break;
40553 +
40554 + default:
40555 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
40556 + }
40557 + }
40558 + else if (p_ManipParams->fragOrReasm)
40559 + {
40560 + if (p_ManipParams->fragOrReasmParams.frag)
40561 + {
40562 + switch (p_ManipParams->fragOrReasmParams.hdr)
40563 + {
40564 + case (HEADER_TYPE_CAPWAP):
40565 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40566 + p_Manip->muramAllocate = FALSE;
40567 + break;
40568 + default:
40569 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
40570 + }
40571 + }
40572 + else
40573 + {
40574 + switch (p_ManipParams->fragOrReasmParams.hdr)
40575 + {
40576 + case (HEADER_TYPE_CAPWAP):
40577 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Reassembly has to be with additional operation - rmv = TRUE, type of remove - e_FM_PCD_MANIP_RMV_FROM_START_OF_FRAME_INCLUDE_SPECIFIC_LOCATION,type = e_FM_PCD_MANIP_LOC_BY_HDR, hdr = HEADER_TYPE_CAPWAP_DTLS"));
40578 + default:
40579 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
40580 + }
40581 + }
40582 +
40583 + }
40584 + else
40585 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
40586 +
40587 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
40588 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
40589 +
40590 + return E_OK;
40591 +}
40592 +
40593 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40594 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
40595 + t_FmPcdManipParams *p_ManipParams)
40596 +{
40597 + switch (p_ManipParams->type)
40598 + {
40599 + case e_FM_PCD_MANIP_HDR:
40600 + /* Check that next-manip is not already used */
40601 + if (p_ManipParams->h_NextManip)
40602 + {
40603 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
40604 + RETURN_ERROR(
40605 + MAJOR, E_INVALID_STATE,
40606 + ("h_NextManip is already a part of another chain"));
40607 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40608 + != e_FM_PCD_MANIP_HDR) &&
40609 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
40610 + != e_FM_PCD_MANIP_FRAG))
40611 + RETURN_ERROR(
40612 + MAJOR,
40613 + E_NOT_SUPPORTED,
40614 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
40615 + }
40616 +
40617 + if (p_ManipParams->u.hdr.rmv)
40618 + {
40619 + switch (p_ManipParams->u.hdr.rmvParams.type)
40620 + {
40621 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
40622 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
40623 + {
40624 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40625 + break;
40626 +#if (DPAA_VERSION >= 11)
40627 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40628 + break;
40629 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40630 + {
40631 + t_Error err;
40632 + uint8_t prsArrayOffset;
40633 +
40634 + err =
40635 + GetPrOffsetByHeaderOrField(
40636 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40637 + &prsArrayOffset);
40638 + if (err)
40639 + RETURN_ERROR(MAJOR, err, NO_MSG);
40640 + break;
40641 + }
40642 +#endif /* (DPAA_VERSION >= 11) */
40643 + default:
40644 + RETURN_ERROR(
40645 + MAJOR,
40646 + E_INVALID_STATE,
40647 + ("invalid type of remove manipulation"));
40648 + }
40649 + break;
40650 + case (e_FM_PCD_MANIP_RMV_GENERIC):
40651 + break;
40652 + default:
40653 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40654 + ("invalid type of remove manipulation"));
40655 + }
40656 + p_Manip->opcode = HMAN_OC;
40657 + p_Manip->muramAllocate = TRUE;
40658 + p_Manip->rmv = TRUE;
40659 + }
40660 + else
40661 + if (p_ManipParams->u.hdr.insrt)
40662 + {
40663 + switch (p_ManipParams->u.hdr.insrtParams.type)
40664 + {
40665 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
40666 + {
40667 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
40668 + {
40669 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40670 + /* nothing to check */
40671 + break;
40672 +#if (DPAA_VERSION >= 11)
40673 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40674 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40675 + % 4)
40676 + RETURN_ERROR(
40677 + MAJOR,
40678 + E_INVALID_VALUE,
40679 + ("IP inserted header must be of size which is a multiple of four bytes"));
40680 + break;
40681 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40682 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40683 + % 4)
40684 + RETURN_ERROR(
40685 + MAJOR,
40686 + E_INVALID_VALUE,
40687 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
40688 + break;
40689 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40690 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40691 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40692 + != 8)
40693 + RETURN_ERROR(
40694 + MAJOR,
40695 + E_INVALID_VALUE,
40696 + ("Inserted header must be of size 8"));
40697 + break;
40698 +#endif /* (DPAA_VERSION >= 11) */
40699 + default:
40700 + RETURN_ERROR(
40701 + MAJOR,
40702 + E_INVALID_STATE,
40703 + ("unsupported insert by header type"));
40704 + }
40705 + }
40706 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
40707 + break;
40708 + default:
40709 + RETURN_ERROR(
40710 + MAJOR,
40711 + E_INVALID_STATE,
40712 + ("for only insert manipulation unsupported type"));
40713 + }
40714 + p_Manip->opcode = HMAN_OC;
40715 + p_Manip->muramAllocate = TRUE;
40716 + p_Manip->insrt = TRUE;
40717 + }
40718 + else
40719 + if (p_ManipParams->u.hdr.fieldUpdate)
40720 + {
40721 + /* Check parameters */
40722 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
40723 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
40724 + {
40725 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40726 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40727 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
40728 + > 7))
40729 + RETURN_ERROR(
40730 + MAJOR, E_INVALID_VALUE,
40731 + ("vpri should get values of 0-7 "));
40732 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40733 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40734 + {
40735 + int i;
40736 +
40737 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
40738 + > 7)
40739 + RETURN_ERROR(
40740 + MAJOR,
40741 + E_INVALID_VALUE,
40742 + ("vpriDefVal should get values of 0-7 "));
40743 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
40744 + i++)
40745 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
40746 + & 0xf0)
40747 + RETURN_ERROR(
40748 + MAJOR,
40749 + E_INVALID_VALUE,
40750 + ("dscpToVpriTabl value out of range (0-15)"));
40751 + }
40752 +
40753 + }
40754 +
40755 + p_Manip->opcode = HMAN_OC;
40756 + p_Manip->muramAllocate = TRUE;
40757 + p_Manip->fieldUpdate = TRUE;
40758 + }
40759 + else
40760 + if (p_ManipParams->u.hdr.custom)
40761 + {
40762 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
40763 + {
40764 +
40765 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
40766 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
40767 + RETURN_ERROR(
40768 + MAJOR, E_INVALID_VALUE,
40769 + ("size should get values of 1-8 "));
40770 +
40771 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
40772 + RETURN_ERROR(
40773 + MAJOR, E_INVALID_VALUE,
40774 + ("srcOffset should be <= 7"));
40775 +
40776 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
40777 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
40778 + RETURN_ERROR(
40779 + MAJOR, E_INVALID_VALUE,
40780 + ("(srcOffset + size) should be <= 8"));
40781 +
40782 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
40783 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
40784 + RETURN_ERROR(
40785 + MAJOR, E_INVALID_VALUE,
40786 + ("(dstOffset + size) should be <= 256"));
40787 +
40788 + }
40789 +
40790 + p_Manip->opcode = HMAN_OC;
40791 + p_Manip->muramAllocate = TRUE;
40792 + p_Manip->custom = TRUE;
40793 + }
40794 + break;
40795 + case e_FM_PCD_MANIP_REASSEM:
40796 + if (p_ManipParams->h_NextManip)
40797 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40798 + ("next manip with reassembly"));
40799 + switch (p_ManipParams->u.reassem.hdr)
40800 + {
40801 + case (HEADER_TYPE_IPv4):
40802 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
40803 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40804 + break;
40805 + case (HEADER_TYPE_IPv6):
40806 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
40807 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
40808 + break;
40809 +#if (DPAA_VERSION >= 11)
40810 + case (HEADER_TYPE_CAPWAP):
40811 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
40812 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
40813 + break;
40814 +#endif /* (DPAA_VERSION >= 11) */
40815 + default:
40816 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40817 + ("header for reassembly"));
40818 + }
40819 + break;
40820 + case e_FM_PCD_MANIP_FRAG:
40821 + if (p_ManipParams->h_NextManip)
40822 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40823 + ("next manip with fragmentation"));
40824 + switch (p_ManipParams->u.frag.hdr)
40825 + {
40826 + case (HEADER_TYPE_IPv4):
40827 + case (HEADER_TYPE_IPv6):
40828 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
40829 + break;
40830 +#if (DPAA_VERSION >= 11)
40831 + case (HEADER_TYPE_CAPWAP):
40832 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
40833 + break;
40834 +#endif /* (DPAA_VERSION >= 11) */
40835 + default:
40836 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40837 + ("header for fragmentation"));
40838 + }
40839 + p_Manip->muramAllocate = TRUE;
40840 + break;
40841 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
40842 + switch (p_ManipParams->u.specialOffload.type)
40843 + {
40844 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
40845 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
40846 + p_Manip->muramAllocate = TRUE;
40847 + break;
40848 +#if (DPAA_VERSION >= 11)
40849 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
40850 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
40851 + p_Manip->muramAllocate = TRUE;
40852 + break;
40853 +#endif /* (DPAA_VERSION >= 11) */
40854 + default:
40855 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
40856 + ("special offload type"));
40857 + }
40858 + break;
40859 + default:
40860 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
40861 + }
40862 +
40863 + return E_OK;
40864 +}
40865 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
40866 +
40867 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40868 +
40869 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
40870 + t_Handle h_FmPort,
40871 + t_FmPcdManip *p_Manip)
40872 +{
40873 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
40874 + uint32_t tmpReg32 = 0;
40875 + t_AdOfTypeContLookup *p_Ad;
40876 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
40877 + t_Error err;
40878 +
40879 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
40880 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40881 +
40882 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40883 + if (p_Manip->h_FmPcd != h_FmPcd)
40884 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
40885 + ("handler of PCD previously was initiated by different value"));
40886 +
40887 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
40888 +
40889 + if (!p_Manip->p_StatsTbl)
40890 + {
40891 +
40892 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40893 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40894 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40895 + if (err)
40896 + RETURN_ERROR(MAJOR, err, NO_MSG);
40897 +
40898 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
40899 +
40900 + p_Manip->p_StatsTbl =
40901 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
40902 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
40903 + 4);
40904 + if (!p_Manip->p_StatsTbl)
40905 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
40906 +
40907 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
40908 +
40909 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
40910 +
40911 + if (p_Manip->cnia)
40912 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
40913 +
40914 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
40915 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40916 + }
40917 + else
40918 + {
40919 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
40920 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
40921 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
40922 + if (err)
40923 + RETURN_ERROR(MAJOR, err, NO_MSG);
40924 + }
40925 +
40926 + return E_OK;
40927 +}
40928 +
40929 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
40930 +{
40931 + t_AdOfTypeContLookup *p_Ad;
40932 + uint32_t tmpReg32 = 0;
40933 + uint8_t prsArrayOffset = 0;
40934 + t_Error err;
40935 +
40936 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
40937 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
40938 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40939 +
40940 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40941 + if (p_Manip->rmv)
40942 + {
40943 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
40944 + if (err)
40945 + RETURN_ERROR(MAJOR, err, NO_MSG);
40946 +
40947 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
40948 + tmpReg32 |= HMAN_RMV_HDR;
40949 + }
40950 +
40951 + if (p_Manip->insrt)
40952 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
40953 +
40954 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
40955 +
40956 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
40957 +
40958 + tmpReg32 = 0;
40959 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40960 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
40961 +
40962 + return E_OK;
40963 +}
40964 +
40965 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
40966 + bool caamUsed)
40967 +{
40968 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40969 + uint32_t tmpReg32 = 0;
40970 +
40971 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
40972 +
40973 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
40974 +
40975 + tmpReg32 = 0;
40976 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
40977 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
40978 +
40979 + tmpReg32 = 0;
40980 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
40981 + tmpReg32 |= (uint32_t)0x16 << 16;
40982 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
40983 +
40984 + if (caamUsed)
40985 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
40986 +
40987 + return E_OK;
40988 +}
40989 +
40990 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
40991 +{
40992 + t_AdOfTypeContLookup *p_Ad;
40993 + uint32_t tmpReg32 = 0;
40994 + t_Error err = E_OK;
40995 +
40996 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
40997 +
40998 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40999 +
41000 + tmpReg32 = 0;
41001 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
41002 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41003 +
41004 + tmpReg32 = 0;
41005 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41006 +
41007 +
41008 + if (p_Manip->h_Frag)
41009 + {
41010 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
41011 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41012 + }
41013 +
41014 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41015 +
41016 + return err;
41017 +}
41018 +
41019 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
41020 + t_FmPcdManip *p_Manip,
41021 + t_FmPcd *p_FmPcd,
41022 + uint8_t poolId)
41023 +{
41024 + t_Handle p_Table;
41025 + uint32_t tmpReg32 = 0;
41026 + int i = 0;
41027 + uint8_t log2Num;
41028 + uint8_t numOfSets;
41029 + uint32_t j = 0;
41030 + uint32_t bitFor1Micro;
41031 +
41032 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41033 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
41034 +
41035 + if (!p_FmPcd->h_Hc)
41036 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
41037 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
41038 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
41039 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
41040 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
41041 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
41042 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
41043 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
41044 + {
41045 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
41046 + (p_ManipParams->maxNumFramesInProcess > 512))
41047 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_EIGHT_WAYS_HASH maxNumFramesInProcess has to be in the range 4-512"));
41048 + }
41049 + else
41050 + {
41051 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
41052 + (p_ManipParams->maxNumFramesInProcess > 2048))
41053 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("In the case of numOfFramesPerHashEntry = e_FM_PCD_MANIP_FOUR_WAYS_HASH maxNumFramesInProcess has to be in the range 8-2048"));
41054 + }
41055 +
41056 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41057 + if (bitFor1Micro == 0)
41058 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41059 +
41060 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
41061 +
41062 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41063 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
41064 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
41065 + if (!p_Manip->h_Frag)
41066 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
41067 +
41068 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
41069 +
41070 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
41071 +
41072 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
41073 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41074 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
41075 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
41076 +
41077 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
41078 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
41079 +
41080 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
41081 +
41082 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
41083 +
41084 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
41085 +
41086 + tmpReg32 = 0;
41087 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
41088 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
41089 + if (p_ManipParams->haltOnDuplicationFrag)
41090 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
41091 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
41092 + {
41093 + i = 8;
41094 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
41095 + }
41096 + else
41097 + i = 4;
41098 +
41099 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
41100 + LOG2(numOfSets, log2Num);
41101 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
41102 +
41103 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
41104 +
41105 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
41106 + if (((j / i) % 2)== 0)
41107 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
41108 +
41109 + tmpReg32 = 0x00008000;
41110 + tmpReg32 |= (uint32_t)poolId << 16;
41111 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
41112 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
41113 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
41114 +
41115 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
41116 +
41117 + p_Manip->capwapFragParams.sgBpid = poolId;
41118 +
41119 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
41120 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
41121 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
41122 +
41123 + tmpReg32 = 0;
41124 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
41125 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
41126 +
41127 + return E_OK;
41128 +}
41129 +
41130 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
41131 + t_FmPcdManip *p_Manip,
41132 + t_FmPcd *p_FmPcd,
41133 + uint8_t poolId)
41134 +{
41135 + t_AdOfTypeContLookup *p_Ad;
41136 + uint32_t tmpReg32 = 0;
41137 +
41138 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41139 +
41140 + p_Manip->updateParams |= OFFSET_OF_DATA;
41141 +
41142 + p_Manip->frag = TRUE;
41143 +
41144 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41145 + FM_PCD_CC_AD_ENTRY_SIZE,
41146 + FM_PCD_CC_AD_TABLE_ALIGN);
41147 + if (!p_Manip->h_Frag)
41148 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
41149 +
41150 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41151 +
41152 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
41153 +
41154 + tmpReg32 = 0;
41155 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
41156 +
41157 + if (p_ManipParams->headerOptionsCompr)
41158 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
41159 + tmpReg32 |= ((uint32_t)poolId << 8);
41160 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41161 +
41162 + tmpReg32 = 0;
41163 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41164 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41165 +
41166 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41167 + p_Manip->capwapFragParams.sgBpid = poolId;
41168 +
41169 + return E_OK;
41170 +}
41171 +
41172 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
41173 +{
41174 + t_AdOfTypeContLookup *p_Ad;
41175 + uint32_t tmpReg32 = 0;
41176 +
41177 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41178 +
41179 + UNUSED(p_FmPcd);
41180 +
41181 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41182 +
41183 + tmpReg32 = 0;
41184 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
41185 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
41186 + tmpReg32 |= (uint32_t)0x16 << 16;
41187 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41188 +
41189 + tmpReg32 = 0;
41190 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41191 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41192 +
41193 + return E_OK;
41194 +}
41195 +
41196 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
41197 +{
41198 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
41199 + uint8_t tmpReg8 = 0xff;
41200 + t_AdOfTypeContLookup *p_Ad;
41201 + bool ipModify = FALSE;
41202 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41203 + uint16_t tmpReg16 = 0;
41204 + t_Error err = E_OK;
41205 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
41206 + uint8_t *p_Template = NULL;
41207 +
41208 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
41209 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
41210 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
41211 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
41212 +
41213 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41214 + if (p_Manip->insrt)
41215 + {
41216 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
41217 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
41218 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
41219 +
41220 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
41221 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
41222 +
41223 + if (p_InsrtByTemplate->size > 128)
41224 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
41225 +
41226 + if (p_InsrtByTemplate->size)
41227 + {
41228 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41229 + p_InsrtByTemplate->size,
41230 + FM_PCD_CC_AD_TABLE_ALIGN);
41231 + if(!p_Manip->p_Template)
41232 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
41233 +
41234 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
41235 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
41236 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
41237 + }
41238 +
41239 + tmpReg32 = 0;
41240 +
41241 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
41242 +
41243 + if (!p_Template)
41244 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
41245 +
41246 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
41247 +
41248 + if (p_InsrtByTemplate->modifyOuterIp)
41249 + {
41250 + ipModify = TRUE;
41251 +
41252 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
41253 +
41254 + if((tmpReg8 & 0xf0) == 0x40)
41255 + tmpReg8 = 4;
41256 + else if((tmpReg8 & 0xf0) == 0x60)
41257 + tmpReg8 = 6;
41258 + else
41259 + tmpReg8 = 0xff;
41260 +
41261 + if (tmpReg8 != 0xff)
41262 + {
41263 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
41264 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
41265 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
41266 + {
41267 +
41268 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
41269 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
41270 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
41271 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
41272 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
41273 + /*IP header template - IP totalLength -
41274 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
41275 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
41276 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
41277 + }
41278 + if (blockSize)
41279 + {
41280 + if (!POWER_OF_2(blockSize))
41281 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
41282 + }
41283 +
41284 + }
41285 + if (tmpReg8 == 4)
41286 + {
41287 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
41288 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IP present in header template, user asked for IP modifications but ipOffset + ipTotalLengthFieldOffset in header template bigger than template size"));
41289 +
41290 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
41291 +
41292 + if (blockSize)
41293 + blockSize -= 1;
41294 +
41295 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
41296 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
41297 +
41298 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
41299 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes);// for IPV6 decrement additional 40 bytes of IPV6 heade size
41300 +
41301 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
41302 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41303 +
41304 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
41305 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
41306 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
41307 +
41308 + /*UDP checksum has to be 0*/
41309 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41310 + {
41311 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41312 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41313 +
41314 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
41315 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41316 +
41317 + }
41318 +
41319 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
41320 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
41321 +
41322 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
41323 + }
41324 + else if (tmpReg8 == 6)
41325 + {
41326 + /*TODO - add check for maximum value of blockSize;*/
41327 + if (blockSize)
41328 + LOG2(blockSize, log2Num);
41329 + tmpRegNia |= (uint32_t)log2Num << 24;
41330 +
41331 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
41332 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
41333 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
41334 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
41335 + {
41336 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
41337 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
41338 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
41339 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
41340 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
41341 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
41342 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
41343 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
41344 + }
41345 + }
41346 + else
41347 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
41348 + }
41349 +
41350 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
41351 + /*TODO - check it*/
41352 + if (p_InsrtByTemplate->modifyOuterVlan)
41353 + {
41354 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
41355 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
41356 +
41357 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
41358 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
41359 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
41360 +
41361 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
41362 + tmpReg8 &= 0x1f;
41363 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
41364 +
41365 + p_Template[14] = tmpReg8;
41366 + }
41367 +
41368 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
41369 +
41370 + XX_Free(p_Template);
41371 + }
41372 +
41373 + tmpReg32 = 0;
41374 + if (p_Manip->h_Frag)
41375 + {
41376 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
41377 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
41378 + }
41379 + else
41380 + tmpReg32 = 0xffff0000;
41381 +
41382 + if (ipModify)
41383 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
41384 + else
41385 + tmpReg32 |= (uint32_t)0x0000ff00;
41386 +
41387 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
41388 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
41389 +
41390 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41391 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
41392 +
41393 + return err;
41394 +}
41395 +
41396 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
41397 +{
41398 +
41399 + switch (p_StatsParams->type)
41400 + {
41401 + case (e_FM_PCD_STATS_PER_FLOWID):
41402 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
41403 + p_Manip->muramAllocate = TRUE;
41404 + break;
41405 + default:
41406 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
41407 + }
41408 +
41409 + return E_OK;
41410 +}
41411 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41412 +
41413 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41414 +{
41415 + t_AdOfTypeContLookup *p_Ad;
41416 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41417 + uint32_t tmpReg32;
41418 + t_Error err = E_OK;
41419 +
41420 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
41421 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
41422 + two separate IP Reassembly Parameter tables are required.*/
41423 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
41424 + RETURN_ERROR(MAJOR, err, NO_MSG);
41425 +
41426 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
41427 + tmpReg32 = 0;
41428 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41429 +
41430 + /* Gets the required Action descriptor table pointer */
41431 + switch (hdr)
41432 + {
41433 + case HEADER_TYPE_IPv4:
41434 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
41435 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41436 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41437 + - (p_FmPcd->physicalMuramBase));
41438 + break;
41439 + case HEADER_TYPE_IPv6:
41440 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
41441 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41442 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41443 + - (p_FmPcd->physicalMuramBase));
41444 + break;
41445 + case HEADER_TYPE_CAPWAP:
41446 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
41447 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
41448 + p_Manip->reassmParams.capwap.p_ReassTbl)
41449 + - (p_FmPcd->physicalMuramBase));
41450 + break;
41451 + default:
41452 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41453 + }
41454 +
41455 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
41456 +
41457 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
41458 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
41459 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
41460 +
41461 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
41462 + {
41463 +#if (DPAA_VERSION == 10)
41464 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
41465 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
41466 +#endif /* (DPAA_VERSION == 10) */
41467 +#if (DPAA_VERSION >= 11)
41468 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
41469 + {
41470 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
41471 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
41472 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
41473 + }
41474 +#endif /* (DPAA_VERSION >= 11) */
41475 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
41476 + tmpReg32 = 0;
41477 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
41478 + }
41479 +#if (DPAA_VERSION >= 11)
41480 + else
41481 + if (hdr == HEADER_TYPE_CAPWAP)
41482 + {
41483 + tmpReg32 = 0;
41484 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
41485 + }
41486 +#endif /* (DPAA_VERSION >= 11) */
41487 +
41488 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41489 +
41490 + p_Manip->reassm = TRUE;
41491 +
41492 + return E_OK;
41493 +}
41494 +
41495 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
41496 +{
41497 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41498 +
41499 + /* Allocation if IPv4 Action descriptor */
41500 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
41501 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41502 + FM_PCD_CC_AD_TABLE_ALIGN);
41503 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
41504 + {
41505 + ReleaseManipHandler(p_Manip, p_FmPcd);
41506 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41507 + ("Allocation of IPv4 table descriptor"));
41508 + }
41509 +
41510 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41511 +
41512 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41513 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
41514 +}
41515 +
41516 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
41517 +{
41518 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41519 +
41520 + /* Allocation if IPv6 Action descriptor */
41521 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
41522 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
41523 + FM_PCD_CC_AD_TABLE_ALIGN);
41524 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
41525 + {
41526 + ReleaseManipHandler(p_Manip, p_FmPcd);
41527 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41528 + ("Allocation of IPv6 table descriptor"));
41529 + }
41530 +
41531 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41532 +
41533 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
41534 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
41535 +}
41536 +
41537 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
41538 + t_FmPcdManip *p_Manip)
41539 +{
41540 + uint32_t maxSetNumber = 10000;
41541 + t_FmPcdManipReassemIpParams reassmManipParams =
41542 + p_ManipReassmParams->u.ipReassem;
41543 + t_Error res;
41544 +
41545 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
41546 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
41547 + E_INVALID_HANDLE);
41548 +
41549 + /* Check validation of user's parameter.*/
41550 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
41551 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
41552 + RETURN_ERROR(
41553 + MAJOR, E_INVALID_VALUE,
41554 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
41555 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
41556 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
41557 + if (reassmManipParams.maxNumFramesInProcess
41558 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
41559 + RETURN_ERROR(
41560 + MAJOR,
41561 + E_INVALID_VALUE,
41562 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
41563 +
41564 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
41565 + && (reassmManipParams.minFragSize[1] < 256))
41566 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
41567 +
41568 + /* Saves user's reassembly manipulation parameters */
41569 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
41570 + reassmManipParams.relativeSchemeId[0];
41571 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
41572 + reassmManipParams.relativeSchemeId[1];
41573 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
41574 + reassmManipParams.numOfFramesPerHashEntry[0];
41575 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
41576 + reassmManipParams.numOfFramesPerHashEntry[1];
41577 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
41578 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
41579 + p_Manip->reassmParams.maxNumFramesInProcess =
41580 + reassmManipParams.maxNumFramesInProcess;
41581 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
41582 + p_Manip->reassmParams.fqidForTimeOutFrames =
41583 + reassmManipParams.fqidForTimeOutFrames;
41584 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
41585 + reassmManipParams.timeoutThresholdForReassmProcess;
41586 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
41587 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
41588 +#if (DPAA_VERSION == 10)
41589 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
41590 +#endif /* (DPAA_VERSION == 10) */
41591 +#if (DPAA_VERSION >= 11)
41592 + if (reassmManipParams.nonConsistentSpFqid != 0)
41593 + {
41594 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
41595 + reassmManipParams.nonConsistentSpFqid;
41596 + }
41597 +#endif /* (DPAA_VERSION >= 11) */
41598 +
41599 + /* Creates and initializes the IP Reassembly common parameter table */
41600 + CreateReassCommonTable(p_Manip);
41601 +
41602 + /* Creation of IPv4 reassembly manipulation */
41603 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41604 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
41605 + {
41606 + res = SetIpv4ReassmManip(p_Manip);
41607 + if (res != E_OK)
41608 + return res;
41609 + }
41610 +
41611 + /* Creation of IPv6 reassembly manipulation */
41612 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
41613 + {
41614 + res = SetIpv6ReassmManip(p_Manip);
41615 + if (res != E_OK)
41616 + return res;
41617 + }
41618 +
41619 + return E_OK;
41620 +}
41621 +
41622 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
41623 + t_FmPcdKgSchemeParams *p_Scheme,
41624 + t_Handle h_CcTree, bool ipv4,
41625 + uint8_t groupId)
41626 +{
41627 + uint32_t j;
41628 + uint8_t res;
41629 +
41630 + /* Configures scheme's network environment parameters */
41631 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
41632 + if (ipv4)
41633 + res = FmPcdNetEnvGetUnitId(
41634 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41635 + HEADER_TYPE_IPv4, FALSE, 0);
41636 + else
41637 + res = FmPcdNetEnvGetUnitId(
41638 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41639 + HEADER_TYPE_IPv6, FALSE, 0);
41640 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41641 + p_Scheme->netEnvParams.unitIds[0] = res;
41642 +
41643 + res = FmPcdNetEnvGetUnitId(
41644 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
41645 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
41646 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
41647 + p_Scheme->netEnvParams.unitIds[1] = res;
41648 +
41649 + /* Configures scheme's next engine parameters*/
41650 + p_Scheme->nextEngine = e_FM_PCD_CC;
41651 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
41652 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
41653 + p_Scheme->useHash = TRUE;
41654 +
41655 + /* Configures scheme's key*/
41656 + if (ipv4 == TRUE)
41657 + {
41658 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
41659 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41660 + e_FM_PCD_EXTRACT_BY_HDR;
41661 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41662 + e_FM_PCD_EXTRACT_FULL_FIELD;
41663 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41664 + HEADER_TYPE_IPv4;
41665 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
41666 + NET_HEADER_FIELD_IPv4_DST_IP;
41667 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41668 + e_FM_PCD_EXTRACT_BY_HDR;
41669 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41670 + e_FM_PCD_EXTRACT_FULL_FIELD;
41671 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41672 + HEADER_TYPE_IPv4;
41673 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
41674 + NET_HEADER_FIELD_IPv4_SRC_IP;
41675 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41676 + e_FM_PCD_EXTRACT_BY_HDR;
41677 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41678 + e_FM_PCD_EXTRACT_FULL_FIELD;
41679 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41680 + HEADER_TYPE_IPv4;
41681 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
41682 + NET_HEADER_FIELD_IPv4_PROTO;
41683 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
41684 + e_FM_PCD_EXTRACT_BY_HDR;
41685 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
41686 + HEADER_TYPE_IPv4;
41687 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
41688 + e_FM_PCD_EXTRACT_FROM_HDR;
41689 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
41690 + FALSE;
41691 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
41692 + 2;
41693 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
41694 + 4;
41695 + }
41696 + else /* IPv6 */
41697 + {
41698 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
41699 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
41700 + e_FM_PCD_EXTRACT_BY_HDR;
41701 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
41702 + e_FM_PCD_EXTRACT_FULL_FIELD;
41703 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
41704 + HEADER_TYPE_IPv6;
41705 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
41706 + NET_HEADER_FIELD_IPv6_DST_IP;
41707 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
41708 + e_FM_PCD_EXTRACT_BY_HDR;
41709 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
41710 + e_FM_PCD_EXTRACT_FULL_FIELD;
41711 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
41712 + HEADER_TYPE_IPv6;
41713 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
41714 + NET_HEADER_FIELD_IPv6_SRC_IP;
41715 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
41716 + e_FM_PCD_EXTRACT_BY_HDR;
41717 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
41718 + HEADER_TYPE_USER_DEFINED_SHIM2;
41719 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
41720 + e_FM_PCD_EXTRACT_FROM_HDR;
41721 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
41722 + 4;
41723 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
41724 + 4;
41725 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
41726 + TRUE;
41727 + }
41728 +
41729 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
41730 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
41731 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
41732 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
41733 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
41734 + {
41735 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
41736 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
41737 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
41738 + e_FM_PCD_KG_DFLT_GBL_0;
41739 + }
41740 +}
41741 +
41742 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
41743 + t_FmPcdManipReassemIpStats *p_Stats)
41744 +{
41745 + ASSERT_COND(p_Manip);
41746 + ASSERT_COND(p_Stats);
41747 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
41748 +
41749 + p_Stats->timeout =
41750 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
41751 + p_Stats->rfdPoolBusy =
41752 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
41753 + p_Stats->internalBufferBusy =
41754 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
41755 + p_Stats->externalBufferBusy =
41756 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
41757 + p_Stats->sgFragments =
41758 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
41759 + p_Stats->dmaSemaphoreDepletion =
41760 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
41761 +#if (DPAA_VERSION >= 11)
41762 + p_Stats->nonConsistentSp =
41763 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
41764 +#endif /* (DPAA_VERSION >= 11) */
41765 +
41766 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
41767 + {
41768 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
41769 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
41770 + p_Stats->specificHdrStatistics[0].validFragments =
41771 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
41772 + p_Stats->specificHdrStatistics[0].processedFragments =
41773 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
41774 + p_Stats->specificHdrStatistics[0].malformedFragments =
41775 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
41776 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
41777 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
41778 + p_Stats->specificHdrStatistics[0].discardedFragments =
41779 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
41780 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
41781 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
41782 + }
41783 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
41784 + {
41785 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
41786 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
41787 + p_Stats->specificHdrStatistics[1].validFragments =
41788 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
41789 + p_Stats->specificHdrStatistics[1].processedFragments =
41790 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
41791 + p_Stats->specificHdrStatistics[1].malformedFragments =
41792 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
41793 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
41794 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
41795 + p_Stats->specificHdrStatistics[1].discardedFragments =
41796 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
41797 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
41798 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
41799 + }
41800 + return E_OK;
41801 +}
41802 +
41803 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
41804 + t_FmPcdManipFragIpStats *p_Stats)
41805 +{
41806 + t_AdOfTypeContLookup *p_Ad;
41807 +
41808 + ASSERT_COND(p_Manip);
41809 + ASSERT_COND(p_Stats);
41810 + ASSERT_COND(p_Manip->h_Ad);
41811 + ASSERT_COND(p_Manip->fragParams.p_Frag);
41812 +
41813 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41814 +
41815 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
41816 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
41817 + & 0x00ffffff;
41818 + p_Stats->generatedFragments =
41819 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
41820 +
41821 + return E_OK;
41822 +}
41823 +
41824 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
41825 + t_FmPcdManip *p_Manip)
41826 +{
41827 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
41828 + t_FmPcd *p_FmPcd;
41829 +#if (DPAA_VERSION == 10)
41830 + t_Error err = E_OK;
41831 +#endif /* (DPAA_VERSION == 10) */
41832 +
41833 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
41834 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
41835 + E_INVALID_VALUE);
41836 +
41837 + p_FmPcd = p_Manip->h_FmPcd;
41838 + /* Allocation of fragmentation Action Descriptor */
41839 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
41840 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
41841 + FM_PCD_CC_AD_TABLE_ALIGN);
41842 + if (!p_Manip->fragParams.p_Frag)
41843 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41844 + ("MURAM alloc for Fragmentation table descriptor"));
41845 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
41846 +
41847 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
41848 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
41849 +
41850 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
41851 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
41852 + ccAdBaseReg |= (p_ManipParams->dontFragAction
41853 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
41854 +
41855 +
41856 + /* Set Scatter/Gather BPid */
41857 + if (p_ManipParams->sgBpidEn)
41858 + {
41859 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
41860 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
41861 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
41862 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
41863 + }
41864 +
41865 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
41866 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
41867 + - p_FmPcd->physicalMuramBase);
41868 +#if (DPAA_VERSION == 10)
41869 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41870 +#else
41871 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
41872 +#endif /* (DPAA_VERSION == 10) */
41873 +
41874 + /* Set all Ad registers */
41875 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
41876 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
41877 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
41878 +
41879 + /* Saves user's fragmentation manipulation parameters */
41880 + p_Manip->frag = TRUE;
41881 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
41882 +
41883 +#if (DPAA_VERSION == 10)
41884 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
41885 +
41886 + /* scratch buffer pool initialization */
41887 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
41888 + {
41889 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
41890 + p_Manip->fragParams.p_Frag = NULL;
41891 + RETURN_ERROR(MAJOR, err, NO_MSG);
41892 + }
41893 +#endif /* (DPAA_VERSION == 10) */
41894 +
41895 + return E_OK;
41896 +}
41897 +
41898 +static t_Error IPManip(t_FmPcdManip *p_Manip)
41899 +{
41900 + t_Error err = E_OK;
41901 + t_FmPcd *p_FmPcd;
41902 + t_AdOfTypeContLookup *p_Ad;
41903 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
41904 +
41905 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41906 + p_FmPcd = p_Manip->h_FmPcd;
41907 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41908 +
41909 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41910 +
41911 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
41912 + if (p_Manip->frag == TRUE)
41913 + {
41914 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
41915 + - (p_FmPcd->physicalMuramBase));
41916 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
41917 + << FM_PCD_MANIP_IP_MTU_SHIFT;
41918 + }
41919 +
41920 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41921 + tmpReg32 |= HMAN_OC_IP_MANIP;
41922 +
41923 +#if (DPAA_VERSION >= 11)
41924 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
41925 +#endif /* (DPAA_VERSION >= 11) */
41926 +
41927 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
41928 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
41929 + WRITE_UINT32(p_Ad->gmask, 0);
41930 + /* Total frame counter - MUST be initialized to zero.*/
41931 +
41932 + return err;
41933 +}
41934 +
41935 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
41936 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41937 + t_Handle h_Ad, bool validate)
41938 +{
41939 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41940 + t_Error err;
41941 +
41942 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41943 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
41944 + E_INVALID_STATE);
41945 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41946 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
41947 +
41948 + UNUSED(h_FmPcd);
41949 + UNUSED(h_Ad);
41950 + UNUSED(h_PcdParams);
41951 + UNUSED(validate);
41952 + UNUSED(p_Manip);
41953 +
41954 + fmPortGetSetCcParams.setCcParams.type = 0;
41955 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
41956 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
41957 + RETURN_ERROR(MAJOR, err, NO_MSG);
41958 +
41959 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
41960 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
41961 +
41962 + return E_OK;
41963 +}
41964 +
41965 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
41966 + t_FmPcdManip *p_Manip)
41967 +{
41968 + t_AdOfTypeContLookup *p_Ad;
41969 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
41970 + t_Error err = E_OK;
41971 + uint32_t tmpReg32 = 0;
41972 + uint32_t power;
41973 +
41974 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41975 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
41976 +
41977 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
41978 +
41979 + SANITY_CHECK_RETURN_ERROR(
41980 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
41981 + E_INVALID_VALUE);
41982 + SANITY_CHECK_RETURN_ERROR(
41983 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
41984 + E_INVALID_VALUE);
41985 + SANITY_CHECK_RETURN_ERROR(
41986 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
41987 + E_INVALID_VALUE);
41988 + SANITY_CHECK_RETURN_ERROR(
41989 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
41990 + E_INVALID_VALUE);
41991 + SANITY_CHECK_RETURN_ERROR(
41992 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
41993 + E_INVALID_VALUE);
41994 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
41995 +
41996 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41997 +
41998 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
41999 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
42000 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
42001 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
42002 + tmpReg32 |=
42003 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
42004 + tmpReg32 |=
42005 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
42006 + if (p_IPSecParams->arwSize)
42007 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
42008 + & (FM_MURAM_SIZE-1));
42009 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42010 +
42011 + tmpReg32 = 0;
42012 + if (p_IPSecParams->arwSize) {
42013 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
42014 + LOG2(power, power);
42015 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
42016 + }
42017 +
42018 + if (p_ManipParams->h_NextManip)
42019 + tmpReg32 |=
42020 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
42021 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
42022 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
42023 +
42024 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
42025 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
42026 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
42027 + if (p_ManipParams->h_NextManip)
42028 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
42029 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42030 +
42031 + return err;
42032 +}
42033 +
42034 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
42035 +{
42036 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
42037 +
42038 + /* Allocation if CAPWAP Action descriptor */
42039 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
42040 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
42041 + FM_PCD_CC_AD_TABLE_ALIGN);
42042 + if (!p_Manip->reassmParams.capwap.h_Ad)
42043 + {
42044 + ReleaseManipHandler(p_Manip, p_FmPcd);
42045 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42046 + ("Allocation of CAPWAP table descriptor"));
42047 + }
42048 +
42049 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42050 +
42051 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
42052 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
42053 +}
42054 +
42055 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
42056 + t_FmPcdKgSchemeParams *p_Scheme,
42057 + t_Handle h_CcTree, uint8_t groupId)
42058 +{
42059 + uint8_t res;
42060 +
42061 + /* Configures scheme's network environment parameters */
42062 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
42063 + res = FmPcdNetEnvGetUnitId(
42064 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
42065 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
42066 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
42067 + p_Scheme->netEnvParams.unitIds[0] = res;
42068 +
42069 + /* Configures scheme's next engine parameters*/
42070 + p_Scheme->nextEngine = e_FM_PCD_CC;
42071 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
42072 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
42073 + p_Scheme->useHash = TRUE;
42074 +
42075 + /* Configures scheme's key*/
42076 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
42077 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
42078 + e_FM_PCD_EXTRACT_NON_HDR;
42079 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
42080 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
42081 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
42082 + e_FM_PCD_ACTION_NONE;
42083 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
42084 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
42085 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
42086 + e_FM_PCD_EXTRACT_NON_HDR;
42087 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
42088 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
42089 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
42090 + e_FM_PCD_ACTION_NONE;
42091 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
42092 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
42093 +
42094 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
42095 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
42096 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
42097 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
42098 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
42099 +}
42100 +
42101 +#if (DPAA_VERSION >= 11)
42102 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
42103 + t_FmPcdManipReassemCapwapStats *p_Stats)
42104 +{
42105 + ASSERT_COND(p_Manip);
42106 + ASSERT_COND(p_Stats);
42107 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
42108 +
42109 + p_Stats->timeout =
42110 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
42111 + p_Stats->rfdPoolBusy =
42112 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
42113 + p_Stats->internalBufferBusy =
42114 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
42115 + p_Stats->externalBufferBusy =
42116 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
42117 + p_Stats->sgFragments =
42118 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
42119 + p_Stats->dmaSemaphoreDepletion =
42120 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
42121 + p_Stats->exceedMaxReassemblyFrameLen =
42122 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
42123 +
42124 + p_Stats->successfullyReassembled =
42125 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
42126 + p_Stats->validFragments =
42127 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
42128 + p_Stats->processedFragments =
42129 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
42130 + p_Stats->malformedFragments =
42131 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
42132 + p_Stats->autoLearnBusy =
42133 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
42134 + p_Stats->discardedFragments =
42135 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
42136 + p_Stats->moreThan16Fragments =
42137 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
42138 +
42139 + return E_OK;
42140 +}
42141 +
42142 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
42143 + t_FmPcdManipFragCapwapStats *p_Stats)
42144 +{
42145 + t_AdOfTypeContLookup *p_Ad;
42146 +
42147 + ASSERT_COND(p_Manip);
42148 + ASSERT_COND(p_Stats);
42149 + ASSERT_COND(p_Manip->h_Ad);
42150 + ASSERT_COND(p_Manip->fragParams.p_Frag);
42151 +
42152 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42153 +
42154 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
42155 +
42156 + return E_OK;
42157 +}
42158 +
42159 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
42160 + t_FmPcdManip *p_Manip)
42161 +{
42162 + uint32_t maxSetNumber = 10000;
42163 + t_FmPcdManipReassemCapwapParams reassmManipParams =
42164 + p_ManipReassmParams->u.capwapReassem;
42165 + t_Error res;
42166 +
42167 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
42168 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
42169 + E_INVALID_HANDLE);
42170 +
42171 + /* Check validation of user's parameter.*/
42172 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
42173 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
42174 + RETURN_ERROR(
42175 + MAJOR, E_INVALID_VALUE,
42176 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
42177 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
42178 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
42179 + if (reassmManipParams.maxNumFramesInProcess
42180 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
42181 + RETURN_ERROR(
42182 + MAJOR,
42183 + E_INVALID_VALUE,
42184 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
42185 +
42186 + /* Saves user's reassembly manipulation parameters */
42187 + p_Manip->reassmParams.capwap.relativeSchemeId =
42188 + reassmManipParams.relativeSchemeId;
42189 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
42190 + reassmManipParams.numOfFramesPerHashEntry;
42191 + p_Manip->reassmParams.capwap.maxRessembledsSize =
42192 + reassmManipParams.maxReassembledFrameLength;
42193 + p_Manip->reassmParams.maxNumFramesInProcess =
42194 + reassmManipParams.maxNumFramesInProcess;
42195 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
42196 + p_Manip->reassmParams.fqidForTimeOutFrames =
42197 + reassmManipParams.fqidForTimeOutFrames;
42198 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
42199 + reassmManipParams.timeoutThresholdForReassmProcess;
42200 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
42201 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
42202 +
42203 + /* Creates and initializes the Reassembly common parameter table */
42204 + CreateReassCommonTable(p_Manip);
42205 +
42206 + res = SetCapwapReassmManip(p_Manip);
42207 + if (res != E_OK)
42208 + return res;
42209 +
42210 + return E_OK;
42211 +}
42212 +
42213 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
42214 + t_FmPcdManip *p_Manip)
42215 +{
42216 + t_FmPcd *p_FmPcd;
42217 + t_AdOfTypeContLookup *p_Ad;
42218 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
42219 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42220 +
42221 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42222 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
42223 + E_INVALID_VALUE);
42224 + p_FmPcd = p_Manip->h_FmPcd;
42225 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
42226 +
42227 + /* Allocation of fragmentation Action Descriptor */
42228 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
42229 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42230 + FM_PCD_CC_AD_TABLE_ALIGN);
42231 + if (!p_Manip->fragParams.p_Frag)
42232 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42233 + ("MURAM alloc for Fragmentation table descriptor"));
42234 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42235 +
42236 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
42237 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42238 +
42239 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
42240 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
42241 + ccAdBaseReg |=
42242 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
42243 + 0;
42244 +
42245 + /* Set Scatter/Gather BPid */
42246 + if (p_ManipParams->sgBpidEn)
42247 + {
42248 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
42249 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
42250 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
42251 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
42252 + }
42253 +
42254 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
42255 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
42256 + - p_FmPcd->physicalMuramBase);
42257 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
42258 +
42259 + /* Set all Ad registers */
42260 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
42261 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
42262 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
42263 +
42264 + /* Saves user's fragmentation manipulation parameters */
42265 + p_Manip->frag = TRUE;
42266 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42267 +
42268 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42269 +
42270 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
42271 + - (p_FmPcd->physicalMuramBase));
42272 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
42273 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
42274 +
42275 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42276 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
42277 +
42278 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
42279 +
42280 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42281 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
42282 + WRITE_UINT32(p_Ad->gmask, 0);
42283 + /* Total frame counter - MUST be initialized to zero.*/
42284 +
42285 + return E_OK;
42286 +}
42287 +
42288 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
42289 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
42290 + t_Handle h_Ad, bool validate)
42291 +{
42292 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42293 + t_Error err;
42294 +
42295 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42296 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
42297 + E_INVALID_STATE);
42298 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
42299 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
42300 +
42301 + UNUSED(h_FmPcd);
42302 + UNUSED(h_Ad);
42303 + UNUSED(h_PcdParams);
42304 + UNUSED(validate);
42305 + UNUSED(p_Manip);
42306 +
42307 + fmPortGetSetCcParams.setCcParams.type = 0;
42308 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
42309 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
42310 + RETURN_ERROR(MAJOR, err, NO_MSG);
42311 +
42312 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
42313 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
42314 +
42315 + return E_OK;
42316 +}
42317 +
42318 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
42319 + t_FmPcdManip *p_Manip)
42320 +{
42321 + t_AdOfTypeContLookup *p_Ad;
42322 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
42323 + t_Error err = E_OK;
42324 + uint32_t tmpReg32 = 0;
42325 +
42326 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
42327 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
42328 +
42329 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
42330 +
42331 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42332 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42333 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
42334 + /* TODO - add 'qosSrc' */
42335 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42336 +
42337 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
42338 + if (p_ManipParams->h_NextManip)
42339 + {
42340 + WRITE_UINT32(
42341 + p_Ad->matchTblPtr,
42342 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
42343 +
42344 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
42345 + }
42346 +
42347 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42348 +
42349 + return err;
42350 +}
42351 +#endif /* (DPAA_VERSION >= 11) */
42352 +
42353 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
42354 + bool stats)
42355 +{
42356 + t_FmPcdManip *p_Manip;
42357 + t_Error err;
42358 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42359 +
42360 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
42361 + if (!p_Manip)
42362 + {
42363 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
42364 + return NULL;
42365 + }
42366 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
42367 +
42368 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
42369 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
42370 + sizeof(p_Manip->manipParams));
42371 +
42372 + if (!stats)
42373 + err = CheckManipParamsAndSetType(p_Manip,
42374 + (t_FmPcdManipParams *)p_Params);
42375 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42376 + else
42377 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
42378 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42379 + else
42380 + {
42381 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
42382 + XX_Free(p_Manip);
42383 + return NULL;
42384 + }
42385 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42386 + if (err)
42387 + {
42388 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
42389 + XX_Free(p_Manip);
42390 + return NULL;
42391 + }
42392 +
42393 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
42394 + {
42395 + /* In Case of reassembly manipulation the reassembly action descriptor will
42396 + be defines later on */
42397 + if (p_Manip->muramAllocate)
42398 + {
42399 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
42400 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
42401 + FM_PCD_CC_AD_TABLE_ALIGN);
42402 + if (!p_Manip->h_Ad)
42403 + {
42404 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
42405 + ReleaseManipHandler(p_Manip, p_FmPcd);
42406 + XX_Free(p_Manip);
42407 + return NULL;
42408 + }
42409 +
42410 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42411 + }
42412 + else
42413 + {
42414 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
42415 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42416 + if (!p_Manip->h_Ad)
42417 + {
42418 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
42419 + ReleaseManipHandler(p_Manip, p_FmPcd);
42420 + XX_Free(p_Manip);
42421 + return NULL;
42422 + }
42423 +
42424 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
42425 + }
42426 + }
42427 +
42428 + p_Manip->h_FmPcd = h_FmPcd;
42429 +
42430 + return p_Manip;
42431 +}
42432 +
42433 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
42434 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
42435 +{
42436 + t_CcNodeInformation *p_CcNodeInformation;
42437 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
42438 + t_List *p_Pos;
42439 + int i = 0;
42440 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
42441 + t_CcNodeInformation ccNodeInfo;
42442 +
42443 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
42444 + {
42445 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
42446 + p_NodePtrOnCurrentMdfManip =
42447 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
42448 +
42449 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
42450 +
42451 + /* Search in the previous node which exact index points on this current modified node for getting AD */
42452 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
42453 + {
42454 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
42455 + == e_FM_PCD_CC)
42456 + {
42457 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
42458 + == (t_Handle)p_CrntMdfManip)
42459 + {
42460 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
42461 + p_AdTablePtOnCrntCurrentMdfNode =
42462 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
42463 + else
42464 + p_AdTablePtOnCrntCurrentMdfNode =
42465 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
42466 +
42467 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
42468 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
42469 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
42470 + }
42471 + }
42472 + }
42473 +
42474 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
42475 + }
42476 +}
42477 +
42478 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
42479 + t_FmPcd *p_FmPcd)
42480 +{
42481 + t_Error err;
42482 +
42483 + /* Copy the HMTD */
42484 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
42485 + /* Replace the HMCT table pointer */
42486 + WRITE_UINT32(
42487 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
42488 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
42489 + /* Call Host Command to replace HMTD by a new HMTD */
42490 + err = FmHcPcdCcDoDynamicChange(
42491 + p_FmPcd->h_Hc,
42492 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
42493 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
42494 + if (err)
42495 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
42496 +}
42497 +
42498 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42499 + t_Handle h_FmPort, t_Handle h_Manip,
42500 + t_Handle h_Ad, bool validate, int level,
42501 + t_Handle h_FmTree)
42502 +{
42503 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42504 + t_Error err = E_OK;
42505 +
42506 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42507 +
42508 + UNUSED(level);
42509 + UNUSED(h_FmTree);
42510 +
42511 + switch (p_Manip->opcode)
42512 + {
42513 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42514 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42515 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
42516 + p_Manip,
42517 + h_Ad,
42518 + validate);
42519 + break;
42520 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42521 + if (!p_Manip->h_Frag)
42522 + break;
42523 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42524 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
42525 + break;
42526 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42527 + if (p_Manip->h_Frag)
42528 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
42529 + break;
42530 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42531 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
42532 + break;
42533 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42534 + case (HMAN_OC_IP_REASSEMBLY):
42535 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42536 + validate);
42537 + break;
42538 + case (HMAN_OC_IP_FRAGMENTATION):
42539 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42540 + h_Ad, validate);
42541 + break;
42542 +#if (DPAA_VERSION >= 11)
42543 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42544 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
42545 + h_Ad, validate);
42546 + break;
42547 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42548 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
42549 + validate);
42550 + break;
42551 +#endif /* (DPAA_VERSION >= 11) */
42552 + default:
42553 + return E_OK;
42554 + }
42555 +
42556 + return err;
42557 +}
42558 +
42559 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
42560 + bool validate, int level,
42561 + t_Handle h_FmTree)
42562 +{
42563 +
42564 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42565 + t_Error err = E_OK;
42566 +
42567 + UNUSED(level);
42568 +
42569 + switch (p_Manip->opcode)
42570 + {
42571 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42572 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42573 + RETURN_ERROR(
42574 + MAJOR,
42575 + E_INVALID_STATE,
42576 + ("modify node with this type of manipulation is not suppported"));
42577 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42578 +
42579 + if (p_Manip->h_Frag)
42580 + {
42581 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
42582 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
42583 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
42584 + RETURN_ERROR(
42585 + MAJOR,
42586 + E_INVALID_STATE,
42587 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
42588 + }
42589 + break;
42590 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42591 + if (p_Manip->h_Frag)
42592 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
42593 + break;
42594 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42595 + default:
42596 + return E_OK;
42597 + }
42598 +
42599 + return err;
42600 +}
42601 +
42602 +/*****************************************************************************/
42603 +/* Inter-module API routines */
42604 +/*****************************************************************************/
42605 +
42606 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
42607 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
42608 + bool validate, int level, t_Handle h_FmTree,
42609 + bool modify)
42610 +{
42611 + t_Error err;
42612 +
42613 + if (!modify)
42614 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
42615 + h_Ad, validate, level, h_FmTree);
42616 + else
42617 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
42618 +
42619 + return err;
42620 +}
42621 +
42622 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
42623 +{
42624 +
42625 + uint32_t intFlags;
42626 +
42627 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
42628 + if (add)
42629 + ((t_FmPcdManip *)h_Manip)->owner++;
42630 + else
42631 + {
42632 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
42633 + ((t_FmPcdManip *)h_Manip)->owner--;
42634 + }
42635 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
42636 +}
42637 +
42638 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
42639 +{
42640 + ASSERT_COND(h_Manip);
42641 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
42642 +}
42643 +
42644 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
42645 +{
42646 + ASSERT_COND(h_Manip);
42647 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
42648 +}
42649 +
42650 +t_Error FmPcdManipCheckParamsForCcNextEngine(
42651 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
42652 + uint32_t *requiredAction)
42653 +{
42654 + t_FmPcdManip *p_Manip;
42655 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42656 + t_Error err = E_OK;
42657 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
42658 + bool pointFromCc = TRUE;
42659 +
42660 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
42661 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
42662 + E_NULL_POINTER);
42663 +
42664 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
42665 + *requiredAction = 0;
42666 +
42667 + while (p_Manip)
42668 + {
42669 + switch (p_Manip->opcode)
42670 + {
42671 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42672 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42673 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42674 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42675 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42676 + p_Manip->cnia = TRUE;
42677 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42678 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42679 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42680 + p_Manip->ownerTmp++;
42681 + break;
42682 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42683 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42684 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
42685 + RETURN_ERROR(
42686 + MAJOR,
42687 + E_INVALID_STATE,
42688 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
42689 + p_Manip->ownerTmp++;
42690 + break;
42691 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42692 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
42693 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
42694 + != CC_PC_GENERIC_IC_HASH_INDEXED))
42695 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation next engine has to be CC and action = e_FM_PCD_ACTION_INDEXED_LOOKUP"));
42696 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
42697 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
42698 + if (err)
42699 + RETURN_ERROR(MAJOR, err, NO_MSG);
42700 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
42701 + break;
42702 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42703 + case (HMAN_OC_IP_FRAGMENTATION):
42704 + case (HMAN_OC_IP_REASSEMBLY):
42705 +#if (DPAA_VERSION >= 11)
42706 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42707 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42708 +#endif /* (DPAA_VERSION >= 11) */
42709 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
42710 + RETURN_ERROR(
42711 + MAJOR,
42712 + E_INVALID_STATE,
42713 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
42714 + p_Manip->ownerTmp++;
42715 + break;
42716 + case (HMAN_OC_IPSEC_MANIP):
42717 +#if (DPAA_VERSION >= 11)
42718 + case (HMAN_OC_CAPWAP_MANIP):
42719 +#endif /* (DPAA_VERSION >= 11) */
42720 + p_Manip->ownerTmp++;
42721 + break;
42722 + case (HMAN_OC):
42723 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
42724 + && MANIP_IS_CASCADED(p_Manip))
42725 + RETURN_ERROR(
42726 + MINOR,
42727 + E_INVALID_STATE,
42728 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
42729 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
42730 + RETURN_ERROR(
42731 + MAJOR,
42732 + E_INVALID_STATE,
42733 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
42734 + break;
42735 + default:
42736 + RETURN_ERROR(
42737 + MAJOR, E_INVALID_STATE,
42738 + ("invalid type of header manipulation for this state"));
42739 + }
42740 + p_Manip = p_Manip->h_NextManip;
42741 + pointFromCc = FALSE;
42742 + }
42743 + return E_OK;
42744 +}
42745 +
42746 +
42747 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
42748 + t_Handle h_FmPcdCcNode)
42749 +{
42750 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42751 + t_Error err = E_OK;
42752 +
42753 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
42754 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
42755 +
42756 + switch (p_Manip->opcode)
42757 + {
42758 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42759 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42760 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42761 + RETURN_ERROR(
42762 + MAJOR,
42763 + E_INVALID_VALUE,
42764 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
42765 + break;
42766 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42767 + if (p_Manip->h_Frag)
42768 + {
42769 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
42770 + RETURN_ERROR(
42771 + MAJOR,
42772 + E_INVALID_VALUE,
42773 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
42774 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
42775 + if (err)
42776 + RETURN_ERROR(MAJOR, err, NO_MSG);
42777 + }
42778 + break;
42779 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42780 + default:
42781 + break;
42782 + }
42783 +
42784 + return err;
42785 +}
42786 +
42787 +void FmPcdManipUpdateAdResultForCc(
42788 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
42789 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
42790 +{
42791 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42792 +
42793 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42794 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42795 +
42796 + ASSERT_COND(p_Manip);
42797 + ASSERT_COND(p_CcNextEngineParams);
42798 + ASSERT_COND(p_Ad);
42799 + ASSERT_COND(p_AdNewPtr);
42800 +
42801 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42802 +
42803 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
42804 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
42805 + switch (p_Manip->opcode)
42806 + {
42807 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42808 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
42809 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
42810 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
42811 + *p_AdNewPtr = p_Manip->h_Ad;
42812 + break;
42813 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
42814 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42815 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
42816 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
42817 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
42818 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
42819 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
42820 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
42821 + *p_AdNewPtr = NULL;
42822 + break;
42823 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42824 + case (HMAN_OC_IPSEC_MANIP):
42825 +#if (DPAA_VERSION >= 11)
42826 + case (HMAN_OC_CAPWAP_MANIP):
42827 +#endif /* (DPAA_VERSION >= 11) */
42828 + *p_AdNewPtr = p_Manip->h_Ad;
42829 + break;
42830 + case (HMAN_OC_IP_FRAGMENTATION):
42831 +#if (DPAA_VERSION >= 11)
42832 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
42833 +#endif /* (DPAA_VERSION >= 11) */
42834 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
42835 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
42836 + {
42837 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
42838 + sizeof(t_AdOfTypeContLookup));
42839 +#if (DPAA_VERSION >= 11)
42840 + WRITE_UINT32(
42841 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42842 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
42843 +#endif /* (DPAA_VERSION >= 11) */
42844 + *p_AdNewPtr = NULL;
42845 + }
42846 + else
42847 + *p_AdNewPtr = p_Manip->h_Ad;
42848 + break;
42849 + case (HMAN_OC_IP_REASSEMBLY):
42850 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
42851 + {
42852 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
42853 + {
42854 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
42855 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
42856 + FmPcdManipUpdateOwner(h_Manip, FALSE);
42857 + }
42858 + else
42859 + {
42860 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42861 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
42862 + }
42863 + }
42864 + else
42865 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
42866 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42867 + sizeof(t_AdOfTypeContLookup));
42868 + *p_AdNewPtr = NULL;
42869 + break;
42870 +#if (DPAA_VERSION >= 11)
42871 + case (HMAN_OC_CAPWAP_REASSEMBLY):
42872 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
42873 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
42874 + sizeof(t_AdOfTypeContLookup));
42875 + *p_AdNewPtr = NULL;
42876 + break;
42877 +#endif /* (DPAA_VERSION >= 11) */
42878 + case (HMAN_OC):
42879 + /* Allocate and initialize HMTD */
42880 + *p_AdNewPtr = p_Manip->h_Ad;
42881 + break;
42882 + default:
42883 + break;
42884 + }
42885 +}
42886 +
42887 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
42888 + t_Handle *p_AdNewPtr,
42889 + uint32_t adTableOffset)
42890 +{
42891 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42892 +
42893 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
42894 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
42895 + ASSERT_COND(p_Manip);
42896 +
42897 + FmPcdManipUpdateOwner(h_Manip, TRUE);
42898 +
42899 + switch (p_Manip->opcode)
42900 + {
42901 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42902 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
42903 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42904 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
42905 + WRITE_UINT32(
42906 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
42907 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
42908 + WRITE_UINT32(
42909 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
42910 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
42911 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
42912 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
42913 + WRITE_UINT32(
42914 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
42915 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
42916 + *p_AdNewPtr = NULL;
42917 + break;
42918 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42919 + case (HMAN_OC):
42920 + /* Initialize HMTD within the match table*/
42921 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42922 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
42923 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
42924 + /* update NADEN to be "1"*/
42925 + WRITE_UINT16(
42926 + ((t_Hmtd *)p_Ad)->cfg,
42927 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
42928 + /* update next action descriptor */
42929 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
42930 + (uint16_t)(adTableOffset >> 4));
42931 + /* mark that Manip's HMTD is not used */
42932 + *p_AdNewPtr = NULL;
42933 + break;
42934 +
42935 + default:
42936 + break;
42937 + }
42938 +}
42939 +
42940 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
42941 + t_Handle h_CcTree, t_Handle h_Manip,
42942 + bool isIpv4, uint8_t groupId)
42943 +{
42944 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
42945 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
42946 + t_Handle h_Scheme;
42947 +
42948 + ASSERT_COND(p_FmPcd);
42949 + ASSERT_COND(h_NetEnv);
42950 + ASSERT_COND(p_Manip);
42951 +
42952 + /* scheme was already build, no need to check for IPv6 */
42953 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
42954 + return E_OK;
42955 +
42956 + if (isIpv4) {
42957 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
42958 + if (h_Scheme) {
42959 + /* scheme was found */
42960 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
42961 + return E_OK;
42962 + }
42963 + } else {
42964 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
42965 + if (h_Scheme) {
42966 + /* scheme was found */
42967 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
42968 + return E_OK;
42969 + }
42970 + }
42971 +
42972 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
42973 + if (!p_SchemeParams)
42974 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
42975 + ("Memory allocation failed for scheme"));
42976 +
42977 + /* Configures the IPv4 or IPv6 scheme*/
42978 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
42979 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
42980 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
42981 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
42982 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
42983 + p_SchemeParams->schemeCounter.update = TRUE;
42984 +#if (DPAA_VERSION >= 11)
42985 + p_SchemeParams->alwaysDirect = TRUE;
42986 + p_SchemeParams->bypassFqidGeneration = TRUE;
42987 +#else
42988 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
42989 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
42990 +#endif /* (DPAA_VERSION >= 11) */
42991 +
42992 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
42993 +
42994 + /* Sets the new scheme */
42995 + if (isIpv4)
42996 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
42997 + p_FmPcd, p_SchemeParams);
42998 + else
42999 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
43000 + p_FmPcd, p_SchemeParams);
43001 +
43002 + XX_Free(p_SchemeParams);
43003 +
43004 + return E_OK;
43005 +}
43006 +
43007 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
43008 +{
43009 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43010 +
43011 + ASSERT_COND(p_Manip);
43012 +
43013 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
43014 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
43015 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
43016 +
43017 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
43018 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
43019 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
43020 +
43021 + return E_OK;
43022 +}
43023 +
43024 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
43025 +{
43026 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43027 +
43028 + ASSERT_COND(p_Manip);
43029 +
43030 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
43031 +}
43032 +
43033 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
43034 + t_Handle h_CcTree, t_Handle h_Manip,
43035 + uint8_t groupId)
43036 +{
43037 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43038 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
43039 +
43040 + ASSERT_COND(p_FmPcd);
43041 + ASSERT_COND(h_NetEnv);
43042 + ASSERT_COND(p_Manip);
43043 +
43044 + /* scheme was already build, no need to check for IPv6 */
43045 + if (p_Manip->reassmParams.capwap.h_Scheme)
43046 + return E_OK;
43047 +
43048 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
43049 + if (!p_SchemeParams)
43050 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43051 + ("Memory allocation failed for scheme"));
43052 +
43053 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
43054 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
43055 + p_SchemeParams->id.relativeSchemeId =
43056 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
43057 + p_SchemeParams->schemeCounter.update = TRUE;
43058 + p_SchemeParams->bypassFqidGeneration = TRUE;
43059 +
43060 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
43061 +
43062 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
43063 + p_SchemeParams);
43064 +
43065 + XX_Free(p_SchemeParams);
43066 +
43067 + return E_OK;
43068 +}
43069 +
43070 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
43071 +{
43072 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43073 +
43074 + ASSERT_COND(p_Manip);
43075 +
43076 + if (p_Manip->reassmParams.capwap.h_Scheme)
43077 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
43078 +
43079 + return E_OK;
43080 +}
43081 +
43082 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43083 +t_Handle FmPcdManipApplSpecificBuild(void)
43084 +{
43085 + t_FmPcdManip *p_Manip;
43086 +
43087 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
43088 + if (!p_Manip)
43089 + {
43090 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
43091 + return NULL;
43092 + }
43093 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
43094 +
43095 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
43096 + p_Manip->muramAllocate = FALSE;
43097 +
43098 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43099 + if (!p_Manip->h_Ad)
43100 + {
43101 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
43102 + XX_Free(p_Manip);
43103 + return NULL;
43104 + }
43105 +
43106 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
43107 +
43108 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
43109 + /*Application specific = type of flowId index, move internal frame header from data to IC,
43110 + SEC errors check*/
43111 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
43112 + {
43113 + XX_Free(p_Manip->h_Ad);
43114 + XX_Free(p_Manip);
43115 + return NULL;
43116 + }
43117 + return p_Manip;
43118 +}
43119 +
43120 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
43121 +{
43122 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
43123 + ASSERT_COND(h_Manip);
43124 +
43125 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
43126 +}
43127 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43128 +/*********************** End of inter-module routines ************************/
43129 +
43130 +/****************************************/
43131 +/* API Init unit functions */
43132 +/****************************************/
43133 +
43134 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
43135 + t_FmPcdManipParams *p_ManipParams)
43136 +{
43137 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43138 + t_FmPcdManip *p_Manip;
43139 + t_Error err;
43140 +
43141 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
43142 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
43143 +
43144 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
43145 + if (!p_Manip)
43146 + return NULL;
43147 +
43148 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
43149 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
43150 + || (p_Manip->opcode == HMAN_OC)
43151 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
43152 +#if (DPAA_VERSION >= 11)
43153 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
43154 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
43155 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
43156 +#endif /* (DPAA_VERSION >= 11) */
43157 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
43158 + {
43159 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
43160 + XX_Free(p_Manip);
43161 + return NULL;
43162 + }
43163 + p_Manip->h_Spinlock = XX_InitSpinlock();
43164 + if (!p_Manip->h_Spinlock)
43165 + {
43166 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43167 + ReleaseManipHandler(p_Manip, p_FmPcd);
43168 + XX_Free(p_Manip);
43169 + return NULL;
43170 + }INIT_LIST(&p_Manip->nodesLst);
43171 +
43172 + switch (p_Manip->opcode)
43173 + {
43174 + case (HMAN_OC_IP_REASSEMBLY):
43175 + /* IpReassembly */
43176 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
43177 + break;
43178 + case (HMAN_OC_IP_FRAGMENTATION):
43179 + /* IpFragmentation */
43180 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
43181 + if (err)
43182 + break;
43183 + err = IPManip(p_Manip);
43184 + break;
43185 + case (HMAN_OC_IPSEC_MANIP):
43186 + err = IPSecManip(p_ManipParams, p_Manip);
43187 + break;
43188 +#if (DPAA_VERSION >= 11)
43189 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43190 + /* CapwapReassembly */
43191 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
43192 + break;
43193 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43194 + /* CapwapFragmentation */
43195 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
43196 + p_Manip);
43197 + break;
43198 + case (HMAN_OC_CAPWAP_MANIP):
43199 + err = CapwapManip(p_ManipParams, p_Manip);
43200 + break;
43201 +#endif /* (DPAA_VERSION >= 11) */
43202 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43203 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
43204 + /* HmanType1 */
43205 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
43206 + break;
43207 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43208 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
43209 + p_Manip,
43210 + p_FmPcd,
43211 + p_ManipParams->fragOrReasmParams.sgBpid);
43212 + if (err)
43213 + {
43214 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43215 + ReleaseManipHandler(p_Manip, p_FmPcd);
43216 + XX_Free(p_Manip);
43217 + return NULL;
43218 + }
43219 + if (p_Manip->insrt)
43220 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
43221 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
43222 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
43223 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
43224 + break;
43225 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43226 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
43227 + p_Manip,
43228 + p_FmPcd,
43229 + p_ManipParams->fragOrReasmParams.sgBpid);
43230 + if (err)
43231 + {
43232 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43233 + ReleaseManipHandler(p_Manip, p_FmPcd);
43234 + XX_Free(p_Manip);
43235 + return NULL;
43236 + }
43237 + if (p_Manip->rmv)
43238 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
43239 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
43240 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
43241 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
43242 + break;
43243 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
43244 + /*Application Specific type 1*/
43245 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
43246 + break;
43247 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43248 + case (HMAN_OC):
43249 + /* New Manip */
43250 + err = CreateManipActionNew(p_Manip, p_ManipParams);
43251 + break;
43252 + default:
43253 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
43254 + ReleaseManipHandler(p_Manip, p_FmPcd);
43255 + XX_Free(p_Manip);
43256 + return NULL;
43257 + }
43258 +
43259 + if (err)
43260 + {
43261 + REPORT_ERROR(MAJOR, err, NO_MSG);
43262 + ReleaseManipHandler(p_Manip, p_FmPcd);
43263 + XX_Free(p_Manip);
43264 + return NULL;
43265 + }
43266 +
43267 + if (p_ManipParams->h_NextManip)
43268 + {
43269 + /* in the check routine we've verified that h_NextManip has no owners
43270 + * and that only supported types are allowed. */
43271 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
43272 + /* save a "prev" pointer in h_NextManip */
43273 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
43274 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
43275 + }
43276 +
43277 + return p_Manip;
43278 +}
43279 +
43280 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
43281 + t_FmPcdManipParams *p_ManipParams)
43282 +{
43283 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
43284 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
43285 + t_Error err;
43286 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
43287 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
43288 + t_CcNodeInformation *p_CcNodeInfo;
43289 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
43290 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43291 +
43292 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
43293 +
43294 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
43295 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
43296 + RETURN_ERROR(
43297 + MINOR,
43298 + E_NOT_SUPPORTED,
43299 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
43300 +
43301 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
43302 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
43303 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
43304 + sizeof(p_Manip->manipParams));
43305 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
43306 +
43307 + /* The replacement of the HdrManip depends on the node type.*/
43308 + /*
43309 + * (1) If this is an independent node, all its owners should be updated.
43310 + *
43311 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
43312 + * it has a "next" and it has a "cascaded" indication), the next
43313 + * node remains unchanged, and the behavior is as in (1).
43314 + *
43315 + * (3) If it is not the head, but a part of a cascaded chain, in can be
43316 + * also replaced as a regular node with just one owner.
43317 + *
43318 + * (4) If it is a part of a chain implemented as a unified table, the
43319 + * whole table is replaced and the owners of the head node must be updated.
43320 + *
43321 + */
43322 + /* lock shadow */
43323 + if (!p_FmPcd->p_CcShadow)
43324 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
43325 +
43326 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
43327 + return ERROR_CODE(E_BUSY);
43328 +
43329 + /* this routine creates a new manip action in the CC Shadow. */
43330 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
43331 + if (err)
43332 + RETURN_ERROR(MINOR, err, NO_MSG);
43333 +
43334 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
43335 + * replace only HMTD and no lcok is required. Otherwise
43336 + * lock the whole PCD
43337 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
43338 + if (!FmPcdLockTryLockAll(p_FmPcd))
43339 + {
43340 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
43341 + return ERROR_CODE(E_BUSY);
43342 + }
43343 +
43344 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
43345 +
43346 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
43347 + e_MANIP_HANDLER_TABLE_OWNER);
43348 + ASSERT_COND(p_FirstManip);
43349 +
43350 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
43351 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
43352 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
43353 +
43354 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43355 + ASSERT_COND(p_Hmtd);
43356 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
43357 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
43358 +
43359 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43360 + {
43361 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43362 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43363 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43364 + }
43365 +
43366 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
43367 + ASSERT_COND(p_WholeHmct);
43368 +
43369 + /* re-build the HMCT n the original location */
43370 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
43371 + if (err)
43372 + {
43373 + RELEASE_LOCK(p_FmPcd->shadowLock);
43374 + RETURN_ERROR(MINOR, err, NO_MSG);
43375 + }
43376 +
43377 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
43378 + ASSERT_COND(p_Hmtd);
43379 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
43380 + ((t_FmPcd*)p_Manip->h_FmPcd));
43381 +
43382 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
43383 + * For each p_Hmct (from list+fixed):
43384 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
43385 + {
43386 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
43387 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
43388 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
43389 + }
43390 +
43391 +
43392 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
43393 +
43394 + FmPcdLockUnlockAll(p_FmPcd);
43395 +
43396 + /* unlock shadow */
43397 + RELEASE_LOCK(p_FmPcd->shadowLock);
43398 +
43399 + return E_OK;
43400 +}
43401 +
43402 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
43403 +{
43404 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43405 +
43406 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43407 +
43408 + if (p_Manip->owner)
43409 + RETURN_ERROR(
43410 + MAJOR,
43411 + E_INVALID_STATE,
43412 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
43413 +
43414 + if (p_Manip->h_NextManip)
43415 + {
43416 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
43417 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
43418 + }
43419 +
43420 + if (p_Manip->p_Hmct
43421 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
43422 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
43423 + p_Manip->p_Hmct);
43424 +
43425 + if (p_Manip->h_Spinlock)
43426 + {
43427 + XX_FreeSpinlock(p_Manip->h_Spinlock);
43428 + p_Manip->h_Spinlock = NULL;
43429 + }
43430 +
43431 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
43432 +
43433 + XX_Free(h_ManipNode);
43434 +
43435 + return E_OK;
43436 +}
43437 +
43438 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
43439 + t_FmPcdManipStats *p_FmPcdManipStats)
43440 +{
43441 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
43442 +
43443 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43444 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
43445 +
43446 + switch (p_Manip->opcode)
43447 + {
43448 + case (HMAN_OC_IP_REASSEMBLY):
43449 + return IpReassemblyStats(p_Manip,
43450 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
43451 + case (HMAN_OC_IP_FRAGMENTATION):
43452 + return IpFragmentationStats(p_Manip,
43453 + &p_FmPcdManipStats->u.frag.u.ipFrag);
43454 +#if (DPAA_VERSION >= 11)
43455 + case (HMAN_OC_CAPWAP_REASSEMBLY):
43456 + return CapwapReassemblyStats(
43457 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
43458 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
43459 + return CapwapFragmentationStats(
43460 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
43461 +#endif /* (DPAA_VERSION >= 11) */
43462 + default:
43463 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
43464 + ("no statistics to this type of manip"));
43465 + }
43466 +
43467 + return E_OK;
43468 +}
43469 +
43470 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43471 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
43472 +{
43473 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
43474 + t_FmPcdManip *p_Manip;
43475 + t_Error err;
43476 +
43477 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
43478 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
43479 +
43480 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
43481 + if (!p_Manip)
43482 + return NULL;
43483 +
43484 + switch (p_Manip->opcode)
43485 + {
43486 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
43487 + /* Indexed statistics */
43488 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
43489 + break;
43490 + default:
43491 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
43492 + ReleaseManipHandler(p_Manip, p_FmPcd);
43493 + XX_Free(p_Manip);
43494 + return NULL;
43495 + }
43496 +
43497 + if (err)
43498 + {
43499 + REPORT_ERROR(MAJOR, err, NO_MSG);
43500 + ReleaseManipHandler(p_Manip, p_FmPcd);
43501 + XX_Free(p_Manip);
43502 + return NULL;
43503 + }
43504 +
43505 + return p_Manip;
43506 +}
43507 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43508 --- /dev/null
43509 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
43510 @@ -0,0 +1,555 @@
43511 +/*
43512 + * Copyright 2008-2012 Freescale Semiconductor Inc.
43513 + *
43514 + * Redistribution and use in source and binary forms, with or without
43515 + * modification, are permitted provided that the following conditions are met:
43516 + * * Redistributions of source code must retain the above copyright
43517 + * notice, this list of conditions and the following disclaimer.
43518 + * * Redistributions in binary form must reproduce the above copyright
43519 + * notice, this list of conditions and the following disclaimer in the
43520 + * documentation and/or other materials provided with the distribution.
43521 + * * Neither the name of Freescale Semiconductor nor the
43522 + * names of its contributors may be used to endorse or promote products
43523 + * derived from this software without specific prior written permission.
43524 + *
43525 + *
43526 + * ALTERNATIVELY, this software may be distributed under the terms of the
43527 + * GNU General Public License ("GPL") as published by the Free Software
43528 + * Foundation, either version 2 of that License or (at your option) any
43529 + * later version.
43530 + *
43531 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
43532 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43533 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43534 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
43535 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43536 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43537 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43538 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43539 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43540 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43541 + */
43542 +
43543 +
43544 +/******************************************************************************
43545 + @File fm_manip.h
43546 +
43547 + @Description FM PCD manip...
43548 +*//***************************************************************************/
43549 +#ifndef __FM_MANIP_H
43550 +#define __FM_MANIP_H
43551 +
43552 +#include "std_ext.h"
43553 +#include "error_ext.h"
43554 +#include "list_ext.h"
43555 +
43556 +#include "fm_cc.h"
43557 +
43558 +
43559 +/***********************************************************************/
43560 +/* Header manipulations defines */
43561 +/***********************************************************************/
43562 +
43563 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
43564 +
43565 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43566 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
43567 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
43568 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
43569 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
43570 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
43571 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
43572 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43573 +#else
43574 +#define HMAN_OC_CAPWAP_MANIP 0x2F
43575 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
43576 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
43577 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
43578 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43579 +#define HMAN_OC_IP_MANIP 0x34
43580 +#define HMAN_OC_IP_FRAGMENTATION 0x74
43581 +#define HMAN_OC_IP_REASSEMBLY 0xB4
43582 +#define HMAN_OC_IPSEC_MANIP 0xF4
43583 +#define HMAN_OC 0x35
43584 +
43585 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43586 +#define HMAN_RMV_HDR 0x80000000
43587 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
43588 +
43589 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
43590 +#define UDP_CHECKSUM_FIELD_SIZE 2
43591 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
43592 +
43593 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
43594 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
43595 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
43596 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
43597 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
43598 +
43599 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
43600 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
43601 +
43602 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
43603 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
43604 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
43605 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
43606 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
43607 +
43608 +
43609 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
43610 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
43611 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
43612 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
43613 +
43614 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
43615 +
43616 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
43617 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
43618 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
43619 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43620 +
43621 +#if (DPAA_VERSION >= 11)
43622 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
43623 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
43624 +
43625 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
43626 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
43627 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
43628 +
43629 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
43630 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
43631 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
43632 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
43633 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
43634 +#endif /* (DPAA_VERSION >= 11) */
43635 +
43636 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
43637 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
43638 +
43639 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
43640 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
43641 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
43642 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
43643 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
43644 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
43645 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
43646 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
43647 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
43648 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
43649 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
43650 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
43651 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
43652 +
43653 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
43654 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
43655 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
43656 +
43657 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
43658 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
43659 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
43660 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
43661 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
43662 +
43663 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
43664 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
43665 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
43666 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
43667 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
43668 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
43669 +
43670 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
43671 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
43672 +
43673 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
43674 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
43675 +
43676 +#define e_FM_MANIP_IP_INDX 1
43677 +
43678 +#define HMCD_OPCODE_GENERIC_RMV 0x01
43679 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
43680 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
43681 +#define HMCD_OPCODE_L2_RMV 0x08
43682 +#define HMCD_OPCODE_L2_INSRT 0x09
43683 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
43684 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
43685 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
43686 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
43687 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
43688 +#define HMCD_OPCODE_REPLACE_IP 0x12
43689 +#define HMCD_OPCODE_RMV_TILL 0x15
43690 +#define HMCD_OPCODE_UDP_INSRT 0x16
43691 +#define HMCD_OPCODE_IP_INSRT 0x17
43692 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
43693 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
43694 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
43695 +
43696 +#define HMCD_LAST 0x00800000
43697 +
43698 +#define HMCD_DSCP_VALUES 64
43699 +
43700 +#define HMCD_BASIC_SIZE 4
43701 +#define HMCD_PTR_SIZE 4
43702 +#define HMCD_PARAM_SIZE 4
43703 +#define HMCD_IPV4_ADDR_SIZE 4
43704 +#define HMCD_IPV6_ADDR_SIZE 0x10
43705 +#define HMCD_L4_HDR_SIZE 8
43706 +
43707 +#define HMCD_CAPWAP_INSRT 0x00010000
43708 +#define HMCD_INSRT_UDP_LITE 0x00010000
43709 +#define HMCD_IP_ID_MASK 0x0000FFFF
43710 +#define HMCD_IP_SIZE_MASK 0x0000FF00
43711 +#define HMCD_IP_SIZE_SHIFT 8
43712 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
43713 +#define HMCD_IP_OR_QOS 0x00010000
43714 +#define HMCD_IP_L4_CS_CALC 0x00040000
43715 +#define HMCD_IP_DF_MODE 0x00400000
43716 +
43717 +
43718 +#define HMCD_OC_SHIFT 24
43719 +
43720 +#define HMCD_RMV_OFFSET_SHIFT 0
43721 +#define HMCD_RMV_SIZE_SHIFT 8
43722 +
43723 +#define HMCD_INSRT_OFFSET_SHIFT 0
43724 +#define HMCD_INSRT_SIZE_SHIFT 8
43725 +
43726 +#define HMTD_CFG_TYPE 0x4000
43727 +#define HMTD_CFG_EXT_HMCT 0x0080
43728 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
43729 +#define HMTD_CFG_NEXT_AD_EN 0x0020
43730 +
43731 +#define HMCD_RMV_L2_ETHERNET 0
43732 +#define HMCD_RMV_L2_STACKED_QTAGS 1
43733 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
43734 +#define HMCD_RMV_L2_MPLS 3
43735 +#define HMCD_RMV_L2_PPPOE 4
43736 +
43737 +#define HMCD_INSRT_L2_MPLS 0
43738 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
43739 +#define HMCD_INSRT_L2_PPPOE 2
43740 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
43741 +
43742 +#define HMCD_L2_MODE_SHIFT 16
43743 +
43744 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
43745 +#define HMCD_VLAN_PRI_UPDATE 0
43746 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
43747 +
43748 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
43749 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
43750 +#define HMCD_IPV4_UPDATE_DST 0x00000020
43751 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
43752 +#define HMCD_IPV4_UPDATE_ID 0x00000080
43753 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
43754 +
43755 +#define HMCD_IPV6_UPDATE_HL 0x00000001
43756 +#define HMCD_IPV6_UPDATE_TC 0x00000002
43757 +#define HMCD_IPV6_UPDATE_DST 0x00000040
43758 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
43759 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
43760 +
43761 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
43762 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
43763 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
43764 +
43765 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
43766 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
43767 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
43768 +#define HMCD_IP_REPLACE_ID 0x00400000
43769 +
43770 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
43771 +
43772 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
43773 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
43774 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
43775 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
43776 +
43777 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
43778 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
43779 +
43780 +#define DSCP_TO_VLAN_TABLE_SIZE 32
43781 +
43782 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
43783 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
43784 +
43785 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
43786 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
43787 +
43788 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
43789 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
43790 +
43791 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
43792 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
43793 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
43794 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
43795 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
43796 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
43797 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
43798 +#define MANIP_FREE_HMTD(h_Manip) \
43799 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
43800 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
43801 + else \
43802 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
43803 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
43804 + }
43805 +/* position regarding Manip SW structure */
43806 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
43807 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
43808 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
43809 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
43810 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
43811 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
43812 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
43813 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
43814 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
43815 +
43816 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
43817 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
43818 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
43819 +
43820 +typedef enum e_ManipUnifiedPosition {
43821 + e_MANIP_UNIFIED_NONE = 0,
43822 + e_MANIP_UNIFIED_FIRST,
43823 + e_MANIP_UNIFIED_MID,
43824 + e_MANIP_UNIFIED_LAST
43825 +} e_ManipUnifiedPosition;
43826 +
43827 +typedef enum e_ManipInfo {
43828 + e_MANIP_HMTD,
43829 + e_MANIP_HMCT,
43830 + e_MANIP_HANDLER_TABLE_OWNER
43831 +}e_ManipInfo;
43832 +/***********************************************************************/
43833 +/* Memory map */
43834 +/***********************************************************************/
43835 +#if defined(__MWERKS__) && !defined(__GNUC__)
43836 +#pragma pack(push,1)
43837 +#endif /* defined(__MWERKS__) && ... */
43838 +
43839 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43840 +typedef struct t_CapwapReasmPram {
43841 + volatile uint32_t mode;
43842 + volatile uint32_t autoLearnHashTblPtr;
43843 + volatile uint32_t intStatsTblPtr;
43844 + volatile uint32_t reasmFrmDescPoolTblPtr;
43845 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
43846 + volatile uint32_t timeOutTblPtr;
43847 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
43848 + volatile uint32_t risc23SetIndexes;
43849 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
43850 + volatile uint32_t extendedStatsTblPtr;
43851 + volatile uint32_t expirationDelay;
43852 + volatile uint32_t totalProcessedFragCounter;
43853 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
43854 + volatile uint32_t totalDuplicatedFragCounter;
43855 + volatile uint32_t totalMalformdFragCounter;
43856 + volatile uint32_t totalTimeOutCounter;
43857 + volatile uint32_t totalSetBusyCounter;
43858 + volatile uint32_t totalRfdPoolBusyCounter;
43859 + volatile uint32_t totalDiscardedFragsCounter;
43860 + volatile uint32_t totalMoreThan16FramesCounter;
43861 + volatile uint32_t internalBufferBusy;
43862 + volatile uint32_t externalBufferBusy;
43863 + volatile uint32_t reserved1[4];
43864 +} t_CapwapReasmPram;
43865 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43866 +
43867 +typedef _Packed struct t_ReassTbl {
43868 + volatile uint16_t waysNumAndSetSize;
43869 + volatile uint16_t autoLearnHashKeyMask;
43870 + volatile uint32_t reassCommonPrmTblPtr;
43871 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
43872 + volatile uint32_t autoLearnHashTblPtrLow;
43873 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
43874 + volatile uint32_t autoLearnSetLockTblPtrLow;
43875 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
43876 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
43877 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
43878 + volatile uint32_t totalValidFragmentCounter;
43879 + volatile uint32_t totalProcessedFragCounter;
43880 + volatile uint32_t totalMalformdFragCounter;
43881 + volatile uint32_t totalSetBusyCounter;
43882 + volatile uint32_t totalDiscardedFragsCounter;
43883 + volatile uint32_t totalMoreThan16FramesCounter;
43884 + volatile uint32_t reserved2[2];
43885 +} _PackedType t_ReassTbl;
43886 +
43887 +typedef struct t_ReassCommonTbl {
43888 + volatile uint32_t timeoutModeAndFqid;
43889 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
43890 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
43891 + volatile uint32_t reassFrmDescPoolPtrLow;
43892 + volatile uint32_t timeOutTblPtr;
43893 + volatile uint32_t expirationDelay;
43894 + volatile uint32_t internalBufferManagement;
43895 + volatile uint32_t reserved2;
43896 + volatile uint32_t totalTimeOutCounter;
43897 + volatile uint32_t totalRfdPoolBusyCounter;
43898 + volatile uint32_t totalInternalBufferBusy;
43899 + volatile uint32_t totalExternalBufferBusy;
43900 + volatile uint32_t totalSgFragmentCounter;
43901 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
43902 + volatile uint32_t totalNCSPCounter;
43903 + volatile uint32_t discardMask;
43904 +} t_ReassCommonTbl;
43905 +
43906 +typedef _Packed struct t_Hmtd {
43907 + volatile uint16_t cfg;
43908 + volatile uint8_t eliodnOffset;
43909 + volatile uint8_t extHmcdBasePtrHi;
43910 + volatile uint32_t hmcdBasePtr;
43911 + volatile uint16_t nextAdIdx;
43912 + volatile uint8_t res1;
43913 + volatile uint8_t opCode;
43914 + volatile uint32_t res2;
43915 +} _PackedType t_Hmtd;
43916 +
43917 +#if defined(__MWERKS__) && !defined(__GNUC__)
43918 +#pragma pack(pop)
43919 +#endif /* defined(__MWERKS__) && ... */
43920 +
43921 +
43922 +/***********************************************************************/
43923 +/* Driver's internal structures */
43924 +/***********************************************************************/
43925 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
43926 +typedef struct
43927 +{
43928 + t_Handle p_AutoLearnHashTbl;
43929 + t_Handle p_ReassmFrmDescrPoolTbl;
43930 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
43931 + t_Handle p_TimeOutTbl;
43932 + uint16_t maxNumFramesInProcess;
43933 + uint8_t numOfTasks;
43934 + //uint8_t poolId;
43935 + uint8_t prOffset;
43936 + uint16_t dataOffset;
43937 + uint8_t sgBpid;
43938 + uint8_t hwPortId;
43939 + uint32_t fqidForTimeOutFrames;
43940 + uint32_t timeoutRoutineRequestTime;
43941 + uint32_t bitFor1Micro;
43942 +} t_CapwapFragParams;
43943 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43944 +
43945 +typedef struct
43946 +{
43947 + t_AdOfTypeContLookup *p_Frag;
43948 +#if (DPAA_VERSION == 10)
43949 + uint8_t scratchBpid;
43950 +#endif /* (DPAA_VERSION == 10) */
43951 +} t_FragParams;
43952 +
43953 +typedef struct t_ReassmParams
43954 +{
43955 + e_NetHeaderType hdr; /* Header selection */
43956 + t_ReassCommonTbl *p_ReassCommonTbl;
43957 + uintptr_t reassFrmDescrIndxPoolTblAddr;
43958 + uintptr_t reassFrmDescrPoolTblAddr;
43959 + uintptr_t timeOutTblAddr;
43960 + uintptr_t internalBufferPoolManagementIndexAddr;
43961 + uintptr_t internalBufferPoolAddr;
43962 + uint32_t maxNumFramesInProcess;
43963 + uint8_t sgBpid;
43964 + uint8_t dataMemId;
43965 + uint16_t dataLiodnOffset;
43966 + uint32_t fqidForTimeOutFrames;
43967 + e_FmPcdManipReassemTimeOutMode timeOutMode;
43968 + uint32_t timeoutThresholdForReassmProcess;
43969 + union {
43970 + struct {
43971 + t_Handle h_Ipv4Ad;
43972 + t_Handle h_Ipv6Ad;
43973 + bool ipv6Assigned;
43974 + t_ReassTbl *p_Ipv4ReassTbl;
43975 + t_ReassTbl *p_Ipv6ReassTbl;
43976 + uintptr_t ipv4AutoLearnHashTblAddr;
43977 + uintptr_t ipv6AutoLearnHashTblAddr;
43978 + uintptr_t ipv4AutoLearnSetLockTblAddr;
43979 + uintptr_t ipv6AutoLearnSetLockTblAddr;
43980 + uint16_t minFragSize[2];
43981 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
43982 + uint8_t relativeSchemeId[2];
43983 + t_Handle h_Ipv4Scheme;
43984 + t_Handle h_Ipv6Scheme;
43985 + uint32_t nonConsistentSpFqid;
43986 + } ip;
43987 + struct {
43988 + t_Handle h_Ad;
43989 + t_ReassTbl *p_ReassTbl;
43990 + uintptr_t autoLearnHashTblAddr;
43991 + uintptr_t autoLearnSetLockTblAddr;
43992 + uint16_t maxRessembledsSize;
43993 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
43994 + uint8_t relativeSchemeId;
43995 + t_Handle h_Scheme;
43996 + } capwap;
43997 + };
43998 +} t_ReassmParams;
43999 +
44000 +typedef struct{
44001 + e_FmPcdManipType type;
44002 + t_FmPcdManipParams manipParams;
44003 + bool muramAllocate;
44004 + t_Handle h_Ad;
44005 + uint32_t opcode;
44006 + bool rmv;
44007 + bool insrt;
44008 + t_Handle h_NextManip;
44009 + t_Handle h_PrevManip;
44010 + e_FmPcdManipType nextManipType;
44011 + /* HdrManip parameters*/
44012 + uint8_t *p_Hmct;
44013 + uint8_t *p_Data;
44014 + bool dontParseAfterManip;
44015 + bool fieldUpdate;
44016 + bool custom;
44017 + uint16_t tableSize;
44018 + uint8_t dataSize;
44019 + bool cascaded;
44020 + e_ManipUnifiedPosition unifiedPosition;
44021 + /* end HdrManip */
44022 + uint8_t *p_Template;
44023 + uint16_t owner;
44024 + uint32_t updateParams;
44025 + uint32_t shadowUpdateParams;
44026 + bool frag;
44027 + bool reassm;
44028 + uint16_t sizeForFragmentation;
44029 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44030 + t_Handle h_Frag;
44031 + t_CapwapFragParams capwapFragParams;
44032 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44033 + union {
44034 + t_ReassmParams reassmParams;
44035 + t_FragParams fragParams;
44036 + };
44037 + uint8_t icOffset;
44038 + uint16_t ownerTmp;
44039 + bool cnia;
44040 + t_Handle p_StatsTbl;
44041 + t_Handle h_FmPcd;
44042 + t_List nodesLst;
44043 + t_Handle h_Spinlock;
44044 +} t_FmPcdManip;
44045 +
44046 +typedef struct t_FmPcdCcSavedManipParams
44047 +{
44048 + union
44049 + {
44050 + struct
44051 + {
44052 + uint16_t dataOffset;
44053 + //uint8_t poolId;
44054 + }capwapParams;
44055 + struct
44056 + {
44057 + uint16_t dataOffset;
44058 + uint8_t poolId;
44059 + }ipParams;
44060 + };
44061 +
44062 +} t_FmPcdCcSavedManipParams;
44063 +
44064 +
44065 +#endif /* __FM_MANIP_H */
44066 --- /dev/null
44067 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
44068 @@ -0,0 +1,2095 @@
44069 +/*
44070 + * Copyright 2008-2012 Freescale Semiconductor Inc.
44071 + *
44072 + * Redistribution and use in source and binary forms, with or without
44073 + * modification, are permitted provided that the following conditions are met:
44074 + * * Redistributions of source code must retain the above copyright
44075 + * notice, this list of conditions and the following disclaimer.
44076 + * * Redistributions in binary form must reproduce the above copyright
44077 + * notice, this list of conditions and the following disclaimer in the
44078 + * documentation and/or other materials provided with the distribution.
44079 + * * Neither the name of Freescale Semiconductor nor the
44080 + * names of its contributors may be used to endorse or promote products
44081 + * derived from this software without specific prior written permission.
44082 + *
44083 + *
44084 + * ALTERNATIVELY, this software may be distributed under the terms of the
44085 + * GNU General Public License ("GPL") as published by the Free Software
44086 + * Foundation, either version 2 of that License or (at your option) any
44087 + * later version.
44088 + *
44089 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
44090 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44091 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44092 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
44093 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
44094 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44095 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44096 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44097 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
44098 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44099 + */
44100 +
44101 +
44102 +/******************************************************************************
44103 + @File fm_pcd.c
44104 +
44105 + @Description FM PCD ...
44106 +*//***************************************************************************/
44107 +#include "std_ext.h"
44108 +#include "error_ext.h"
44109 +#include "string_ext.h"
44110 +#include "xx_ext.h"
44111 +#include "sprint_ext.h"
44112 +#include "debug_ext.h"
44113 +#include "net_ext.h"
44114 +#include "fm_ext.h"
44115 +#include "fm_pcd_ext.h"
44116 +
44117 +#include "fm_common.h"
44118 +#include "fm_pcd.h"
44119 +#include "fm_pcd_ipc.h"
44120 +#include "fm_hc.h"
44121 +#include "fm_muram_ext.h"
44122 +
44123 +
44124 +/****************************************/
44125 +/* static functions */
44126 +/****************************************/
44127 +
44128 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
44129 +{
44130 + if (!p_FmPcd->h_Fm)
44131 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
44132 +
44133 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
44134 + {
44135 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
44136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
44137 +
44138 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
44139 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
44140 +
44141 + if (!p_FmPcd->f_Exception)
44142 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
44143 +
44144 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
44145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
44146 +
44147 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
44148 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
44149 + }
44150 +
44151 + return E_OK;
44152 +}
44153 +
44154 +static volatile bool blockingFlag = FALSE;
44155 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
44156 + uint8_t *p_Msg,
44157 + uint8_t *p_Reply,
44158 + uint32_t replyLength,
44159 + t_Error status)
44160 +{
44161 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
44162 + blockingFlag = FALSE;
44163 +}
44164 +
44165 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
44166 + uint8_t *p_Msg,
44167 + uint32_t msgLength,
44168 + uint8_t *p_Reply,
44169 + uint32_t *p_ReplyLength)
44170 +{
44171 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44172 + t_Error err = E_OK;
44173 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
44174 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
44175 +
44176 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44177 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
44178 +
44179 +#ifdef DISABLE_SANITY_CHECKS
44180 + UNUSED(msgLength);
44181 +#endif /* DISABLE_SANITY_CHECKS */
44182 +
44183 + ASSERT_COND(p_Msg);
44184 +
44185 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
44186 + *p_ReplyLength = 0;
44187 +
44188 + switch (p_IpcMsg->msgId)
44189 + {
44190 + case (FM_PCD_MASTER_IS_ALIVE):
44191 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
44192 + p_IpcReply->error = E_OK;
44193 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44194 + break;
44195 + case (FM_PCD_MASTER_IS_ENABLED):
44196 + /* count partitions registrations */
44197 + if (p_FmPcd->enabled)
44198 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
44199 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
44200 + p_IpcReply->error = E_OK;
44201 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44202 + break;
44203 + case (FM_PCD_GUEST_DISABLE):
44204 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
44205 + {
44206 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
44207 + p_IpcReply->error = E_OK;
44208 + }
44209 + else
44210 + {
44211 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
44212 + p_IpcReply->error = E_INVALID_STATE;
44213 + }
44214 + *p_ReplyLength = sizeof(uint32_t);
44215 + break;
44216 + case (FM_PCD_GET_COUNTER):
44217 + {
44218 + e_FmPcdCounters inCounter;
44219 + uint32_t outCounter;
44220 +
44221 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
44222 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
44223 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
44224 + p_IpcReply->error = E_OK;
44225 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44226 + break;
44227 + }
44228 + case (FM_PCD_ALLOC_KG_SCHEMES):
44229 + {
44230 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44231 +
44232 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44233 + err = FmPcdKgAllocSchemes(h_FmPcd,
44234 + ipcSchemesParams.numOfSchemes,
44235 + ipcSchemesParams.guestId,
44236 + p_IpcReply->replyBody);
44237 + p_IpcReply->error = err;
44238 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
44239 + break;
44240 + }
44241 + case (FM_PCD_FREE_KG_SCHEMES):
44242 + {
44243 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
44244 +
44245 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
44246 + err = FmPcdKgFreeSchemes(h_FmPcd,
44247 + ipcSchemesParams.numOfSchemes,
44248 + ipcSchemesParams.guestId,
44249 + ipcSchemesParams.schemesIds);
44250 + p_IpcReply->error = err;
44251 + *p_ReplyLength = sizeof(uint32_t);
44252 + break;
44253 + }
44254 + case (FM_PCD_ALLOC_KG_CLSPLAN):
44255 + {
44256 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44257 +
44258 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44259 + err = KgAllocClsPlanEntries(h_FmPcd,
44260 + ipcKgClsPlanParams.numOfClsPlanEntries,
44261 + ipcKgClsPlanParams.guestId,
44262 + p_IpcReply->replyBody);
44263 + p_IpcReply->error = err;
44264 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
44265 + break;
44266 + }
44267 + case (FM_PCD_FREE_KG_CLSPLAN):
44268 + {
44269 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
44270 +
44271 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
44272 + KgFreeClsPlanEntries(h_FmPcd,
44273 + ipcKgClsPlanParams.numOfClsPlanEntries,
44274 + ipcKgClsPlanParams.guestId,
44275 + ipcKgClsPlanParams.clsPlanBase);
44276 + *p_ReplyLength = sizeof(uint32_t);
44277 + break;
44278 + }
44279 + case (FM_PCD_ALLOC_PROFILES):
44280 + {
44281 + t_FmIpcResourceAllocParams ipcAllocParams;
44282 + uint16_t base;
44283 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44284 + base = PlcrAllocProfilesForPartition(h_FmPcd,
44285 + ipcAllocParams.base,
44286 + ipcAllocParams.num,
44287 + ipcAllocParams.guestId);
44288 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
44289 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
44290 + break;
44291 + }
44292 + case (FM_PCD_FREE_PROFILES):
44293 + {
44294 + t_FmIpcResourceAllocParams ipcAllocParams;
44295 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44296 + PlcrFreeProfilesForPartition(h_FmPcd,
44297 + ipcAllocParams.base,
44298 + ipcAllocParams.num,
44299 + ipcAllocParams.guestId);
44300 + break;
44301 + }
44302 + case (FM_PCD_SET_PORT_PROFILES):
44303 + {
44304 + t_FmIpcResourceAllocParams ipcAllocParams;
44305 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44306 + PlcrSetPortProfiles(h_FmPcd,
44307 + ipcAllocParams.guestId,
44308 + ipcAllocParams.num,
44309 + ipcAllocParams.base);
44310 + break;
44311 + }
44312 + case (FM_PCD_CLEAR_PORT_PROFILES):
44313 + {
44314 + t_FmIpcResourceAllocParams ipcAllocParams;
44315 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
44316 + PlcrClearPortProfiles(h_FmPcd,
44317 + ipcAllocParams.guestId);
44318 + break;
44319 + }
44320 + case (FM_PCD_GET_SW_PRS_OFFSET):
44321 + {
44322 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
44323 + uint32_t swPrsOffset;
44324 +
44325 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
44326 + swPrsOffset =
44327 + FmPcdGetSwPrsOffset(h_FmPcd,
44328 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
44329 + ipcSwPrsLable.indexPerHdr);
44330 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
44331 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
44332 + break;
44333 + }
44334 + case (FM_PCD_PRS_INC_PORT_STATS):
44335 + {
44336 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
44337 +
44338 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
44339 + PrsIncludePortInStatistics(h_FmPcd,
44340 + ipcPrsIncludePort.hardwarePortId,
44341 + ipcPrsIncludePort.include);
44342 + break;
44343 + }
44344 + default:
44345 + *p_ReplyLength = 0;
44346 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
44347 + }
44348 + return E_OK;
44349 +}
44350 +
44351 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
44352 +{
44353 + ASSERT_COND(h_NetEnv);
44354 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
44355 +}
44356 +
44357 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
44358 +{
44359 + ASSERT_COND(h_NetEnv);
44360 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
44361 +}
44362 +
44363 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44364 +{
44365 + uint32_t intFlags;
44366 +
44367 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44368 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
44369 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44370 +}
44371 +
44372 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
44373 +{
44374 + t_FmPcdLock *p_Lock = NULL;
44375 + uint32_t intFlags;
44376 +
44377 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44378 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
44379 + {
44380 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
44381 + LIST_DelAndInit(&p_Lock->node);
44382 + }
44383 + if (p_FmPcd->h_Spinlock)
44384 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44385 +
44386 + return p_Lock;
44387 +}
44388 +
44389 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
44390 +{
44391 + uint32_t intFlags;
44392 +
44393 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
44394 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
44395 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
44396 +}
44397 +
44398 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
44399 +{
44400 + t_FmPcdLock *p_Lock;
44401 + int i;
44402 +
44403 + for (i=0; i<10; i++)
44404 + {
44405 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
44406 + if (!p_Lock)
44407 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
44408 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
44409 + INIT_LIST(&p_Lock->node);
44410 + p_Lock->h_Spinlock = XX_InitSpinlock();
44411 + if (!p_Lock->h_Spinlock)
44412 + {
44413 + XX_Free(p_Lock);
44414 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
44415 + }
44416 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
44417 + }
44418 +
44419 + return E_OK;
44420 +}
44421 +
44422 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
44423 +{
44424 + t_FmPcdLock *p_Lock;
44425 +
44426 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44427 + while (p_Lock)
44428 + {
44429 + XX_FreeSpinlock(p_Lock->h_Spinlock);
44430 + XX_Free(p_Lock);
44431 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
44432 + }
44433 +}
44434 +
44435 +
44436 +
44437 +/*****************************************************************************/
44438 +/* Inter-module API routines */
44439 +/*****************************************************************************/
44440 +
44441 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
44442 +{
44443 + ASSERT_COND(p_FmPcd);
44444 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
44445 +}
44446 +
44447 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
44448 +{
44449 + uint8_t netEnvId = p_GrpParams->netEnvId;
44450 + int i, k, j;
44451 +
44452 + ASSERT_COND(p_FmPcd);
44453 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
44454 + {
44455 + p_GrpParams->grpExists = TRUE;
44456 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
44457 + return E_OK;
44458 + }
44459 +
44460 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44461 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44462 + {
44463 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44464 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44465 + {
44466 + /* if an option exists, add it to the opts list */
44467 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44468 + {
44469 + /* check if this option already exists, add if it doesn't */
44470 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
44471 + {
44472 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44473 + break;
44474 + }
44475 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
44476 + if (j == p_GrpParams->numOfOptions)
44477 + {
44478 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
44479 + p_GrpParams->numOfOptions++;
44480 + }
44481 + }
44482 + }
44483 + }
44484 +
44485 + if (p_GrpParams->numOfOptions == 0)
44486 + {
44487 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
44488 + {
44489 + p_GrpParams->grpExists = TRUE;
44490 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
44491 + }
44492 + }
44493 +
44494 + return E_OK;
44495 +
44496 +}
44497 +
44498 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
44499 +{
44500 + uint8_t j,k;
44501 +
44502 + *p_Vector = 0;
44503 +
44504 + ASSERT_COND(p_FmPcd);
44505 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44506 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
44507 + {
44508 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44509 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44510 + {
44511 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
44512 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
44513 + }
44514 + }
44515 +
44516 + if (!*p_Vector)
44517 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
44518 + else
44519 + return E_OK;
44520 +}
44521 +
44522 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
44523 +{
44524 + int i;
44525 +
44526 + ASSERT_COND(p_FmPcd);
44527 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
44528 +
44529 + p_Params->vector = 0;
44530 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
44531 + {
44532 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
44533 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
44534 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
44535 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
44536 + }
44537 +
44538 + return E_OK;
44539 +}
44540 +
44541 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
44542 +{
44543 + int i=0, k;
44544 +
44545 + ASSERT_COND(p_FmPcd);
44546 + /* check whether a given unit may be used by non-clsPlan users. */
44547 + /* first, recognize the unit by its vector */
44548 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
44549 + {
44550 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
44551 + {
44552 + for (k=0;
44553 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44554 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
44555 + k++)
44556 + /* check that no option exists */
44557 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
44558 + return FALSE;
44559 + break;
44560 + }
44561 + i++;
44562 + }
44563 + /* assert that a unit was found to mach the vector */
44564 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
44565 +
44566 + return TRUE;
44567 +}
44568 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44569 +{
44570 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44571 + int i, k;
44572 +
44573 + ASSERT_COND(p_FmPcd);
44574 +
44575 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44576 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
44577 + {
44578 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44579 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
44580 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
44581 + return TRUE;
44582 + }
44583 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44584 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
44585 + {
44586 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44587 + return TRUE;
44588 + }
44589 +
44590 + return FALSE;
44591 +}
44592 +
44593 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
44594 +{
44595 + uint8_t i, k;
44596 +
44597 + ASSERT_COND(p_FmPcd);
44598 +
44599 + if (interchangeable)
44600 + {
44601 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44602 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44603 + {
44604 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
44605 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
44606 + {
44607 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
44608 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
44609 +
44610 + return i;
44611 + }
44612 + }
44613 + }
44614 + else
44615 + {
44616 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
44617 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
44618 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
44619 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
44620 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
44621 + return i;
44622 +
44623 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
44624 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44625 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
44626 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
44627 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44628 + }
44629 +
44630 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
44631 +}
44632 +
44633 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
44634 +{
44635 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44636 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
44637 + uint8_t result;
44638 + t_Error err = E_OK;
44639 +
44640 + ASSERT_COND(p_FmPcd);
44641 + ASSERT_COND(h_ReasmCommonPramTbl);
44642 +
44643 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
44644 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
44645 +
44646 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
44647 + RETURN_ERROR(MAJOR, err, NO_MSG);
44648 +
44649 + switch (result)
44650 + {
44651 + case (0):
44652 + return E_OK;
44653 + case (1):
44654 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44655 + case (2):
44656 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
44657 + case (3):
44658 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
44659 + default:
44660 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
44661 + }
44662 +
44663 + return E_OK;
44664 +}
44665 +
44666 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
44667 +{
44668 + int i;
44669 +
44670 + ASSERT_COND(p_FmPcd);
44671 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
44672 +
44673 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
44674 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
44675 + {
44676 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
44677 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
44678 + }
44679 +
44680 + return HEADER_TYPE_NONE;
44681 +}
44682 +
44683 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
44684 +{
44685 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44686 + uint16_t swPortIndex = 0;
44687 +
44688 + ASSERT_COND(h_FmPcd);
44689 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
44690 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
44691 +}
44692 +
44693 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
44694 +{
44695 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44696 +
44697 + ASSERT_COND(h_FmPcd);
44698 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
44699 +}
44700 +
44701 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
44702 +{
44703 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44704 +
44705 + ASSERT_COND(h_FmPcd);
44706 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
44707 +}
44708 +
44709 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
44710 +{
44711 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
44712 +}
44713 +
44714 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44715 +{
44716 + uint32_t intFlags;
44717 +
44718 + ASSERT_COND(h_FmPcd);
44719 +
44720 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44721 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
44722 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44723 +}
44724 +
44725 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
44726 +{
44727 + uint32_t intFlags;
44728 +
44729 + ASSERT_COND(h_FmPcd);
44730 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
44731 +
44732 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
44733 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
44734 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
44735 +}
44736 +
44737 +uint32_t FmPcdLock(t_Handle h_FmPcd)
44738 +{
44739 + ASSERT_COND(h_FmPcd);
44740 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
44741 +}
44742 +
44743 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
44744 +{
44745 + ASSERT_COND(h_FmPcd);
44746 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
44747 +}
44748 +
44749 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
44750 +{
44751 + t_FmPcdLock *p_Lock;
44752 + ASSERT_COND(h_FmPcd);
44753 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44754 + if (!p_Lock)
44755 + {
44756 + FillFreeLocksLst(h_FmPcd);
44757 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
44758 + }
44759 +
44760 + if (p_Lock)
44761 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
44762 + return p_Lock;
44763 +}
44764 +
44765 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
44766 +{
44767 + uint32_t intFlags;
44768 + ASSERT_COND(h_FmPcd);
44769 + intFlags = FmPcdLock(h_FmPcd);
44770 + LIST_DelAndInit(&p_Lock->node);
44771 + FmPcdUnlock(h_FmPcd, intFlags);
44772 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
44773 +}
44774 +
44775 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
44776 +{
44777 + uint32_t intFlags;
44778 + t_List *p_Pos, *p_SavedPos=NULL;
44779 +
44780 + ASSERT_COND(h_FmPcd);
44781 + intFlags = FmPcdLock(h_FmPcd);
44782 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44783 + {
44784 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44785 + if (!FmPcdLockTryLock(p_Lock))
44786 + {
44787 + p_SavedPos = p_Pos;
44788 + break;
44789 + }
44790 + }
44791 + if (p_SavedPos)
44792 + {
44793 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44794 + {
44795 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44796 + if (p_Pos == p_SavedPos)
44797 + break;
44798 + FmPcdLockUnlock(p_Lock);
44799 + }
44800 + }
44801 + FmPcdUnlock(h_FmPcd, intFlags);
44802 +
44803 + CORE_MemoryBarrier();
44804 +
44805 + if (p_SavedPos)
44806 + return FALSE;
44807 +
44808 + return TRUE;
44809 +}
44810 +
44811 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
44812 +{
44813 + uint32_t intFlags;
44814 + t_List *p_Pos;
44815 +
44816 + ASSERT_COND(h_FmPcd);
44817 + intFlags = FmPcdLock(h_FmPcd);
44818 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
44819 + {
44820 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
44821 + p_Lock->flag = FALSE;
44822 + }
44823 + FmPcdUnlock(h_FmPcd, intFlags);
44824 +
44825 + CORE_MemoryBarrier();
44826 +}
44827 +
44828 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
44829 +{
44830 + ASSERT_COND(h_FmPcd);
44831 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
44832 +
44833 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
44834 +}
44835 +
44836 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
44837 +{
44838 + ASSERT_COND(h_FmPcd);
44839 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
44840 +}
44841 +
44842 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
44843 +{
44844 + ASSERT_COND(h_FmPcd);
44845 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
44846 +}
44847 +/*********************** End of inter-module routines ************************/
44848 +
44849 +
44850 +/****************************************/
44851 +/* API Init unit functions */
44852 +/****************************************/
44853 +
44854 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
44855 +{
44856 + t_FmPcd *p_FmPcd = NULL;
44857 + t_FmPhysAddr physicalMuramBase;
44858 + uint8_t i;
44859 +
44860 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
44861 +
44862 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
44863 + if (!p_FmPcd)
44864 + {
44865 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
44866 + return NULL;
44867 + }
44868 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
44869 +
44870 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
44871 + if (!p_FmPcd->p_FmPcdDriverParam)
44872 + {
44873 + XX_Free(p_FmPcd);
44874 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
44875 + return NULL;
44876 + }
44877 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
44878 +
44879 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
44880 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
44881 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
44882 + if (p_FmPcd->h_FmMuram)
44883 + {
44884 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
44885 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
44886 + }
44887 +
44888 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
44889 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
44890 +
44891 + if (p_FmPcdParams->useHostCommand)
44892 + {
44893 + t_FmHcParams hcParams;
44894 +
44895 + memset(&hcParams, 0, sizeof(hcParams));
44896 + hcParams.h_Fm = p_FmPcd->h_Fm;
44897 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
44898 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
44899 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
44900 + if (!p_FmPcd->h_Hc)
44901 + {
44902 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
44903 + FM_PCD_Free(p_FmPcd);
44904 + return NULL;
44905 + }
44906 + }
44907 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
44908 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
44909 +
44910 + if (p_FmPcdParams->kgSupport)
44911 + {
44912 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
44913 + if (!p_FmPcd->p_FmPcdKg)
44914 + {
44915 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
44916 + FM_PCD_Free(p_FmPcd);
44917 + return NULL;
44918 + }
44919 + }
44920 +
44921 + if (p_FmPcdParams->plcrSupport)
44922 + {
44923 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
44924 + if (!p_FmPcd->p_FmPcdPlcr)
44925 + {
44926 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
44927 + FM_PCD_Free(p_FmPcd);
44928 + return NULL;
44929 + }
44930 + }
44931 +
44932 + if (p_FmPcdParams->prsSupport)
44933 + {
44934 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
44935 + if (!p_FmPcd->p_FmPcdPrs)
44936 + {
44937 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
44938 + FM_PCD_Free(p_FmPcd);
44939 + return NULL;
44940 + }
44941 + }
44942 +
44943 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
44944 + if (!p_FmPcd->h_Spinlock)
44945 + {
44946 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
44947 + FM_PCD_Free(p_FmPcd);
44948 + return NULL;
44949 + }
44950 + INIT_LIST(&p_FmPcd->freeLocksLst);
44951 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
44952 +
44953 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
44954 +
44955 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
44956 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
44957 + p_FmPcd->h_App = p_FmPcdParams->h_App;
44958 +
44959 + p_FmPcd->p_CcShadow = NULL;
44960 + p_FmPcd->ccShadowSize = 0;
44961 + p_FmPcd->ccShadowAlign = 0;
44962 +
44963 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
44964 + if (!p_FmPcd->h_ShadowSpinlock)
44965 + {
44966 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
44967 + FM_PCD_Free(p_FmPcd);
44968 + return NULL;
44969 + }
44970 +
44971 + return p_FmPcd;
44972 +}
44973 +
44974 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
44975 +{
44976 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
44977 + t_Error err = E_OK;
44978 + t_FmPcdIpcMsg msg;
44979 +
44980 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
44981 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
44982 +
44983 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
44984 +
44985 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
44986 + {
44987 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44988 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
44989 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44990 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
44991 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
44992 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
44993 +
44994 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
44995 + if (p_FmPcd->h_IpcSession)
44996 + {
44997 + t_FmPcdIpcReply reply;
44998 + uint32_t replyLength;
44999 + uint8_t isMasterAlive = 0;
45000 +
45001 + memset(&msg, 0, sizeof(msg));
45002 + memset(&reply, 0, sizeof(reply));
45003 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
45004 + msg.msgBody[0] = p_FmPcd->guestId;
45005 + blockingFlag = TRUE;
45006 +
45007 + do
45008 + {
45009 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
45010 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45011 + (uint8_t*)&msg,
45012 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
45013 + (uint8_t*)&reply,
45014 + &replyLength,
45015 + IpcMsgCompletionCB,
45016 + h_FmPcd)) != E_OK)
45017 + REPORT_ERROR(MAJOR, err, NO_MSG);
45018 + while (blockingFlag) ;
45019 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
45020 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45021 + isMasterAlive = *(uint8_t*)(reply.replyBody);
45022 + } while (!isMasterAlive);
45023 + }
45024 + }
45025 +
45026 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
45027 +
45028 + if (p_FmPcd->p_FmPcdKg)
45029 + {
45030 + err = KgInit(p_FmPcd);
45031 + if (err)
45032 + RETURN_ERROR(MAJOR, err, NO_MSG);
45033 + }
45034 +
45035 + if (p_FmPcd->p_FmPcdPlcr)
45036 + {
45037 + err = PlcrInit(p_FmPcd);
45038 + if (err)
45039 + RETURN_ERROR(MAJOR, err, NO_MSG);
45040 + }
45041 +
45042 + if (p_FmPcd->p_FmPcdPrs)
45043 + {
45044 + err = PrsInit(p_FmPcd);
45045 + if (err)
45046 + RETURN_ERROR(MAJOR, err, NO_MSG);
45047 + }
45048 +
45049 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45050 + {
45051 + /* register to inter-core messaging mechanism */
45052 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
45053 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
45054 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
45055 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
45056 + if (err)
45057 + RETURN_ERROR(MAJOR, err, NO_MSG);
45058 + }
45059 +
45060 + /* IPv6 Frame-Id used for fragmentation */
45061 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
45062 + if (!p_FmPcd->ipv6FrameIdAddr)
45063 + {
45064 + FM_PCD_Free(p_FmPcd);
45065 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
45066 + }
45067 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
45068 +
45069 + /* CAPWAP Frame-Id used for fragmentation */
45070 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
45071 + if (!p_FmPcd->capwapFrameIdAddr)
45072 + {
45073 + FM_PCD_Free(p_FmPcd);
45074 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
45075 + }
45076 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
45077 +
45078 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
45079 + p_FmPcd->p_FmPcdDriverParam = NULL;
45080 +
45081 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
45082 +
45083 + return E_OK;
45084 +}
45085 +
45086 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
45087 +{
45088 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
45089 + t_Error err = E_OK;
45090 +
45091 + if (p_FmPcd->ipv6FrameIdAddr)
45092 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
45093 +
45094 + if (p_FmPcd->capwapFrameIdAddr)
45095 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
45096 +
45097 + if (p_FmPcd->enabled)
45098 + FM_PCD_Disable(p_FmPcd);
45099 +
45100 + if (p_FmPcd->p_FmPcdDriverParam)
45101 + {
45102 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
45103 + p_FmPcd->p_FmPcdDriverParam = NULL;
45104 + }
45105 +
45106 + if (p_FmPcd->p_FmPcdKg)
45107 + {
45108 + if ((err = KgFree(p_FmPcd)) != E_OK)
45109 + RETURN_ERROR(MINOR, err, NO_MSG);
45110 + XX_Free(p_FmPcd->p_FmPcdKg);
45111 + p_FmPcd->p_FmPcdKg = NULL;
45112 + }
45113 +
45114 + if (p_FmPcd->p_FmPcdPlcr)
45115 + {
45116 + PlcrFree(p_FmPcd);
45117 + XX_Free(p_FmPcd->p_FmPcdPlcr);
45118 + p_FmPcd->p_FmPcdPlcr = NULL;
45119 + }
45120 +
45121 + if (p_FmPcd->p_FmPcdPrs)
45122 + {
45123 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45124 + PrsFree(p_FmPcd);
45125 + XX_Free(p_FmPcd->p_FmPcdPrs);
45126 + p_FmPcd->p_FmPcdPrs = NULL;
45127 + }
45128 +
45129 + if (p_FmPcd->h_Hc)
45130 + {
45131 + FmHcFree(p_FmPcd->h_Hc);
45132 + p_FmPcd->h_Hc = NULL;
45133 + }
45134 +
45135 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
45136 +
45137 + FmUnregisterPcd(p_FmPcd->h_Fm);
45138 +
45139 + ReleaseFreeLocksLst(p_FmPcd);
45140 +
45141 + if (p_FmPcd->h_Spinlock)
45142 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
45143 +
45144 + if (p_FmPcd->h_ShadowSpinlock)
45145 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
45146 +
45147 + XX_Free(p_FmPcd);
45148 +
45149 + return E_OK;
45150 +}
45151 +
45152 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45153 +{
45154 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45155 + uint32_t bitMask = 0;
45156 +
45157 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45158 +
45159 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45160 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
45161 +
45162 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45163 + if (bitMask)
45164 + {
45165 + if (enable)
45166 + p_FmPcd->exceptions |= bitMask;
45167 + else
45168 + p_FmPcd->exceptions &= ~bitMask;
45169 + }
45170 + else
45171 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
45172 +
45173 + return E_OK;
45174 +}
45175 +
45176 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
45177 +{
45178 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45179 +
45180 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45181 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
45182 +
45183 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
45184 +}
45185 +
45186 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
45187 +{
45188 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45189 + t_Error err = E_OK;
45190 +
45191 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45192 +
45193 + if (p_FmPcd->enabled)
45194 + return E_OK;
45195 +
45196 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45197 + p_FmPcd->h_IpcSession)
45198 + {
45199 + uint8_t enabled;
45200 + t_FmPcdIpcMsg msg;
45201 + t_FmPcdIpcReply reply;
45202 + uint32_t replyLength;
45203 +
45204 + memset(&reply, 0, sizeof(reply));
45205 + memset(&msg, 0, sizeof(msg));
45206 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
45207 + replyLength = sizeof(uint32_t) + sizeof(enabled);
45208 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45209 + (uint8_t*)&msg,
45210 + sizeof(msg.msgId),
45211 + (uint8_t*)&reply,
45212 + &replyLength,
45213 + NULL,
45214 + NULL)) != E_OK)
45215 + RETURN_ERROR(MAJOR, err, NO_MSG);
45216 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
45217 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45218 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
45219 + if (!p_FmPcd->enabled)
45220 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
45221 +
45222 + return E_OK;
45223 + }
45224 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45225 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45226 + ("running in guest-mode without IPC!"));
45227 +
45228 + if (p_FmPcd->p_FmPcdKg)
45229 + KgEnable(p_FmPcd);
45230 +
45231 + if (p_FmPcd->p_FmPcdPlcr)
45232 + PlcrEnable(p_FmPcd);
45233 +
45234 + if (p_FmPcd->p_FmPcdPrs)
45235 + PrsEnable(p_FmPcd);
45236 +
45237 + p_FmPcd->enabled = TRUE;
45238 +
45239 + return E_OK;
45240 +}
45241 +
45242 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
45243 +{
45244 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45245 + t_Error err = E_OK;
45246 +
45247 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45248 +
45249 + if (!p_FmPcd->enabled)
45250 + return E_OK;
45251 +
45252 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45253 + p_FmPcd->h_IpcSession)
45254 + {
45255 + t_FmPcdIpcMsg msg;
45256 + t_FmPcdIpcReply reply;
45257 + uint32_t replyLength;
45258 +
45259 + memset(&reply, 0, sizeof(reply));
45260 + memset(&msg, 0, sizeof(msg));
45261 + msg.msgId = FM_PCD_GUEST_DISABLE;
45262 + replyLength = sizeof(uint32_t);
45263 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45264 + (uint8_t*)&msg,
45265 + sizeof(msg.msgId),
45266 + (uint8_t*)&reply,
45267 + &replyLength,
45268 + NULL,
45269 + NULL)) != E_OK)
45270 + RETURN_ERROR(MAJOR, err, NO_MSG);
45271 + if (replyLength != sizeof(uint32_t))
45272 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45273 + if (reply.error == E_OK)
45274 + p_FmPcd->enabled = FALSE;
45275 +
45276 + return (t_Error)(reply.error);
45277 + }
45278 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
45279 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
45280 + ("running in guest-mode without IPC!"));
45281 +
45282 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
45283 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
45284 + ("Trying to disable a master partition PCD while"
45285 + "guest partitions are still enabled!"));
45286 +
45287 + if (p_FmPcd->p_FmPcdKg)
45288 + KgDisable(p_FmPcd);
45289 +
45290 + if (p_FmPcd->p_FmPcdPlcr)
45291 + PlcrDisable(p_FmPcd);
45292 +
45293 + if (p_FmPcd->p_FmPcdPrs)
45294 + PrsDisable(p_FmPcd);
45295 +
45296 + p_FmPcd->enabled = FALSE;
45297 +
45298 + return E_OK;
45299 +}
45300 +
45301 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
45302 +{
45303 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45304 + uint32_t intFlags, specialUnits = 0;
45305 + uint8_t bitId = 0;
45306 + uint8_t i, j, k;
45307 + uint8_t netEnvCurrId;
45308 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
45309 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
45310 + uint8_t hdrNum;
45311 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
45312 +
45313 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
45314 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
45315 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
45316 +
45317 + intFlags = FmPcdLock(p_FmPcd);
45318 +
45319 + /* find a new netEnv */
45320 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
45321 + if (!p_FmPcd->netEnvs[i].used)
45322 + break;
45323 +
45324 + if (i== FM_MAX_NUM_OF_PORTS)
45325 + {
45326 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
45327 + FmPcdUnlock(p_FmPcd, intFlags);
45328 + return NULL;
45329 + }
45330 +
45331 + p_FmPcd->netEnvs[i].used = TRUE;
45332 + FmPcdUnlock(p_FmPcd, intFlags);
45333 +
45334 + /* As anyone doesn't have handle of this netEnv yet, no need
45335 + to protect it with spinlocks */
45336 +
45337 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
45338 + if (!p_ModifiedNetEnvParams)
45339 + {
45340 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
45341 + return NULL;
45342 + }
45343 +
45344 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
45345 + p_NetEnvParams = p_ModifiedNetEnvParams;
45346 +
45347 + netEnvCurrId = (uint8_t)i;
45348 +
45349 + /* clear from previous use */
45350 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
45351 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
45352 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
45353 +
45354 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
45355 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
45356 +
45357 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45358 +
45359 + /* check that header with opt is not interchanged with the same header */
45360 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45361 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45362 + {
45363 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45364 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45365 + {
45366 + /* if an option exists, check that other headers are not the same header
45367 + without option */
45368 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
45369 + {
45370 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45371 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
45372 + {
45373 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
45374 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
45375 + {
45376 + REPORT_ERROR(MINOR, E_FULL,
45377 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
45378 + XX_Free(p_ModifiedNetEnvParams);
45379 + return NULL;
45380 + }
45381 + }
45382 + }
45383 + }
45384 + }
45385 +
45386 + /* Specific headers checking */
45387 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45388 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45389 + {
45390 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45391 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45392 + {
45393 + /* Some headers pairs may not be defined on different units as the parser
45394 + doesn't distinguish */
45395 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
45396 + /* check that header with opt is not interchanged with the same header */
45397 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
45398 + {
45399 + if (ipsecEspExists && (ipsecEspUnit != i))
45400 + {
45401 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45402 + XX_Free(p_ModifiedNetEnvParams);
45403 + return NULL;
45404 + }
45405 + else
45406 + {
45407 + ipsecAhUnit = i;
45408 + ipsecAhExists = TRUE;
45409 + }
45410 + }
45411 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
45412 + {
45413 + if (ipsecAhExists && (ipsecAhUnit != i))
45414 + {
45415 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
45416 + XX_Free(p_ModifiedNetEnvParams);
45417 + return NULL;
45418 + }
45419 + else
45420 + {
45421 + ipsecEspUnit = i;
45422 + ipsecEspExists = TRUE;
45423 + }
45424 + }
45425 + /* ENCAP_ESP */
45426 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
45427 + {
45428 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
45429 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
45430 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45431 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
45432 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45433 + }
45434 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
45435 + /* UDP_LITE */
45436 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
45437 + {
45438 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
45439 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
45440 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
45441 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45442 + }
45443 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
45444 +
45445 + /* IP FRAG */
45446 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
45447 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
45448 + {
45449 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
45450 + * IPv4 exists. If so we don't need to set an extra unit
45451 + * We consider as "having IPv4" any IPv4 without interchangable headers
45452 + * but including any options. */
45453 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
45454 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
45455 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45456 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45457 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45458 +
45459 + /* check if IPv4 header exists by itself */
45460 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45461 + {
45462 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
45463 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45464 + }
45465 + }
45466 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
45467 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
45468 + {
45469 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
45470 + * IPv4 exists. If so we don't need to set an extra unit
45471 + * We consider as "having IPv6" any IPv6 without interchangable headers
45472 + * but including any options. */
45473 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
45474 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
45475 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45476 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45477 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45478 +
45479 + /* check if IPv6 header exists by itself */
45480 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45481 + {
45482 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
45483 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
45484 + }
45485 + }
45486 +#if (DPAA_VERSION >= 11)
45487 + /* CAPWAP FRAG */
45488 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
45489 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
45490 + {
45491 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
45492 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
45493 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45494 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
45495 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
45496 + }
45497 +#endif /* (DPAA_VERSION >= 11) */
45498 + }
45499 + }
45500 +
45501 + /* if private header (shim), check that no other headers specified */
45502 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45503 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45504 + {
45505 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45506 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
45507 + {
45508 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
45509 + XX_Free(p_ModifiedNetEnvParams);
45510 + return NULL;
45511 + }
45512 + }
45513 +
45514 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
45515 + {
45516 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45517 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
45518 + {
45519 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
45520 + if (shim1Selected)
45521 + {
45522 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
45523 + XX_Free(p_ModifiedNetEnvParams);
45524 + return NULL;
45525 + }
45526 + shim1Selected = TRUE;
45527 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
45528 + break;
45529 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
45530 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
45531 + break;
45532 + default:
45533 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
45534 + }
45535 + else
45536 + {
45537 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
45538 +
45539 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45540 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45541 + }
45542 + }
45543 +
45544 + /* define a set of hardware parser LCV's according to the defined netenv */
45545 +
45546 + /* set an array of LCV's for each header in the netEnv */
45547 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
45548 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
45549 + {
45550 + /* private headers have no LCV in the hard parser */
45551 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
45552 + {
45553 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
45554 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
45555 + {
45556 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
45557 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
45558 + {
45559 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
45560 + XX_Free(p_ModifiedNetEnvParams);
45561 + return NULL;
45562 + }
45563 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
45564 + }
45565 + }
45566 + }
45567 + XX_Free(p_ModifiedNetEnvParams);
45568 +
45569 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
45570 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
45571 + {
45572 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
45573 + return NULL;
45574 + }
45575 + return &p_FmPcd->netEnvs[netEnvCurrId];
45576 +}
45577 +
45578 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
45579 +{
45580 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
45581 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
45582 + uint32_t intFlags;
45583 + uint8_t netEnvId = p_NetEnv->netEnvId;
45584 +
45585 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
45586 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45587 +
45588 + /* check that no port is bound to this netEnv */
45589 + if (p_FmPcd->netEnvs[netEnvId].owners)
45590 + {
45591 + RETURN_ERROR(MINOR, E_INVALID_STATE,
45592 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
45593 + }
45594 +
45595 + intFlags = FmPcdLock(p_FmPcd);
45596 +
45597 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
45598 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
45599 +
45600 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45601 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
45602 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
45603 +
45604 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
45605 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
45606 +
45607 + FmPcdUnlock(p_FmPcd, intFlags);
45608 + return E_OK;
45609 +}
45610 +
45611 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
45612 +{
45613 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45614 +
45615 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
45616 +
45617 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
45618 +}
45619 +
45620 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
45621 +{
45622 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45623 + t_FmCtrlCodeRevisionInfo revInfo;
45624 + t_Error err;
45625 +
45626 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45627 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45628 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
45629 +
45630 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
45631 + {
45632 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
45633 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
45634 + }
45635 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
45636 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
45637 +
45638 + if (!p_FmPcd->h_Hc)
45639 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
45640 +
45641 + p_FmPcd->advancedOffloadSupport = TRUE;
45642 +
45643 + return E_OK;
45644 +}
45645 +
45646 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
45647 +{
45648 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45649 + uint32_t outCounter = 0;
45650 + t_Error err;
45651 +
45652 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
45653 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
45654 +
45655 + switch (counter)
45656 + {
45657 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45658 + if (!p_FmPcd->p_FmPcdKg)
45659 + {
45660 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
45661 + return 0;
45662 + }
45663 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45664 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
45665 + !p_FmPcd->h_IpcSession)
45666 + {
45667 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45668 + ("running in guest-mode without neither IPC nor mapped register!"));
45669 + return 0;
45670 + }
45671 + break;
45672 +
45673 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45674 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45675 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45676 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45677 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45678 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45679 + if (!p_FmPcd->p_FmPcdPlcr)
45680 + {
45681 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
45682 + return 0;
45683 + }
45684 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45685 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45686 + !p_FmPcd->h_IpcSession)
45687 + {
45688 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45689 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
45690 + return 0;
45691 + }
45692 +
45693 + /* check that counters are enabled */
45694 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
45695 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
45696 + {
45697 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
45698 + return 0;
45699 + }
45700 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
45701 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
45702 + break;
45703 +
45704 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45705 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45706 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45707 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45708 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45709 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45710 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45711 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45712 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45713 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45714 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45715 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45716 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45717 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45718 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45719 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45720 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45721 + if (!p_FmPcd->p_FmPcdPrs)
45722 + {
45723 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
45724 + return 0;
45725 + }
45726 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45727 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
45728 + !p_FmPcd->h_IpcSession)
45729 + {
45730 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
45731 + ("running in guest-mode without neither IPC nor mapped register!"));
45732 + return 0;
45733 + }
45734 + break;
45735 + default:
45736 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
45737 + return 0;
45738 + }
45739 +
45740 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
45741 + p_FmPcd->h_IpcSession)
45742 + {
45743 + t_FmPcdIpcMsg msg;
45744 + t_FmPcdIpcReply reply;
45745 + uint32_t replyLength;
45746 +
45747 + memset(&msg, 0, sizeof(msg));
45748 + memset(&reply, 0, sizeof(reply));
45749 + msg.msgId = FM_PCD_GET_COUNTER;
45750 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
45751 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
45752 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
45753 + (uint8_t*)&msg,
45754 + sizeof(msg.msgId) +sizeof(uint32_t),
45755 + (uint8_t*)&reply,
45756 + &replyLength,
45757 + NULL,
45758 + NULL)) != E_OK)
45759 + RETURN_ERROR(MAJOR, err, NO_MSG);
45760 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
45761 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
45762 +
45763 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
45764 + return outCounter;
45765 + }
45766 +
45767 + switch (counter)
45768 + {
45769 + /* Parser statistics */
45770 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
45771 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
45772 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
45773 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
45774 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
45775 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
45776 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
45777 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
45778 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
45779 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
45780 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
45781 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
45782 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
45783 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
45784 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
45785 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
45786 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
45787 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
45788 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
45789 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
45790 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
45791 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
45792 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
45793 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
45794 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
45795 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
45796 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
45797 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
45798 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
45799 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
45800 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
45801 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
45802 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
45803 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
45804 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
45805 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
45806 +
45807 + /* Policer statistics */
45808 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
45809 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
45810 + case (e_FM_PCD_PLCR_COUNTERS_RED):
45811 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
45812 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
45813 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
45814 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
45815 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
45816 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
45817 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
45818 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
45819 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
45820 + }
45821 + return 0;
45822 +}
45823 +
45824 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
45825 +{
45826 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45827 + uint32_t bitMask = 0, tmpReg;
45828 +
45829 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45830 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45831 +
45832 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45833 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
45834 +
45835 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
45836 +
45837 + if (bitMask)
45838 + {
45839 + if (enable)
45840 + p_FmPcd->exceptions |= bitMask;
45841 + else
45842 + p_FmPcd->exceptions &= ~bitMask;
45843 +
45844 + switch (exception)
45845 + {
45846 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45847 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45848 + if (!p_FmPcd->p_FmPcdKg)
45849 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45850 + break;
45851 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45852 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45853 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45854 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45855 + if (!p_FmPcd->p_FmPcdPlcr)
45856 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45857 + break;
45858 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45859 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45860 + if (!p_FmPcd->p_FmPcdPrs)
45861 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
45862 + break;
45863 + }
45864 +
45865 + switch (exception)
45866 + {
45867 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45868 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45869 + if (enable)
45870 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
45871 + else
45872 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
45873 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45874 + break;
45875 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45876 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
45877 + if (enable)
45878 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
45879 + else
45880 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
45881 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
45882 + break;
45883 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45884 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
45885 + if (enable)
45886 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
45887 + else
45888 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
45889 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
45890 + break;
45891 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45892 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
45893 + if (enable)
45894 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
45895 + else
45896 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
45897 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
45898 + break;
45899 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45900 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45901 + if (enable)
45902 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
45903 + else
45904 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
45905 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45906 + break;
45907 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45908 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
45909 + if (enable)
45910 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
45911 + else
45912 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
45913 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
45914 + break;
45915 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45916 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45917 + if (enable)
45918 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45919 + else
45920 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
45921 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45922 + break;
45923 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45924 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
45925 + if (enable)
45926 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45927 + else
45928 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
45929 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
45930 + break;
45931 + }
45932 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
45933 + Driver may disable them automatically, depending on driver's status */
45934 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45935 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45936 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45937 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45938 + FmEnableRamsEcc(p_FmPcd->h_Fm);
45939 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
45940 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
45941 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
45942 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
45943 + FmDisableRamsEcc(p_FmPcd->h_Fm);
45944 + }
45945 +
45946 + return E_OK;
45947 +}
45948 +
45949 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
45950 +{
45951 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45952 +
45953 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
45954 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
45955 +
45956 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
45957 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
45958 +
45959 + switch (exception)
45960 + {
45961 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
45962 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
45963 + if (!p_FmPcd->p_FmPcdKg)
45964 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
45965 + break;
45966 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
45967 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
45968 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
45969 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
45970 + if (!p_FmPcd->p_FmPcdPlcr)
45971 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
45972 + break;
45973 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
45974 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
45975 + if (!p_FmPcd->p_FmPcdPrs)
45976 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
45977 + break;
45978 + default:
45979 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
45980 + }
45981 + switch (exception)
45982 + {
45983 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
45984 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
45985 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45986 + break;
45987 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
45988 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
45989 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45990 + break;
45991 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
45992 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
45993 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45994 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
45995 + break;
45996 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
45997 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
45998 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
45999 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
46000 + break;
46001 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
46002 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
46003 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
46004 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
46005 + break;
46006 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
46007 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
46008 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
46009 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
46010 + break;
46011 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
46012 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
46013 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
46014 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
46015 + break;
46016 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
46017 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
46018 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
46019 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
46020 + break;
46021 + }
46022 +
46023 + return E_OK;
46024 +}
46025 +
46026 +
46027 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
46028 +{
46029 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46030 +
46031 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46032 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
46033 +
46034 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46035 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
46036 +
46037 + switch (counter)
46038 + {
46039 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
46040 + if (!p_FmPcd->p_FmPcdKg)
46041 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
46042 + break;
46043 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
46044 + case (e_FM_PCD_PLCR_COUNTERS_RED):
46045 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
46046 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
46047 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
46048 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46049 + if (!p_FmPcd->p_FmPcdPlcr)
46050 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
46051 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
46052 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
46053 + break;
46054 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
46055 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
46056 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
46057 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
46058 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
46059 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
46060 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
46061 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
46062 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
46063 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
46064 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
46065 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
46066 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
46067 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
46068 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
46069 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
46070 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
46071 + if (!p_FmPcd->p_FmPcdPrs)
46072 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
46073 + break;
46074 + default:
46075 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
46076 + }
46077 + switch (counter)
46078 + {
46079 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
46080 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
46081 + break;
46082 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
46083 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
46084 + break;
46085 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
46086 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
46087 + break;
46088 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
46089 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
46090 + break;
46091 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
46092 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
46093 + break;
46094 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
46095 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
46096 + break;
46097 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
46098 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
46099 + break;
46100 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
46101 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
46102 + break;
46103 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
46104 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
46105 + break;
46106 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
46107 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
46108 + break;
46109 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
46110 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
46111 + break;
46112 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
46113 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
46114 + break;
46115 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
46116 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
46117 + break;
46118 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
46119 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
46120 + break;
46121 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
46122 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
46123 + break;
46124 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
46125 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
46126 + break;
46127 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
46128 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
46129 + break;
46130 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
46131 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
46132 + break;
46133 +
46134 + /*Policer counters*/
46135 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
46136 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
46137 + break;
46138 + case (e_FM_PCD_PLCR_COUNTERS_RED):
46139 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
46140 + break;
46141 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
46142 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
46143 + break;
46144 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
46145 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
46146 + break;
46147 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
46148 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
46149 + break;
46150 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
46151 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
46152 + break;
46153 + }
46154 +
46155 + return E_OK;
46156 +}
46157 +
46158 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
46159 +{
46160 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46161 + return FmHcGetPort(p_FmPcd->h_Hc);
46162 +}
46163 +
46164 --- /dev/null
46165 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
46166 @@ -0,0 +1,543 @@
46167 +/*
46168 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46169 + *
46170 + * Redistribution and use in source and binary forms, with or without
46171 + * modification, are permitted provided that the following conditions are met:
46172 + * * Redistributions of source code must retain the above copyright
46173 + * notice, this list of conditions and the following disclaimer.
46174 + * * Redistributions in binary form must reproduce the above copyright
46175 + * notice, this list of conditions and the following disclaimer in the
46176 + * documentation and/or other materials provided with the distribution.
46177 + * * Neither the name of Freescale Semiconductor nor the
46178 + * names of its contributors may be used to endorse or promote products
46179 + * derived from this software without specific prior written permission.
46180 + *
46181 + *
46182 + * ALTERNATIVELY, this software may be distributed under the terms of the
46183 + * GNU General Public License ("GPL") as published by the Free Software
46184 + * Foundation, either version 2 of that License or (at your option) any
46185 + * later version.
46186 + *
46187 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46188 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46189 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46190 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46191 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46192 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46193 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46194 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46195 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46196 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46197 + */
46198 +
46199 +
46200 +/******************************************************************************
46201 + @File fm_pcd.h
46202 +
46203 + @Description FM PCD ...
46204 +*//***************************************************************************/
46205 +#ifndef __FM_PCD_H
46206 +#define __FM_PCD_H
46207 +
46208 +#include "std_ext.h"
46209 +#include "error_ext.h"
46210 +#include "list_ext.h"
46211 +#include "fm_pcd_ext.h"
46212 +#include "fm_common.h"
46213 +#include "fsl_fman_prs.h"
46214 +#include "fsl_fman_kg.h"
46215 +
46216 +#define __ERR_MODULE__ MODULE_FM_PCD
46217 +
46218 +
46219 +/****************************/
46220 +/* Defaults */
46221 +/****************************/
46222 +#define DEFAULT_plcrAutoRefresh FALSE
46223 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
46224 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
46225 +#define DEFAULT_fmPcdPlcrExceptions 0
46226 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
46227 +
46228 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
46229 +#define DEFAULT_numOfUsedProfilesPerWindow 16
46230 +#define DEFAULT_numOfSharedPlcrProfiles 4
46231 +
46232 +/****************************/
46233 +/* Network defines */
46234 +/****************************/
46235 +#define UDP_HEADER_SIZE 8
46236 +
46237 +#define ESP_SPI_OFFSET 0
46238 +#define ESP_SPI_SIZE 4
46239 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
46240 +#define ESP_SEQ_NUM_SIZE 4
46241 +
46242 +/****************************/
46243 +/* General defines */
46244 +/****************************/
46245 +#define ILLEGAL_CLS_PLAN 0xff
46246 +#define ILLEGAL_NETENV 0xff
46247 +
46248 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
46249 +
46250 +/****************************/
46251 +/* Error defines */
46252 +/****************************/
46253 +
46254 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
46255 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
46256 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
46257 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
46258 +
46259 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
46260 +switch (exception){ \
46261 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
46262 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
46263 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
46264 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
46265 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
46266 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
46267 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
46268 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
46269 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
46270 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
46271 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
46272 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
46273 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
46274 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
46275 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
46276 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
46277 + default: bitMask = 0;break;}
46278 +
46279 +/***********************************************************************/
46280 +/* Policer defines */
46281 +/***********************************************************************/
46282 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
46283 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
46284 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
46285 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
46286 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
46287 +
46288 +/***********************************************************************/
46289 +/* Memory map */
46290 +/***********************************************************************/
46291 +#if defined(__MWERKS__) && !defined(__GNUC__)
46292 +#pragma pack(push,1)
46293 +#endif /* defined(__MWERKS__) && ... */
46294 +
46295 +
46296 +typedef struct {
46297 +/* General Configuration and Status Registers */
46298 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
46299 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
46300 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
46301 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
46302 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
46303 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
46304 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
46305 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
46306 +/* Global Statistic Counters */
46307 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
46308 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
46309 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
46310 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
46311 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
46312 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
46313 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
46314 +/* Profile RAM Access Registers */
46315 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
46316 + t_FmPcdPlcrProfileRegs profileRegs;
46317 +/* Error Capture Registers */
46318 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
46319 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
46320 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
46321 +/* Debug Registers */
46322 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
46323 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
46324 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
46325 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
46326 + (for port-ID 1-11, only for supported Port-ID registers) */
46327 +} t_FmPcdPlcrRegs;
46328 +
46329 +#if defined(__MWERKS__) && !defined(__GNUC__)
46330 +#pragma pack(pop)
46331 +#endif /* defined(__MWERKS__) && ... */
46332 +
46333 +
46334 +/***********************************************************************/
46335 +/* Driver's internal structures */
46336 +/***********************************************************************/
46337 +
46338 +typedef struct {
46339 + bool known;
46340 + uint8_t id;
46341 +} t_FmPcdKgSchemesExtractsEntry;
46342 +
46343 +typedef struct {
46344 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
46345 +} t_FmPcdKgSchemesExtracts;
46346 +
46347 +typedef struct {
46348 + t_Handle h_Manip;
46349 + bool keepRes;
46350 + e_FmPcdEngine nextEngine;
46351 + uint8_t parseCode;
46352 +} t_FmPcdInfoForManip;
46353 +
46354 +/**************************************************************************//**
46355 + @Description A structure of parameters to communicate
46356 + between the port and PCD regarding the KG scheme.
46357 +*//***************************************************************************/
46358 +typedef struct {
46359 + uint8_t netEnvId; /* in */
46360 + uint8_t numOfDistinctionUnits; /* in */
46361 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
46362 + uint32_t vector; /* out */
46363 +} t_NetEnvParams;
46364 +
46365 +typedef struct {
46366 + bool allocated;
46367 + uint8_t ownerId; /* guestId for KG in multi-partition only.
46368 + portId for PLCR in any environment */
46369 +} t_FmPcdAllocMng;
46370 +
46371 +typedef struct {
46372 + volatile bool lock;
46373 + bool used;
46374 + uint8_t owners;
46375 + uint8_t netEnvId;
46376 + uint8_t guestId;
46377 + uint8_t baseEntry;
46378 + uint16_t sizeOfGrp;
46379 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
46380 +} t_FmPcdKgClsPlanGrp;
46381 +
46382 +typedef struct {
46383 + t_Handle h_FmPcd;
46384 + uint8_t schemeId;
46385 + t_FmPcdLock *p_Lock;
46386 + bool valid;
46387 + uint8_t netEnvId;
46388 + uint8_t owners;
46389 + uint32_t matchVector;
46390 + uint32_t ccUnits;
46391 + bool nextRelativePlcrProfile;
46392 + uint16_t relativeProfileId;
46393 + uint16_t numOfProfiles;
46394 + t_FmPcdKgKeyOrder orderedArray;
46395 + e_FmPcdEngine nextEngine;
46396 + e_FmPcdDoneAction doneAction;
46397 + bool requiredActionFlag;
46398 + uint32_t requiredAction;
46399 + bool extractedOrs;
46400 + uint8_t bitOffsetInPlcrProfile;
46401 + bool directPlcr;
46402 +#if (DPAA_VERSION >= 11)
46403 + bool vspe;
46404 +#endif
46405 +} t_FmPcdKgScheme;
46406 +
46407 +typedef union {
46408 + struct fman_kg_scheme_regs schemeRegs;
46409 + struct fman_kg_pe_regs portRegs;
46410 + struct fman_kg_cp_regs clsPlanRegs;
46411 +} u_FmPcdKgIndirectAccessRegs;
46412 +
46413 +typedef struct {
46414 + struct fman_kg_regs *p_FmPcdKgRegs;
46415 + uint32_t schemeExceptionsBitMask;
46416 + uint8_t numOfSchemes;
46417 + t_Handle h_HwSpinlock;
46418 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46419 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
46420 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
46421 + uint8_t emptyClsPlanGrpId;
46422 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
46423 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
46424 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
46425 +} t_FmPcdKg;
46426 +
46427 +typedef struct {
46428 + uint16_t profilesBase;
46429 + uint16_t numOfProfiles;
46430 + t_Handle h_FmPort;
46431 +} t_FmPcdPlcrMapParam;
46432 +
46433 +typedef struct {
46434 + uint16_t absoluteProfileId;
46435 + t_Handle h_FmPcd;
46436 + bool valid;
46437 + t_FmPcdLock *p_Lock;
46438 + t_FmPcdAllocMng profilesMng;
46439 + bool requiredActionFlag;
46440 + uint32_t requiredAction;
46441 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
46442 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
46443 +
46444 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
46445 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
46446 +
46447 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
46448 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
46449 +} t_FmPcdPlcrProfile;
46450 +
46451 +typedef struct {
46452 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
46453 + uint16_t partPlcrProfilesBase;
46454 + uint16_t partNumOfPlcrProfiles;
46455 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
46456 + uint16_t numOfSharedProfiles;
46457 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
46458 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
46459 + t_Handle h_HwSpinlock;
46460 + t_Handle h_SwSpinlock;
46461 +} t_FmPcdPlcr;
46462 +
46463 +typedef struct {
46464 + uint32_t *p_SwPrsCode;
46465 + uint32_t *p_CurrSwPrs;
46466 + uint8_t currLabel;
46467 + struct fman_prs_regs *p_FmPcdPrsRegs;
46468 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
46469 + uint32_t fmPcdPrsPortIdStatistics;
46470 +} t_FmPcdPrs;
46471 +
46472 +typedef struct {
46473 + struct {
46474 + e_NetHeaderType hdr;
46475 + protocolOpt_t opt; /* only one option !! */
46476 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
46477 +} t_FmPcdIntDistinctionUnit;
46478 +
46479 +typedef struct {
46480 + e_NetHeaderType hdr;
46481 + protocolOpt_t opt; /* only one option !! */
46482 + e_NetHeaderType aliasHdr;
46483 +} t_FmPcdNetEnvAliases;
46484 +
46485 +typedef struct {
46486 + uint8_t netEnvId;
46487 + t_Handle h_FmPcd;
46488 + t_Handle h_Spinlock;
46489 + bool used;
46490 + uint8_t owners;
46491 + uint8_t clsPlanGrpId;
46492 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46493 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
46494 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
46495 + uint32_t macsecVector;
46496 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
46497 +} t_FmPcdNetEnv;
46498 +
46499 +typedef struct {
46500 + struct fman_prs_cfg dfltCfg;
46501 + bool plcrAutoRefresh;
46502 + uint16_t prsMaxParseCycleLimit;
46503 +} t_FmPcdDriverParam;
46504 +
46505 +typedef struct {
46506 + t_Handle h_Fm;
46507 + t_Handle h_FmMuram;
46508 + t_FmRevisionInfo fmRevInfo;
46509 +
46510 + uint64_t physicalMuramBase;
46511 +
46512 + t_Handle h_Spinlock;
46513 + t_List freeLocksLst;
46514 + t_List acquiredLocksLst;
46515 +
46516 + t_Handle h_IpcSession; /* relevant for guest only */
46517 + bool enabled;
46518 + uint8_t guestId; /**< Guest Partition Id */
46519 + uint8_t numOfEnabledGuestPartitionsPcds;
46520 + char fmPcdModuleName[MODULE_NAME_SIZE];
46521 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
46522 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
46523 + t_FmPcdKg *p_FmPcdKg;
46524 + t_FmPcdPlcr *p_FmPcdPlcr;
46525 + t_FmPcdPrs *p_FmPcdPrs;
46526 +
46527 + void *p_CcShadow; /**< CC MURAM shadow */
46528 + uint32_t ccShadowSize;
46529 + uint32_t ccShadowAlign;
46530 + volatile bool shadowLock;
46531 + t_Handle h_ShadowSpinlock;
46532 +
46533 + t_Handle h_Hc;
46534 +
46535 + uint32_t exceptions;
46536 + t_FmPcdExceptionCallback *f_Exception;
46537 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
46538 + t_Handle h_App;
46539 + uintptr_t ipv6FrameIdAddr;
46540 + uintptr_t capwapFrameIdAddr;
46541 + bool advancedOffloadSupport;
46542 +
46543 + t_FmPcdDriverParam *p_FmPcdDriverParam;
46544 +} t_FmPcd;
46545 +
46546 +#if (DPAA_VERSION >= 11)
46547 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
46548 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
46549 +#define FRM_REPLIC_UPDATE_INFO 0x02
46550 +#endif /* (DPAA_VERSION >= 11) */
46551 +/***********************************************************************/
46552 +/* PCD internal routines */
46553 +/***********************************************************************/
46554 +
46555 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
46556 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
46557 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
46558 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
46559 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
46560 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46561 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
46562 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
46563 +
46564 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
46565 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
46566 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
46567 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
46568 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
46569 +
46570 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46571 +t_Error KgInit(t_FmPcd *p_FmPcd);
46572 +t_Error KgFree(t_FmPcd *p_FmPcd);
46573 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
46574 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
46575 +void KgEnable(t_FmPcd *p_FmPcd);
46576 +void KgDisable(t_FmPcd *p_FmPcd);
46577 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
46578 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
46579 +
46580 +/* only for MULTI partittion */
46581 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46582 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
46583 +/* only for SINGLE partittion */
46584 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
46585 +
46586 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
46587 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
46588 +
46589 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
46590 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
46591 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
46592 +void PlcrEnable(t_FmPcd *p_FmPcd);
46593 +void PlcrDisable(t_FmPcd *p_FmPcd);
46594 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46595 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
46596 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
46597 + uint8_t hardwarePortId,
46598 + uint16_t numOfProfiles,
46599 + uint16_t base);
46600 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
46601 +
46602 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
46603 +t_Error PrsInit(t_FmPcd *p_FmPcd);
46604 +void PrsEnable(t_FmPcd *p_FmPcd);
46605 +void PrsDisable(t_FmPcd *p_FmPcd);
46606 +void PrsFree(t_FmPcd *p_FmPcd );
46607 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
46608 +
46609 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
46610 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
46611 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
46612 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
46613 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
46614 +
46615 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46616 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
46617 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
46618 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
46619 + t_Handle p_Ad,
46620 + t_Handle *p_AdNewPtr);
46621 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
46622 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
46623 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
46624 +#ifdef FM_CAPWAP_SUPPORT
46625 +t_Handle FmPcdManipApplSpecificBuild(void);
46626 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
46627 +#endif /* FM_CAPWAP_SUPPORT */
46628 +#if (DPAA_VERSION >= 11)
46629 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
46630 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
46631 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
46632 +
46633 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
46634 + t_Handle h_ReplicGroup,
46635 + t_List *p_AdTables,
46636 + uint32_t *p_NumOfAdTables);
46637 +#endif /* (DPAA_VERSION >= 11) */
46638 +
46639 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
46640 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46641 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
46642 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
46643 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
46644 +
46645 +typedef struct
46646 +{
46647 + t_Handle h_StatsAd;
46648 + t_Handle h_StatsCounters;
46649 +#if (DPAA_VERSION >= 11)
46650 + t_Handle h_StatsFLRs;
46651 +#endif /* (DPAA_VERSION >= 11) */
46652 +} t_FmPcdCcStatsParams;
46653 +
46654 +void NextStepAd(t_Handle h_Ad,
46655 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
46656 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
46657 + t_FmPcd *p_FmPcd);
46658 +void ReleaseLst(t_List *p_List);
46659 +
46660 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
46661 +{
46662 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46663 + ASSERT_COND(p_FmPcd);
46664 + return p_FmPcd->h_FmMuram;
46665 +}
46666 +
46667 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
46668 +{
46669 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46670 + ASSERT_COND(p_FmPcd);
46671 + return p_FmPcd->physicalMuramBase;
46672 +}
46673 +
46674 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
46675 +{
46676 + ASSERT_COND(p_Lock);
46677 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46678 +}
46679 +
46680 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
46681 +{
46682 + ASSERT_COND(p_Lock);
46683 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
46684 +}
46685 +
46686 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
46687 +{
46688 + uint32_t intFlags;
46689 +
46690 + ASSERT_COND(p_Lock);
46691 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
46692 + if (p_Lock->flag)
46693 + {
46694 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46695 + return FALSE;
46696 + }
46697 + p_Lock->flag = TRUE;
46698 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
46699 + return TRUE;
46700 +}
46701 +
46702 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
46703 +{
46704 + ASSERT_COND(p_Lock);
46705 + p_Lock->flag = FALSE;
46706 +}
46707 +
46708 +
46709 +#endif /* __FM_PCD_H */
46710 --- /dev/null
46711 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
46712 @@ -0,0 +1,280 @@
46713 +/*
46714 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46715 + *
46716 + * Redistribution and use in source and binary forms, with or without
46717 + * modification, are permitted provided that the following conditions are met:
46718 + * * Redistributions of source code must retain the above copyright
46719 + * notice, this list of conditions and the following disclaimer.
46720 + * * Redistributions in binary form must reproduce the above copyright
46721 + * notice, this list of conditions and the following disclaimer in the
46722 + * documentation and/or other materials provided with the distribution.
46723 + * * Neither the name of Freescale Semiconductor nor the
46724 + * names of its contributors may be used to endorse or promote products
46725 + * derived from this software without specific prior written permission.
46726 + *
46727 + *
46728 + * ALTERNATIVELY, this software may be distributed under the terms of the
46729 + * GNU General Public License ("GPL") as published by the Free Software
46730 + * Foundation, either version 2 of that License or (at your option) any
46731 + * later version.
46732 + *
46733 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
46734 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46735 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46736 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
46737 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46738 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46739 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
46740 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46741 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46742 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46743 + */
46744 +
46745 +
46746 +/**************************************************************************//**
46747 + @File fm_pcd_ipc.h
46748 +
46749 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
46750 +*//***************************************************************************/
46751 +#ifndef __FM_PCD_IPC_H
46752 +#define __FM_PCD_IPC_H
46753 +
46754 +#include "std_ext.h"
46755 +
46756 +
46757 +/**************************************************************************//**
46758 + @Group FM_grp Frame Manager API
46759 +
46760 + @Description FM API functions, definitions and enums
46761 +
46762 + @{
46763 +*//***************************************************************************/
46764 +
46765 +
46766 +#if defined(__MWERKS__) && !defined(__GNUC__)
46767 +#pragma pack(push,1)
46768 +#endif /* defined(__MWERKS__) && ... */
46769 +
46770 +/**************************************************************************//**
46771 + @Description Structure for getting a sw parser address according to a label
46772 + Fields commented 'IN' are passed by the port module to be used
46773 + by the FM module.
46774 + Fields commented 'OUT' will be filled by FM before returning to port.
46775 +*//***************************************************************************/
46776 +typedef _Packed struct t_FmPcdIpcSwPrsLable
46777 +{
46778 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
46779 + the sw parser code. */
46780 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
46781 + attachments for the same header, use this
46782 +
46783 + index to distinguish between them. */
46784 +} _PackedType t_FmPcdIpcSwPrsLable;
46785 +
46786 +/**************************************************************************//**
46787 + @Description Structure for port-PCD communication.
46788 + Fields commented 'IN' are passed by the port module to be used
46789 + by the FM module.
46790 + Fields commented 'OUT' will be filled by FM before returning to port.
46791 + Some fields are optional (depending on configuration) and
46792 + will be analized by the port and FM modules accordingly.
46793 +*//***************************************************************************/
46794 +
46795 +typedef struct t_FmPcdIpcKgSchemesParams
46796 +{
46797 + uint8_t guestId;
46798 + uint8_t numOfSchemes;
46799 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
46800 +} _PackedType t_FmPcdIpcKgSchemesParams;
46801 +
46802 +typedef struct t_FmPcdIpcKgClsPlanParams
46803 +{
46804 + uint8_t guestId;
46805 + uint16_t numOfClsPlanEntries;
46806 + uint8_t clsPlanBase;
46807 +} _PackedType t_FmPcdIpcKgClsPlanParams;
46808 +
46809 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
46810 +{
46811 + uint8_t hardwarePortId;
46812 + bool include;
46813 +} _PackedType t_FmPcdIpcPrsIncludePort;
46814 +
46815 +
46816 +#define FM_PCD_MAX_REPLY_SIZE 16
46817 +#define FM_PCD_MAX_MSG_SIZE 36
46818 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
46819 +
46820 +typedef _Packed struct {
46821 + uint32_t msgId;
46822 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
46823 +} _PackedType t_FmPcdIpcMsg;
46824 +
46825 +typedef _Packed struct t_FmPcdIpcReply {
46826 + uint32_t error;
46827 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
46828 +} _PackedType t_FmPcdIpcReply;
46829 +
46830 +typedef _Packed struct t_FmIpcResourceAllocParams {
46831 + uint8_t guestId;
46832 + uint16_t base;
46833 + uint16_t num;
46834 +}_PackedType t_FmIpcResourceAllocParams;
46835 +
46836 +#if defined(__MWERKS__) && !defined(__GNUC__)
46837 +#pragma pack(pop)
46838 +#endif /* defined(__MWERKS__) && ... */
46839 +
46840 +
46841 +
46842 +/**************************************************************************//**
46843 + @Function FM_PCD_ALLOC_KG_SCHEMES
46844 +
46845 + @Description Used by FM PCD front-end in order to allocate KG resources
46846 +
46847 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
46848 +*//***************************************************************************/
46849 +#define FM_PCD_ALLOC_KG_SCHEMES 3
46850 +
46851 +/**************************************************************************//**
46852 + @Function FM_PCD_FREE_KG_SCHEMES
46853 +
46854 + @Description Used by FM PCD front-end in order to Free KG resources
46855 +
46856 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
46857 +*//***************************************************************************/
46858 +#define FM_PCD_FREE_KG_SCHEMES 4
46859 +
46860 +/**************************************************************************//**
46861 + @Function FM_PCD_ALLOC_PROFILES
46862 +
46863 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46864 +
46865 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46866 +*//***************************************************************************/
46867 +#define FM_PCD_ALLOC_PROFILES 5
46868 +
46869 +/**************************************************************************//**
46870 + @Function FM_PCD_FREE_PROFILES
46871 +
46872 + @Description Used by FM PCD front-end in order to Free Policer profiles
46873 +
46874 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46875 +*//***************************************************************************/
46876 +#define FM_PCD_FREE_PROFILES 6
46877 +
46878 +/**************************************************************************//**
46879 + @Function FM_PCD_SET_PORT_PROFILES
46880 +
46881 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46882 + for specific port
46883 +
46884 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46885 +*//***************************************************************************/
46886 +#define FM_PCD_SET_PORT_PROFILES 7
46887 +
46888 +/**************************************************************************//**
46889 + @Function FM_PCD_CLEAR_PORT_PROFILES
46890 +
46891 + @Description Used by FM PCD front-end in order to allocate Policer profiles
46892 + for specific port
46893 +
46894 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
46895 +*//***************************************************************************/
46896 +#define FM_PCD_CLEAR_PORT_PROFILES 8
46897 +
46898 +/**************************************************************************//**
46899 + @Function FM_PCD_GET_PHYS_MURAM_BASE
46900 +
46901 + @Description Used by FM PCD front-end in order to get MURAM base address
46902 +
46903 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
46904 +*//***************************************************************************/
46905 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
46906 +
46907 +/**************************************************************************//**
46908 + @Function FM_PCD_GET_SW_PRS_OFFSET
46909 +
46910 + @Description Used by FM front-end to get the SW parser offset of the start of
46911 + code relevant to a given label.
46912 +
46913 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
46914 +*//***************************************************************************/
46915 +#define FM_PCD_GET_SW_PRS_OFFSET 10
46916 +
46917 +/**************************************************************************//**
46918 + @Function FM_PCD_MASTER_IS_ENABLED
46919 +
46920 + @Description Used by FM front-end in order to verify
46921 + PCD enablement.
46922 +
46923 + @Param[in] bool Pointer
46924 +*//***************************************************************************/
46925 +#define FM_PCD_MASTER_IS_ENABLED 15
46926 +
46927 +/**************************************************************************//**
46928 + @Function FM_PCD_GUEST_DISABLE
46929 +
46930 + @Description Used by FM front-end to inform back-end when
46931 + front-end PCD is disabled
46932 +
46933 + @Param[in] None
46934 +*//***************************************************************************/
46935 +#define FM_PCD_GUEST_DISABLE 16
46936 +
46937 +/**************************************************************************//**
46938 + @Function FM_PCD_FREE_KG_CLSPLAN
46939 +
46940 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
46941 +
46942 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46943 +*//***************************************************************************/
46944 +#define FM_PCD_FREE_KG_CLSPLAN 22
46945 +
46946 +/**************************************************************************//**
46947 + @Function FM_PCD_ALLOC_KG_CLSPLAN
46948 +
46949 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
46950 +
46951 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
46952 +*//***************************************************************************/
46953 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
46954 +
46955 +/**************************************************************************//**
46956 + @Function FM_PCD_MASTER_IS_ALIVE
46957 +
46958 + @Description Used by FM front-end to check that back-end exists
46959 +
46960 + @Param[in] None
46961 +*//***************************************************************************/
46962 +#define FM_PCD_MASTER_IS_ALIVE 24
46963 +
46964 +/**************************************************************************//**
46965 + @Function FM_PCD_GET_COUNTER
46966 +
46967 + @Description Used by FM front-end to read PCD counters
46968 +
46969 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
46970 +*//***************************************************************************/
46971 +#define FM_PCD_GET_COUNTER 25
46972 +
46973 +/**************************************************************************//**
46974 + @Function FM_PCD_PRS_INC_PORT_STATS
46975 +
46976 + @Description Used by FM front-end to set/clear statistics for port
46977 +
46978 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
46979 +*//***************************************************************************/
46980 +#define FM_PCD_PRS_INC_PORT_STATS 26
46981 +
46982 +#if (DPAA_VERSION >= 11)
46983 +/* TODO - doc */
46984 +#define FM_PCD_ALLOC_SP 27
46985 +#endif /* (DPAA_VERSION >= 11) */
46986 +
46987 +
46988 +/** @} */ /* end of FM_PCD_IPC_grp group */
46989 +/** @} */ /* end of FM_grp group */
46990 +
46991 +
46992 +#endif /* __FM_PCD_IPC_H */
46993 --- /dev/null
46994 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
46995 @@ -0,0 +1,1847 @@
46996 +/*
46997 + * Copyright 2008-2012 Freescale Semiconductor Inc.
46998 + *
46999 + * Redistribution and use in source and binary forms, with or without
47000 + * modification, are permitted provided that the following conditions are met:
47001 + * * Redistributions of source code must retain the above copyright
47002 + * notice, this list of conditions and the following disclaimer.
47003 + * * Redistributions in binary form must reproduce the above copyright
47004 + * notice, this list of conditions and the following disclaimer in the
47005 + * documentation and/or other materials provided with the distribution.
47006 + * * Neither the name of Freescale Semiconductor nor the
47007 + * names of its contributors may be used to endorse or promote products
47008 + * derived from this software without specific prior written permission.
47009 + *
47010 + *
47011 + * ALTERNATIVELY, this software may be distributed under the terms of the
47012 + * GNU General Public License ("GPL") as published by the Free Software
47013 + * Foundation, either version 2 of that License or (at your option) any
47014 + * later version.
47015 + *
47016 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
47017 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47018 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47019 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
47020 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47021 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47022 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47023 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47024 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47025 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47026 + */
47027 +
47028 +
47029 +/******************************************************************************
47030 + @File fm_plcr.c
47031 +
47032 + @Description FM PCD POLICER...
47033 +*//***************************************************************************/
47034 +#include <linux/math64.h>
47035 +#include "std_ext.h"
47036 +#include "error_ext.h"
47037 +#include "string_ext.h"
47038 +#include "debug_ext.h"
47039 +#include "net_ext.h"
47040 +#include "fm_ext.h"
47041 +
47042 +#include "fm_common.h"
47043 +#include "fm_pcd.h"
47044 +#include "fm_hc.h"
47045 +#include "fm_pcd_ipc.h"
47046 +#include "fm_plcr.h"
47047 +
47048 +
47049 +/****************************************/
47050 +/* static functions */
47051 +/****************************************/
47052 +
47053 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
47054 +{
47055 + ASSERT_COND(h_Profile);
47056 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47057 +}
47058 +
47059 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
47060 +{
47061 + ASSERT_COND(h_Profile);
47062 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
47063 +}
47064 +
47065 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
47066 +{
47067 + ASSERT_COND(h_Profile);
47068 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47069 +}
47070 +
47071 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
47072 +{
47073 + ASSERT_COND(h_Profile);
47074 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
47075 +}
47076 +
47077 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
47078 +{
47079 + ASSERT_COND(h_FmPcdPlcr);
47080 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
47081 +}
47082 +
47083 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
47084 +{
47085 + ASSERT_COND(h_FmPcdPlcr);
47086 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
47087 +}
47088 +
47089 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
47090 +{
47091 + ASSERT_COND(h_FmPcdPlcr);
47092 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
47093 +}
47094 +
47095 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
47096 +{
47097 + ASSERT_COND(h_FmPcdPlcr);
47098 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
47099 +}
47100 +
47101 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
47102 +{
47103 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47104 + uint16_t i;
47105 +
47106 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
47107 +
47108 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
47109 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
47110 + return TRUE;
47111 + return FALSE;
47112 +}
47113 +
47114 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
47115 +{
47116 + uint32_t nia;
47117 + uint16_t absoluteProfileId;
47118 + uint8_t relativeSchemeId, physicalSchemeId;
47119 +
47120 + nia = FM_PCD_PLCR_NIA_VALID;
47121 +
47122 + switch (nextEngine)
47123 + {
47124 + case e_FM_PCD_DONE :
47125 + switch (p_NextEngineParams->action)
47126 + {
47127 + case e_FM_PCD_DROP_FRAME :
47128 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
47129 + break;
47130 + case e_FM_PCD_ENQ_FRAME:
47131 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47132 + break;
47133 + default:
47134 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47135 + }
47136 + break;
47137 + case e_FM_PCD_KG:
47138 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
47139 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
47140 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
47141 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
47142 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
47143 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
47144 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
47145 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
47146 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
47147 + break;
47148 + case e_FM_PCD_PLCR:
47149 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
47150 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
47151 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
47152 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
47153 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
47154 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
47155 + break;
47156 + default:
47157 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47158 + }
47159 +
47160 + *nextAction = nia;
47161 +
47162 + return E_OK;
47163 +}
47164 +
47165 +static uint32_t CalcFPP(uint32_t fpp)
47166 +{
47167 + if (fpp > 15)
47168 + return 15 - (0x1f - fpp);
47169 + else
47170 + return 16 + fpp;
47171 +}
47172 +
47173 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
47174 + uint32_t rate,
47175 + uint64_t tsuInTenthNano,
47176 + uint32_t fppShift,
47177 + uint64_t *p_Integer,
47178 + uint64_t *p_Fraction)
47179 +{
47180 + uint64_t tmp, div;
47181 +
47182 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
47183 + {
47184 + /* now we calculate the initial integer for the bigger rate */
47185 + /* from Kbps to Bytes/TSU */
47186 + tmp = (uint64_t)rate;
47187 + tmp *= 1000; /* kb --> b */
47188 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47189 +
47190 + div = 1000000000; /* nano */
47191 + div *= 10; /* 10 nano */
47192 + div *= 8; /* bit to byte */
47193 + }
47194 + else
47195 + {
47196 + /* now we calculate the initial integer for the bigger rate */
47197 + /* from Kbps to Bytes/TSU */
47198 + tmp = (uint64_t)rate;
47199 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
47200 +
47201 + div = 1000000000; /* nano */
47202 + div *= 10; /* 10 nano */
47203 + }
47204 + *p_Integer = div64_u64(tmp<<fppShift, div);
47205 +
47206 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
47207 + * For precision, we will multiply by 2^16. we do not divid back, since we write
47208 + * this value as fraction - see spec.
47209 + */
47210 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
47211 +}
47212 +
47213 +/* .......... */
47214 +
47215 +static void CalcRates(uint32_t bitFor1Micro,
47216 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
47217 + uint32_t *cir,
47218 + uint32_t *cbs,
47219 + uint32_t *pir_eir,
47220 + uint32_t *pbs_ebs,
47221 + uint32_t *fpp)
47222 +{
47223 + uint64_t integer, fraction;
47224 + uint32_t temp, tsuInTenthNanos;
47225 + uint8_t fppShift=0;
47226 +
47227 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
47228 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
47229 +
47230 + /* we choose the faster rate to calibrate fpp */
47231 + /* The meaning of this step:
47232 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
47233 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
47234 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
47235 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
47236 + * high rate, as many bits as possible for fraction at low rate.
47237 + */
47238 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
47239 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47240 + else
47241 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
47242 +
47243 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
47244 + * the LSB bits are for the fraction */
47245 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
47246 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
47247 + * take max FP = 31.
47248 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
47249 + * limited by the 10G physical port.
47250 + */
47251 + if (temp != 0)
47252 + {
47253 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
47254 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
47255 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
47256 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
47257 + * to use these bits for the fraction. in this way we will have for fraction - the number
47258 + * of "0" bits and the rest - for integer.
47259 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
47260 + * one bit to the left - preserving the relationship and achieving more bits
47261 + * for integer in the TS.
47262 + */
47263 +
47264 + /* count zeroes left of the higher used bit (in order to shift the value such that
47265 + * unused bits may be used for fraction).
47266 + */
47267 + while ((temp & 0x80000000) == 0)
47268 + {
47269 + temp = temp << 1;
47270 + fppShift++;
47271 + }
47272 + if (fppShift > 15)
47273 + {
47274 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
47275 + return;
47276 + }
47277 + }
47278 + else
47279 + {
47280 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
47281 + if (!temp)
47282 + /* integer and fraction are 0, we set FP to its max val */
47283 + fppShift = 31;
47284 + else
47285 + {
47286 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
47287 + * + all left zeroes of the fraction. */
47288 + fppShift=16;
47289 + /* count zeroes left of the higher used bit (in order to shift the value such that
47290 + * unused bits may be used for fraction).
47291 + */
47292 + while ((temp & 0x8000) == 0)
47293 + {
47294 + temp = temp << 1;
47295 + fppShift++;
47296 + }
47297 + }
47298 + }
47299 +
47300 + /*
47301 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
47302 + * fraction and the rest for integer */
47303 + /* now we re-calculate cir and pir_eir with the calculated FP */
47304 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47305 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47306 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
47307 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
47308 +
47309 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
47310 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
47311 +
47312 + /* convert FP as it should be written to reg.
47313 + * 0-15 --> 16-31
47314 + * 16-31 --> 0-15
47315 + */
47316 + *fpp = CalcFPP(fppShift);
47317 +}
47318 +
47319 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
47320 +{
47321 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47322 +
47323 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47324 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
47325 +
47326 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
47327 +}
47328 +
47329 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
47330 + t_FmPcdPlcrProfileParams *p_ProfileParams,
47331 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
47332 +{
47333 + t_Error err = E_OK;
47334 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
47335 +
47336 + ASSERT_COND(p_FmPcd);
47337 +
47338 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
47339 + if (bitFor1Micro == 0)
47340 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
47341 +
47342 +/* Set G, Y, R Nia */
47343 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
47344 + if (err)
47345 + RETURN_ERROR(MAJOR, err, NO_MSG);
47346 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
47347 + if (err)
47348 + RETURN_ERROR(MAJOR, err, NO_MSG);
47349 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
47350 + if (err)
47351 + RETURN_ERROR(MAJOR, err, NO_MSG);
47352 +
47353 +/* Mode fmpl_pemode */
47354 + pemode = FM_PCD_PLCR_PEMODE_PI;
47355 +
47356 + switch (p_ProfileParams->algSelection)
47357 + {
47358 + case e_FM_PCD_PLCR_PASS_THROUGH:
47359 + p_PlcrRegs->fmpl_pecir = 0;
47360 + p_PlcrRegs->fmpl_pecbs = 0;
47361 + p_PlcrRegs->fmpl_pepepir_eir = 0;
47362 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
47363 + p_PlcrRegs->fmpl_pelts = 0;
47364 + p_PlcrRegs->fmpl_pects = 0;
47365 + p_PlcrRegs->fmpl_pepts_ets = 0;
47366 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
47367 + switch (p_ProfileParams->colorMode)
47368 + {
47369 + case e_FM_PCD_PLCR_COLOR_BLIND:
47370 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47371 + switch (p_ProfileParams->color.dfltColor)
47372 + {
47373 + case e_FM_PCD_PLCR_GREEN:
47374 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
47375 + break;
47376 + case e_FM_PCD_PLCR_YELLOW:
47377 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
47378 + break;
47379 + case e_FM_PCD_PLCR_RED:
47380 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
47381 + break;
47382 + case e_FM_PCD_PLCR_OVERRIDE:
47383 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
47384 + break;
47385 + default:
47386 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47387 + }
47388 +
47389 + break;
47390 + case e_FM_PCD_PLCR_COLOR_AWARE:
47391 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47392 + break;
47393 + default:
47394 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47395 + }
47396 + break;
47397 +
47398 + case e_FM_PCD_PLCR_RFC_2698:
47399 + /* Select algorithm MODE[ALG] = "01" */
47400 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
47401 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
47402 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
47403 + goto cont_rfc;
47404 + case e_FM_PCD_PLCR_RFC_4115:
47405 + /* Select algorithm MODE[ALG] = "10" */
47406 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
47407 +cont_rfc:
47408 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
47409 + switch (p_ProfileParams->colorMode)
47410 + {
47411 + case e_FM_PCD_PLCR_COLOR_BLIND:
47412 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
47413 + break;
47414 + case e_FM_PCD_PLCR_COLOR_AWARE:
47415 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
47416 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
47417 + switch (p_ProfileParams->color.override)
47418 + {
47419 + case e_FM_PCD_PLCR_GREEN:
47420 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
47421 + break;
47422 + case e_FM_PCD_PLCR_YELLOW:
47423 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
47424 + break;
47425 + case e_FM_PCD_PLCR_RED:
47426 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
47427 + break;
47428 + case e_FM_PCD_PLCR_OVERRIDE:
47429 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
47430 + break;
47431 + default:
47432 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47433 + }
47434 + break;
47435 + default:
47436 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47437 + }
47438 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
47439 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
47440 + {
47441 + case e_FM_PCD_PLCR_BYTE_MODE :
47442 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
47443 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
47444 + {
47445 + case e_FM_PCD_PLCR_L2_FRM_LEN:
47446 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
47447 + break;
47448 + case e_FM_PCD_PLCR_L3_FRM_LEN:
47449 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
47450 + break;
47451 + case e_FM_PCD_PLCR_L4_FRM_LEN:
47452 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
47453 + break;
47454 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
47455 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
47456 + break;
47457 + default:
47458 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47459 + }
47460 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
47461 + {
47462 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
47463 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
47464 + break;
47465 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
47466 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
47467 + break;
47468 + default:
47469 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47470 + }
47471 + break;
47472 + case e_FM_PCD_PLCR_PACKET_MODE :
47473 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
47474 + break;
47475 + default:
47476 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47477 + }
47478 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
47479 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
47480 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
47481 +
47482 + /* Configure Traffic Parameters*/
47483 + {
47484 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
47485 +
47486 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
47487 +
47488 + /* Set Committed Information Rate (CIR) */
47489 + p_PlcrRegs->fmpl_pecir = cir;
47490 + /* Set Committed Burst Size (CBS). */
47491 + p_PlcrRegs->fmpl_pecbs = cbs;
47492 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
47493 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
47494 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
47495 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
47496 +
47497 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
47498 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
47499 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
47500 + /* Committed Rate Token Bucket Size (CTS) */
47501 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
47502 +
47503 + /* Set the FPP based on calculation */
47504 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
47505 + }
47506 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
47507 + default:
47508 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
47509 + }
47510 +
47511 + p_PlcrRegs->fmpl_pemode = pemode;
47512 +
47513 + p_PlcrRegs->fmpl_pegnia = gnia;
47514 + p_PlcrRegs->fmpl_peynia = ynia;
47515 + p_PlcrRegs->fmpl_pernia = rnia;
47516 +
47517 + /* Zero Counters */
47518 + p_PlcrRegs->fmpl_pegpc = 0;
47519 + p_PlcrRegs->fmpl_peypc = 0;
47520 + p_PlcrRegs->fmpl_perpc = 0;
47521 + p_PlcrRegs->fmpl_perypc = 0;
47522 + p_PlcrRegs->fmpl_perrpc = 0;
47523 +
47524 + return E_OK;
47525 +}
47526 +
47527 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47528 +{
47529 + uint32_t profilesFound;
47530 + uint16_t i, k=0;
47531 + uint32_t intFlags;
47532 +
47533 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47534 +
47535 + if (!numOfProfiles)
47536 + return E_OK;
47537 +
47538 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
47539 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
47540 +
47541 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
47542 + /* Find numOfProfiles free profiles (may be spread) */
47543 + profilesFound = 0;
47544 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47545 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
47546 + {
47547 + profilesFound++;
47548 + profilesIds[k] = i;
47549 + k++;
47550 + if (profilesFound == numOfProfiles)
47551 + break;
47552 + }
47553 +
47554 + if (profilesFound != numOfProfiles)
47555 + {
47556 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47557 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
47558 + }
47559 +
47560 + for (i = 0;i<k;i++)
47561 + {
47562 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
47563 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
47564 + }
47565 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
47566 +
47567 + return E_OK;
47568 +}
47569 +
47570 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
47571 +{
47572 + uint16_t i;
47573 +
47574 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
47575 +
47576 + ASSERT_COND(numOfProfiles);
47577 +
47578 + for (i=0; i < numOfProfiles; i++)
47579 + {
47580 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
47581 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
47582 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
47583 + }
47584 +}
47585 +
47586 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
47587 +{
47588 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47589 +
47590 + /* this routine is protected by calling routine */
47591 +
47592 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
47593 +
47594 + if (set)
47595 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
47596 + else
47597 + {
47598 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
47599 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
47600 + }
47601 +}
47602 +
47603 +/*********************************************/
47604 +/*............Policer Exception..............*/
47605 +/*********************************************/
47606 +static void EventsCB(t_Handle h_FmPcd)
47607 +{
47608 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47609 + uint32_t event, mask, force;
47610 +
47611 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47612 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
47613 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47614 +
47615 + event &= mask;
47616 +
47617 + /* clear the forced events */
47618 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
47619 + if (force & event)
47620 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
47621 +
47622 +
47623 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
47624 +
47625 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
47626 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
47627 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
47628 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
47629 +}
47630 +
47631 +/* ..... */
47632 +
47633 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
47634 +{
47635 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
47636 + uint32_t event, force, captureReg, mask;
47637 +
47638 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
47639 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
47640 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47641 +
47642 + event &= mask;
47643 +
47644 + /* clear the forced events */
47645 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
47646 + if (force & event)
47647 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
47648 +
47649 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
47650 +
47651 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
47652 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
47653 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
47654 + {
47655 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
47656 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
47657 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
47658 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
47659 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
47660 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
47661 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
47662 + }
47663 +}
47664 +
47665 +
47666 +/*****************************************************************************/
47667 +/* Inter-module API routines */
47668 +/*****************************************************************************/
47669 +
47670 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
47671 +{
47672 + t_FmPcdPlcr *p_FmPcdPlcr;
47673 + uint16_t i=0;
47674 +
47675 + UNUSED(p_FmPcd);
47676 + UNUSED(p_FmPcdParams);
47677 +
47678 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
47679 + if (!p_FmPcdPlcr)
47680 + {
47681 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
47682 + return NULL;
47683 + }
47684 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
47685 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
47686 + {
47687 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
47688 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
47689 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
47690 + }
47691 +
47692 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
47693 +
47694 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
47695 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
47696 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
47697 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
47698 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
47699 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
47700 +
47701 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
47702 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47703 +
47704 + return p_FmPcdPlcr;
47705 +}
47706 +
47707 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
47708 +{
47709 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
47710 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
47711 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47712 + t_Error err = E_OK;
47713 + uint32_t tmpReg32 = 0;
47714 + uint16_t base;
47715 +
47716 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
47717 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
47718 +
47719 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
47720 + if (!p_FmPcdPlcr->h_HwSpinlock)
47721 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
47722 +
47723 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
47724 + if (!p_FmPcdPlcr->h_SwSpinlock)
47725 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
47726 +
47727 + base = PlcrAllocProfilesForPartition(p_FmPcd,
47728 + p_FmPcdPlcr->partPlcrProfilesBase,
47729 + p_FmPcdPlcr->partNumOfPlcrProfiles,
47730 + p_FmPcd->guestId);
47731 + if (base == (uint16_t)ILLEGAL_BASE)
47732 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
47733 +
47734 + if (p_FmPcdPlcr->numOfSharedProfiles)
47735 + {
47736 + err = AllocSharedProfiles(p_FmPcd,
47737 + p_FmPcdPlcr->numOfSharedProfiles,
47738 + p_FmPcdPlcr->sharedProfilesIds);
47739 + if (err)
47740 + RETURN_ERROR(MAJOR, err,NO_MSG);
47741 + }
47742 +
47743 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47744 + return E_OK;
47745 +
47746 + /**********************FMPL_GCR******************/
47747 + tmpReg32 = 0;
47748 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
47749 + if (p_Param->plcrAutoRefresh)
47750 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
47751 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
47752 +
47753 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
47754 + /**********************FMPL_GCR******************/
47755 +
47756 + /**********************FMPL_EEVR******************/
47757 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
47758 + /**********************FMPL_EEVR******************/
47759 + /**********************FMPL_EIER******************/
47760 + tmpReg32 = 0;
47761 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
47762 + {
47763 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47764 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
47765 + }
47766 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47767 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47768 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
47769 + /**********************FMPL_EIER******************/
47770 +
47771 + /**********************FMPL_EVR******************/
47772 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
47773 + /**********************FMPL_EVR******************/
47774 + /**********************FMPL_IER******************/
47775 + tmpReg32 = 0;
47776 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
47777 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47778 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
47779 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47780 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
47781 + /**********************FMPL_IER******************/
47782 +
47783 + /* register even if no interrupts enabled, to allow future enablement */
47784 + FmRegisterIntr(p_FmPcd->h_Fm,
47785 + e_FM_MOD_PLCR,
47786 + 0,
47787 + e_FM_INTR_TYPE_ERR,
47788 + ErrorExceptionsCB,
47789 + p_FmPcd);
47790 + FmRegisterIntr(p_FmPcd->h_Fm,
47791 + e_FM_MOD_PLCR,
47792 + 0,
47793 + e_FM_INTR_TYPE_NORMAL,
47794 + EventsCB,
47795 + p_FmPcd);
47796 +
47797 + /* driver initializes one DFLT profile at the last entry*/
47798 + /**********************FMPL_DPMR******************/
47799 + tmpReg32 = 0;
47800 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
47801 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
47802 +
47803 + return E_OK;
47804 +}
47805 +
47806 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
47807 +{
47808 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
47809 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
47810 +
47811 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
47812 + FreeSharedProfiles(p_FmPcd,
47813 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
47814 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
47815 +
47816 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
47817 + PlcrFreeProfilesForPartition(p_FmPcd,
47818 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
47819 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
47820 + p_FmPcd->guestId);
47821 +
47822 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
47823 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
47824 +
47825 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
47826 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
47827 +
47828 + return E_OK;
47829 +}
47830 +
47831 +void PlcrEnable(t_FmPcd *p_FmPcd)
47832 +{
47833 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47834 +
47835 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
47836 +}
47837 +
47838 +void PlcrDisable(t_FmPcd *p_FmPcd)
47839 +{
47840 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47841 +
47842 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
47843 +}
47844 +
47845 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47846 +{
47847 + uint32_t intFlags;
47848 + uint16_t profilesFound = 0;
47849 + int i = 0;
47850 +
47851 + ASSERT_COND(p_FmPcd);
47852 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47853 +
47854 + if (!numOfProfiles)
47855 + return 0;
47856 +
47857 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
47858 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
47859 + return (uint16_t)ILLEGAL_BASE;
47860 +
47861 + if (p_FmPcd->h_IpcSession)
47862 + {
47863 + t_FmIpcResourceAllocParams ipcAllocParams;
47864 + t_FmPcdIpcMsg msg;
47865 + t_FmPcdIpcReply reply;
47866 + t_Error err;
47867 + uint32_t replyLength;
47868 +
47869 + memset(&msg, 0, sizeof(msg));
47870 + memset(&reply, 0, sizeof(reply));
47871 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47872 + ipcAllocParams.guestId = p_FmPcd->guestId;
47873 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47874 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47875 + msg.msgId = FM_PCD_ALLOC_PROFILES;
47876 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47877 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
47878 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47879 + (uint8_t*)&msg,
47880 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47881 + (uint8_t*)&reply,
47882 + &replyLength,
47883 + NULL,
47884 + NULL);
47885 + if ((err != E_OK) ||
47886 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
47887 + {
47888 + REPORT_ERROR(MAJOR, err, NO_MSG);
47889 + return (uint16_t)ILLEGAL_BASE;
47890 + }
47891 + else
47892 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
47893 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
47894 + {
47895 + REPORT_ERROR(MAJOR, err, NO_MSG);
47896 + return (uint16_t)ILLEGAL_BASE;
47897 + }
47898 + }
47899 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47900 + {
47901 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47902 + return (uint16_t)ILLEGAL_BASE;
47903 + }
47904 +
47905 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
47906 + for (i=base; i<(base+numOfProfiles); i++)
47907 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
47908 + profilesFound++;
47909 + else
47910 + break;
47911 +
47912 + if (profilesFound == numOfProfiles)
47913 + for (i=base; i<(base+numOfProfiles); i++)
47914 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
47915 + else
47916 + {
47917 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47918 + return (uint16_t)ILLEGAL_BASE;
47919 + }
47920 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
47921 +
47922 + return base;
47923 +}
47924 +
47925 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
47926 +{
47927 + int i = 0;
47928 +
47929 + ASSERT_COND(p_FmPcd);
47930 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
47931 +
47932 + if (p_FmPcd->h_IpcSession)
47933 + {
47934 + t_FmIpcResourceAllocParams ipcAllocParams;
47935 + t_FmPcdIpcMsg msg;
47936 + t_Error err;
47937 +
47938 + memset(&msg, 0, sizeof(msg));
47939 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47940 + ipcAllocParams.guestId = p_FmPcd->guestId;
47941 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
47942 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
47943 + msg.msgId = FM_PCD_FREE_PROFILES;
47944 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47945 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47946 + (uint8_t*)&msg,
47947 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47948 + NULL,
47949 + NULL,
47950 + NULL,
47951 + NULL);
47952 + if (err != E_OK)
47953 + REPORT_ERROR(MAJOR, err, NO_MSG);
47954 + return;
47955 + }
47956 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
47957 + {
47958 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
47959 + return;
47960 + }
47961 +
47962 + for (i=base; i<(base+numOfProfiles); i++)
47963 + {
47964 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
47965 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
47966 + else
47967 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
47968 + }
47969 +}
47970 +
47971 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
47972 + uint8_t hardwarePortId,
47973 + uint16_t numOfProfiles,
47974 + uint16_t base)
47975 +{
47976 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
47977 + uint32_t log2Num, tmpReg32;
47978 +
47979 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47980 + !p_Regs &&
47981 + p_FmPcd->h_IpcSession)
47982 + {
47983 + t_FmIpcResourceAllocParams ipcAllocParams;
47984 + t_FmPcdIpcMsg msg;
47985 + t_Error err;
47986 +
47987 + memset(&msg, 0, sizeof(msg));
47988 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
47989 + ipcAllocParams.guestId = hardwarePortId;
47990 + ipcAllocParams.num = numOfProfiles;
47991 + ipcAllocParams.base = base;
47992 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
47993 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
47994 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47995 + (uint8_t*)&msg,
47996 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
47997 + NULL,
47998 + NULL,
47999 + NULL,
48000 + NULL);
48001 + if (err != E_OK)
48002 + RETURN_ERROR(MAJOR, err, NO_MSG);
48003 + return E_OK;
48004 + }
48005 + else if (!p_Regs)
48006 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
48007 + ("Either IPC or 'baseAddress' is required!"));
48008 +
48009 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48010 +
48011 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
48012 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
48013 + ("The requesting port has already an allocated profiles window."));
48014 +
48015 + /**********************FMPL_PMRx******************/
48016 + LOG2((uint64_t)numOfProfiles, log2Num);
48017 + tmpReg32 = base;
48018 + tmpReg32 |= log2Num << 16;
48019 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
48020 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
48021 +
48022 + return E_OK;
48023 +}
48024 +
48025 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
48026 +{
48027 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48028 +
48029 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
48030 + !p_Regs &&
48031 + p_FmPcd->h_IpcSession)
48032 + {
48033 + t_FmIpcResourceAllocParams ipcAllocParams;
48034 + t_FmPcdIpcMsg msg;
48035 + t_Error err;
48036 +
48037 + memset(&msg, 0, sizeof(msg));
48038 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
48039 + ipcAllocParams.guestId = hardwarePortId;
48040 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
48041 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
48042 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
48043 + (uint8_t*)&msg,
48044 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
48045 + NULL,
48046 + NULL,
48047 + NULL,
48048 + NULL);
48049 + if (err != E_OK)
48050 + RETURN_ERROR(MAJOR, err, NO_MSG);
48051 + return E_OK;
48052 + }
48053 + else if (!p_Regs)
48054 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
48055 + ("Either IPC or 'baseAddress' is required!"));
48056 +
48057 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48058 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
48059 +
48060 + return E_OK;
48061 +}
48062 +
48063 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
48064 +{
48065 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48066 + t_Error err = E_OK;
48067 + uint32_t profilesFound;
48068 + uint32_t intFlags;
48069 + uint16_t i, first, swPortIndex = 0;
48070 +
48071 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48072 +
48073 + if (!numOfProfiles)
48074 + return E_OK;
48075 +
48076 + ASSERT_COND(hardwarePortId);
48077 +
48078 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
48079 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
48080 +
48081 + if (!POWER_OF_2(numOfProfiles))
48082 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
48083 +
48084 + first = 0;
48085 + profilesFound = 0;
48086 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48087 +
48088 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
48089 + {
48090 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
48091 + {
48092 + profilesFound++;
48093 + i++;
48094 + if (profilesFound == numOfProfiles)
48095 + break;
48096 + }
48097 + else
48098 + {
48099 + profilesFound = 0;
48100 + /* advance i to the next aligned address */
48101 + i = first = (uint16_t)(first + numOfProfiles);
48102 + }
48103 + }
48104 +
48105 + if (profilesFound == numOfProfiles)
48106 + {
48107 + for (i=first; i<first + numOfProfiles; i++)
48108 + {
48109 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
48110 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
48111 + }
48112 + }
48113 + else
48114 + {
48115 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48116 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
48117 + }
48118 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48119 +
48120 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
48121 + if (err)
48122 + {
48123 + RETURN_ERROR(MAJOR, err, NO_MSG);
48124 + }
48125 +
48126 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48127 +
48128 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
48129 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
48130 +
48131 + return E_OK;
48132 +}
48133 +
48134 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48135 +{
48136 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48137 + t_Error err = E_OK;
48138 + uint32_t intFlags;
48139 + uint16_t i, swPortIndex = 0;
48140 +
48141 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
48142 +
48143 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48144 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48145 +
48146 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48147 +
48148 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
48149 + if (err)
48150 + RETURN_ERROR(MAJOR, err,NO_MSG);
48151 +
48152 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
48153 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48154 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
48155 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
48156 + i++)
48157 + {
48158 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
48159 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
48160 +
48161 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
48162 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
48163 + }
48164 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48165 +
48166 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
48167 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
48168 +
48169 + return E_OK;
48170 +}
48171 +
48172 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
48173 +{
48174 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48175 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48176 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
48177 + uint32_t tmpReg32, intFlags;
48178 + t_Error err;
48179 +
48180 + /* Calling function locked all PCD modules, so no need to lock here */
48181 +
48182 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48183 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
48184 +
48185 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
48186 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
48187 +
48188 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
48189 +
48190 + if (p_FmPcd->h_Hc)
48191 + {
48192 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
48193 +
48194 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48195 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48196 +
48197 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48198 + return err;
48199 + }
48200 +
48201 + /* lock the HW because once we read the registers we don't want them to be changed
48202 + * by another access. (We can copy to a tmp location and release the lock!) */
48203 +
48204 + intFlags = PlcrHwLock(p_FmPcdPlcr);
48205 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48206 +
48207 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
48208 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
48209 + {
48210 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
48211 + {
48212 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
48213 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
48214 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
48215 + {
48216 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48217 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48218 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
48219 + }
48220 +
48221 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
48222 + {
48223 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
48224 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48225 + {
48226 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48227 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48228 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48229 + }
48230 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48231 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
48232 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48233 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48234 + WritePar(p_FmPcd, tmpReg32);
48235 + }
48236 +
48237 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
48238 + {
48239 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
48240 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48241 + {
48242 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48243 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48244 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48245 + }
48246 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48247 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
48248 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48249 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48250 + WritePar(p_FmPcd, tmpReg32);
48251 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48252 + }
48253 +
48254 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
48255 + {
48256 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
48257 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
48258 + {
48259 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48260 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48261 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
48262 + }
48263 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
48264 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
48265 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48266 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48267 + WritePar(p_FmPcd, tmpReg32);
48268 +
48269 + }
48270 + }
48271 + }
48272 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
48273 +
48274 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
48275 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
48276 +
48277 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
48278 +
48279 + return E_OK;
48280 +}
48281 +
48282 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48283 +{
48284 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48285 +
48286 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48287 +
48288 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
48289 +}
48290 +
48291 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48292 +{
48293 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48294 +
48295 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48296 +
48297 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
48298 +}
48299 +
48300 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48301 +{
48302 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48303 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48304 +
48305 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
48306 +
48307 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
48308 +}
48309 +
48310 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48311 +{
48312 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48313 + uint32_t intFlags;
48314 +
48315 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48316 +
48317 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48318 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
48319 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48320 +}
48321 +
48322 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48323 +{
48324 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48325 + uint32_t intFlags;
48326 +
48327 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48328 +
48329 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
48330 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
48331 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
48332 +}
48333 +
48334 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
48335 +{
48336 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
48337 +}
48338 +
48339 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
48340 + e_FmPcdProfileTypeSelection profileType,
48341 + t_Handle h_FmPort,
48342 + uint16_t relativeProfile,
48343 + uint16_t *p_AbsoluteId)
48344 +{
48345 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48346 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
48347 + uint8_t i;
48348 +
48349 + switch (profileType)
48350 + {
48351 + case e_FM_PCD_PLCR_PORT_PRIVATE:
48352 + /* get port PCD id from port handle */
48353 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
48354 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
48355 + break;
48356 + if (i == FM_MAX_NUM_OF_PORTS)
48357 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
48358 +
48359 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48360 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
48361 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
48362 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48363 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
48364 + break;
48365 + case e_FM_PCD_PLCR_SHARED:
48366 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
48367 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
48368 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
48369 + break;
48370 + default:
48371 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
48372 + }
48373 +
48374 + return E_OK;
48375 +}
48376 +
48377 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
48378 +{
48379 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48380 + uint16_t swPortIndex = 0;
48381 +
48382 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48383 +
48384 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
48385 +}
48386 +
48387 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
48388 +{
48389 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
48390 + uint16_t swPortIndex = 0;
48391 +
48392 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
48393 +
48394 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
48395 +
48396 +}
48397 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
48398 +{
48399 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48400 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
48401 +}
48402 +
48403 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
48404 +{
48405 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48406 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48407 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48408 +}
48409 +
48410 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
48411 +{
48412 +
48413 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
48414 + return TRUE;
48415 + else
48416 + return FALSE;
48417 +}
48418 +
48419 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
48420 +{
48421 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
48422 + FM_PCD_PLCR_PAR_R |
48423 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
48424 + FM_PCD_PLCR_PAR_PWSEL_MASK);
48425 +}
48426 +
48427 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
48428 +{
48429 + switch (counter)
48430 + {
48431 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
48432 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
48433 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
48434 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
48435 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
48436 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
48437 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
48438 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
48439 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
48440 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
48441 + default:
48442 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48443 + return 0;
48444 + }
48445 +}
48446 +
48447 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
48448 +{
48449 +
48450 + uint32_t tmpReg32 = 0;
48451 +
48452 + if (green)
48453 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
48454 + if (yellow)
48455 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
48456 + if (red)
48457 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
48458 +
48459 + return tmpReg32;
48460 +}
48461 +
48462 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
48463 +{
48464 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48465 +
48466 + /* this routine is protected by calling routine */
48467 +
48468 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
48469 +
48470 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
48471 +}
48472 +
48473 +/*********************** End of inter-module routines ************************/
48474 +
48475 +
48476 +/**************************************************/
48477 +/*............Policer API.........................*/
48478 +/**************************************************/
48479 +
48480 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
48481 +{
48482 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48483 +
48484 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48485 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48486 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48487 +
48488 + if (!FmIsMaster(p_FmPcd->h_Fm))
48489 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
48490 +
48491 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
48492 +
48493 + return E_OK;
48494 +}
48495 +
48496 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
48497 +{
48498 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48499 +
48500 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48501 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48502 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48503 +
48504 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
48505 +
48506 + return E_OK;
48507 +}
48508 +
48509 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
48510 +{
48511 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48512 + uint32_t tmpReg32;
48513 +
48514 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48515 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
48516 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
48517 +
48518 + if (!FmIsMaster(p_FmPcd->h_Fm))
48519 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
48520 +
48521 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
48522 + if (enable)
48523 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
48524 + else
48525 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
48526 +
48527 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
48528 + return E_OK;
48529 +}
48530 +
48531 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
48532 + t_FmPcdPlcrProfileParams *p_ProfileParams)
48533 +{
48534 + t_FmPcd *p_FmPcd;
48535 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48536 + t_FmPcdPlcrProfileRegs plcrProfileReg;
48537 + uint32_t intFlags;
48538 + uint16_t absoluteProfileId;
48539 + t_Error err = E_OK;
48540 + uint32_t tmpReg32;
48541 + t_FmPcdPlcrProfile *p_Profile;
48542 +
48543 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
48544 +
48545 + if (p_ProfileParams->modify)
48546 + {
48547 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
48548 + p_FmPcd = p_Profile->h_FmPcd;
48549 + absoluteProfileId = p_Profile->absoluteProfileId;
48550 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48551 + {
48552 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48553 + return NULL;
48554 + }
48555 +
48556 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48557 +
48558 + /* Try lock profile using flag */
48559 + if (!PlcrProfileFlagTryLock(p_Profile))
48560 + {
48561 + DBG(TRACE, ("Profile Try Lock - BUSY"));
48562 + /* Signal to caller BUSY condition */
48563 + p_ProfileParams->id.h_Profile = NULL;
48564 + return NULL;
48565 + }
48566 + }
48567 + else
48568 + {
48569 + p_FmPcd = (t_FmPcd*)h_FmPcd;
48570 +
48571 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
48572 +
48573 + /* SMP: needs to be protected only if another core now changes the windows */
48574 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
48575 + p_ProfileParams->id.newParams.profileType,
48576 + p_ProfileParams->id.newParams.h_FmPort,
48577 + p_ProfileParams->id.newParams.relativeProfileId,
48578 + &absoluteProfileId);
48579 + if (err)
48580 + {
48581 + REPORT_ERROR(MAJOR, err, NO_MSG);
48582 + return NULL;
48583 + }
48584 +
48585 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
48586 + {
48587 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48588 + return NULL;
48589 + }
48590 +
48591 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48592 + {
48593 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
48594 + return NULL;
48595 + }
48596 +
48597 + /* initialize profile struct */
48598 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
48599 +
48600 + p_Profile->h_FmPcd = p_FmPcd;
48601 + p_Profile->absoluteProfileId = absoluteProfileId;
48602 +
48603 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
48604 + if (!p_Profile->p_Lock)
48605 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
48606 + }
48607 +
48608 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
48609 +
48610 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
48611 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
48612 +
48613 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
48614 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
48615 +
48616 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
48617 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
48618 +
48619 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
48620 +
48621 + /* build the policer profile registers */
48622 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
48623 + if (err)
48624 + {
48625 + REPORT_ERROR(MAJOR, err, NO_MSG);
48626 + if (p_ProfileParams->modify)
48627 + /* unlock */
48628 + PlcrProfileFlagUnlock(p_Profile);
48629 + if (!p_ProfileParams->modify &&
48630 + p_Profile->p_Lock)
48631 + /* release allocated Profile lock */
48632 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48633 + return NULL;
48634 + }
48635 +
48636 + if (p_FmPcd->h_Hc)
48637 + {
48638 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
48639 + if (p_ProfileParams->modify)
48640 + PlcrProfileFlagUnlock(p_Profile);
48641 + if (err)
48642 + {
48643 + /* release the allocated scheme lock */
48644 + if (!p_ProfileParams->modify &&
48645 + p_Profile->p_Lock)
48646 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48647 +
48648 + return NULL;
48649 + }
48650 + if (!p_ProfileParams->modify)
48651 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48652 + return (t_Handle)p_Profile;
48653 + }
48654 +
48655 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48656 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
48657 +
48658 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48659 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
48660 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
48661 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
48662 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
48663 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
48664 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
48665 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
48666 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
48667 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
48668 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
48669 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
48670 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
48671 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
48672 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
48673 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
48674 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
48675 +
48676 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
48677 + WritePar(p_FmPcd, tmpReg32);
48678 +
48679 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48680 +
48681 + if (!p_ProfileParams->modify)
48682 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
48683 + else
48684 + PlcrProfileFlagUnlock(p_Profile);
48685 +
48686 + return (t_Handle)p_Profile;
48687 +}
48688 +
48689 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
48690 +{
48691 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48692 + t_FmPcd *p_FmPcd;
48693 + uint16_t profileIndx;
48694 + uint32_t tmpReg32, intFlags;
48695 + t_Error err;
48696 +
48697 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48698 + p_FmPcd = p_Profile->h_FmPcd;
48699 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48700 +
48701 + profileIndx = p_Profile->absoluteProfileId;
48702 +
48703 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
48704 +
48705 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
48706 +
48707 + if (p_FmPcd->h_Hc)
48708 + {
48709 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
48710 + if (p_Profile->p_Lock)
48711 + /* release allocated Profile lock */
48712 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48713 +
48714 + return err;
48715 + }
48716 +
48717 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48718 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
48719 +
48720 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
48721 + WritePar(p_FmPcd, tmpReg32);
48722 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48723 +
48724 +
48725 + if (p_Profile->p_Lock)
48726 + /* release allocated Profile lock */
48727 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
48728 +
48729 + /* we do not memset profile as all its fields are being re-initialized at "set",
48730 + * plus its allocation information is still valid. */
48731 + return E_OK;
48732 +}
48733 +
48734 +/***************************************************/
48735 +/*............Policer Profile Counter..............*/
48736 +/***************************************************/
48737 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
48738 +{
48739 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48740 + t_FmPcd *p_FmPcd;
48741 + uint16_t profileIndx;
48742 + uint32_t intFlags, counterVal = 0;
48743 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48744 +
48745 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48746 + p_FmPcd = p_Profile->h_FmPcd;
48747 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
48748 +
48749 + if (p_FmPcd->h_Hc)
48750 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
48751 +
48752 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48753 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
48754 +
48755 + profileIndx = p_Profile->absoluteProfileId;
48756 +
48757 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
48758 + {
48759 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
48760 + return 0;
48761 + }
48762 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48763 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
48764 +
48765 + switch (counter)
48766 + {
48767 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48768 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
48769 + break;
48770 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48771 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
48772 + break;
48773 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48774 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
48775 + break;
48776 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48777 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
48778 + break;
48779 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48780 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
48781 + break;
48782 + default:
48783 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48784 + break;
48785 + }
48786 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48787 +
48788 + return counterVal;
48789 +}
48790 +
48791 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
48792 +{
48793 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
48794 + t_FmPcd *p_FmPcd;
48795 + uint16_t profileIndx;
48796 + uint32_t tmpReg32, intFlags;
48797 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48798 +
48799 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
48800 +
48801 + p_FmPcd = p_Profile->h_FmPcd;
48802 + profileIndx = p_Profile->absoluteProfileId;
48803 +
48804 + if (p_FmPcd->h_Hc)
48805 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
48806 +
48807 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48808 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
48809 +
48810 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
48811 + switch (counter)
48812 + {
48813 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
48814 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
48815 + break;
48816 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
48817 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
48818 + break;
48819 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
48820 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
48821 + break;
48822 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
48823 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
48824 + break;
48825 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
48826 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
48827 + break;
48828 + default:
48829 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48830 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48831 + }
48832 +
48833 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
48834 + * Profile Number, PWSEL=0xFFFF (select all words).
48835 + */
48836 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
48837 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
48838 + WritePar(p_FmPcd, tmpReg32);
48839 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
48840 +
48841 + return E_OK;
48842 +}
48843 --- /dev/null
48844 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
48845 @@ -0,0 +1,165 @@
48846 +/*
48847 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48848 + *
48849 + * Redistribution and use in source and binary forms, with or without
48850 + * modification, are permitted provided that the following conditions are met:
48851 + * * Redistributions of source code must retain the above copyright
48852 + * notice, this list of conditions and the following disclaimer.
48853 + * * Redistributions in binary form must reproduce the above copyright
48854 + * notice, this list of conditions and the following disclaimer in the
48855 + * documentation and/or other materials provided with the distribution.
48856 + * * Neither the name of Freescale Semiconductor nor the
48857 + * names of its contributors may be used to endorse or promote products
48858 + * derived from this software without specific prior written permission.
48859 + *
48860 + *
48861 + * ALTERNATIVELY, this software may be distributed under the terms of the
48862 + * GNU General Public License ("GPL") as published by the Free Software
48863 + * Foundation, either version 2 of that License or (at your option) any
48864 + * later version.
48865 + *
48866 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48867 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48868 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48869 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48870 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48871 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48872 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48873 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48874 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48875 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48876 + */
48877 +
48878 +
48879 +/******************************************************************************
48880 + @File fm_plcr.h
48881 +
48882 + @Description FM Policer private header
48883 +*//***************************************************************************/
48884 +#ifndef __FM_PLCR_H
48885 +#define __FM_PLCR_H
48886 +
48887 +#include "std_ext.h"
48888 +
48889 +
48890 +/***********************************************************************/
48891 +/* Policer defines */
48892 +/***********************************************************************/
48893 +
48894 +#define FM_PCD_PLCR_PAR_GO 0x80000000
48895 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
48896 +#define FM_PCD_PLCR_PAR_R 0x40000000
48897 +
48898 +/* shifts */
48899 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
48900 +
48901 +/* masks */
48902 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
48903 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
48904 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
48905 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
48906 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
48907 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
48908 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
48909 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
48910 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
48911 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
48912 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
48913 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
48914 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
48915 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
48916 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
48917 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
48918 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
48919 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
48920 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
48921 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
48922 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
48923 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
48924 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
48925 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
48926 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
48927 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
48928 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
48929 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
48930 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
48931 +
48932 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
48933 +
48934 +#define FM_PCD_PLCR_GCR_EN 0x80000000
48935 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
48936 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
48937 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
48938 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
48939 +
48940 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
48941 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
48942 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
48943 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
48944 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
48945 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
48946 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
48947 +
48948 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
48949 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
48950 +
48951 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
48952 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
48953 +/* PWSEL Selctive select options */
48954 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
48955 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
48956 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
48957 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
48958 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
48959 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
48960 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
48961 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
48962 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
48963 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
48964 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
48965 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
48966 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
48967 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
48968 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
48969 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
48970 +
48971 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
48972 + 1-> 2^N specific locations. */
48973 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
48974 + 2-> 2^(N-1) base locations. */
48975 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
48976 + 4-> 2^(N-2) base locations. */
48977 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
48978 + 8->2^(N-3) base locations. */
48979 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
48980 + 16-> 2^(N-4) base locations. */
48981 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
48982 + 32-> 2^(N-5) base locations. */
48983 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
48984 + 64-> 2^(N-6) base locations. */
48985 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
48986 + 128-> 2^(N-7) base locations. */
48987 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
48988 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
48989 +
48990 +#define FM_PCD_PLCR_PMR_V 0x80000000
48991 +#define PLCR_ERR_ECC_CAP 0x80000000
48992 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
48993 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
48994 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
48995 +
48996 +#define PLCR_ERR_UNINIT_CAP 0x80000000
48997 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
48998 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
48999 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
49000 +
49001 +/* shifts */
49002 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
49003 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
49004 +
49005 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
49006 +
49007 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
49008 +
49009 +
49010 +#endif /* __FM_PLCR_H */
49011 --- /dev/null
49012 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
49013 @@ -0,0 +1,423 @@
49014 +/*
49015 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49016 + *
49017 + * Redistribution and use in source and binary forms, with or without
49018 + * modification, are permitted provided that the following conditions are met:
49019 + * * Redistributions of source code must retain the above copyright
49020 + * notice, this list of conditions and the following disclaimer.
49021 + * * Redistributions in binary form must reproduce the above copyright
49022 + * notice, this list of conditions and the following disclaimer in the
49023 + * documentation and/or other materials provided with the distribution.
49024 + * * Neither the name of Freescale Semiconductor nor the
49025 + * names of its contributors may be used to endorse or promote products
49026 + * derived from this software without specific prior written permission.
49027 + *
49028 + *
49029 + * ALTERNATIVELY, this software may be distributed under the terms of the
49030 + * GNU General Public License ("GPL") as published by the Free Software
49031 + * Foundation, either version 2 of that License or (at your option) any
49032 + * later version.
49033 + *
49034 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49035 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49036 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49037 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49038 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49039 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49040 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49041 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49042 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49043 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49044 + */
49045 +
49046 +
49047 +/******************************************************************************
49048 + @File fm_pcd.c
49049 +
49050 + @Description FM PCD ...
49051 +*//***************************************************************************/
49052 +#include <linux/math64.h>
49053 +#include "std_ext.h"
49054 +#include "error_ext.h"
49055 +#include "string_ext.h"
49056 +#include "debug_ext.h"
49057 +#include "net_ext.h"
49058 +
49059 +#include "fm_common.h"
49060 +#include "fm_pcd.h"
49061 +#include "fm_pcd_ipc.h"
49062 +#include "fm_prs.h"
49063 +#include "fsl_fman_prs.h"
49064 +
49065 +
49066 +static void PcdPrsErrorException(t_Handle h_FmPcd)
49067 +{
49068 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49069 + uint32_t event, ev_mask;
49070 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49071 +
49072 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49073 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
49074 +
49075 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
49076 +
49077 + fman_prs_ack_err_event(PrsRegs, event);
49078 +
49079 + DBG(TRACE, ("parser error - 0x%08x\n",event));
49080 +
49081 + if(event & FM_PCD_PRS_DOUBLE_ECC)
49082 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
49083 +}
49084 +
49085 +static void PcdPrsException(t_Handle h_FmPcd)
49086 +{
49087 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49088 + uint32_t event, ev_mask;
49089 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49090 +
49091 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49092 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
49093 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
49094 +
49095 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
49096 +
49097 + DBG(TRACE, ("parser event - 0x%08x\n",event));
49098 +
49099 + fman_prs_ack_expt_event(PrsRegs, event);
49100 +
49101 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
49102 +}
49103 +
49104 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
49105 +{
49106 + t_FmPcdPrs *p_FmPcdPrs;
49107 + uintptr_t baseAddr;
49108 +
49109 + UNUSED(p_FmPcd);
49110 + UNUSED(p_FmPcdParams);
49111 +
49112 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
49113 + if (!p_FmPcdPrs)
49114 + {
49115 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
49116 + return NULL;
49117 + }
49118 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
49119 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
49120 +
49121 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
49122 + {
49123 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
49124 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
49125 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
49126 + }
49127 +
49128 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
49129 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
49130 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
49131 +
49132 + return p_FmPcdPrs;
49133 +}
49134 +
49135 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49136 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
49137 +#else
49138 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
49139 +#endif /* FM_CAPWAP_SUPPORT */
49140 +
49141 +t_Error PrsInit(t_FmPcd *p_FmPcd)
49142 +{
49143 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
49144 + uint32_t *p_TmpCode;
49145 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
49146 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
49147 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49148 + uint32_t i;
49149 +
49150 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
49151 +
49152 + /* nothing to do in guest-partition */
49153 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49154 + return E_OK;
49155 +
49156 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
49157 + if (!p_TmpCode)
49158 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49159 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
49160 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
49161 +
49162 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
49163 +
49164 + /* register even if no interrupts enabled, to allow future enablement */
49165 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
49166 +
49167 + /* register even if no interrupts enabled, to allow future enablement */
49168 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
49169 +
49170 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
49171 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49172 +
49173 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
49174 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49175 +
49176 + /* load sw parser Ip-Frag patch */
49177 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
49178 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49179 +
49180 + XX_FreeSmart(p_TmpCode);
49181 +
49182 + return E_OK;
49183 +}
49184 +
49185 +void PrsFree(t_FmPcd *p_FmPcd)
49186 +{
49187 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49188 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
49189 + /* register even if no interrupts enabled, to allow future enablement */
49190 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
49191 +}
49192 +
49193 +void PrsEnable(t_FmPcd *p_FmPcd)
49194 +{
49195 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49196 +
49197 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49198 + fman_prs_enable(PrsRegs);
49199 +}
49200 +
49201 +void PrsDisable(t_FmPcd *p_FmPcd)
49202 +{
49203 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49204 +
49205 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49206 + fman_prs_disable(PrsRegs);
49207 +}
49208 +
49209 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
49210 +{
49211 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49212 +
49213 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
49214 + return fman_prs_is_enabled(PrsRegs);
49215 +}
49216 +
49217 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
49218 +{
49219 + struct fman_prs_regs *PrsRegs;
49220 + uint32_t bitMask = 0;
49221 + uint8_t prsPortId;
49222 +
49223 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49224 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49225 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49226 +
49227 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49228 +
49229 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
49230 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
49231 +
49232 + if (include)
49233 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
49234 + else
49235 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
49236 +
49237 + fman_prs_set_stst_port_msk(PrsRegs,
49238 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
49239 +
49240 + return E_OK;
49241 +}
49242 +
49243 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
49244 +{
49245 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49246 + t_Error err;
49247 +
49248 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
49249 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49250 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49251 +
49252 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49253 + p_FmPcd->h_IpcSession)
49254 + {
49255 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
49256 + t_FmPcdIpcMsg msg;
49257 +
49258 + prsIncludePortParams.hardwarePortId = hardwarePortId;
49259 + prsIncludePortParams.include = include;
49260 + memset(&msg, 0, sizeof(msg));
49261 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
49262 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
49263 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49264 + (uint8_t*)&msg,
49265 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
49266 + NULL,
49267 + NULL,
49268 + NULL,
49269 + NULL);
49270 + if (err != E_OK)
49271 + RETURN_ERROR(MAJOR, err, NO_MSG);
49272 + return E_OK;
49273 + }
49274 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49275 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49276 + ("running in guest-mode without IPC!"));
49277 +
49278 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
49279 +}
49280 +
49281 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
49282 +{
49283 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49284 + t_FmPcdPrsLabelParams *p_Label;
49285 + int i;
49286 +
49287 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
49288 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
49289 +
49290 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49291 + p_FmPcd->h_IpcSession)
49292 + {
49293 + t_Error err = E_OK;
49294 + t_FmPcdIpcSwPrsLable labelParams;
49295 + t_FmPcdIpcMsg msg;
49296 + uint32_t prsOffset = 0;
49297 + t_FmPcdIpcReply reply;
49298 + uint32_t replyLength;
49299 +
49300 + memset(&reply, 0, sizeof(reply));
49301 + memset(&msg, 0, sizeof(msg));
49302 + labelParams.enumHdr = (uint32_t)hdr;
49303 + labelParams.indexPerHdr = indexPerHdr;
49304 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
49305 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
49306 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
49307 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49308 + (uint8_t*)&msg,
49309 + sizeof(msg.msgId) +sizeof(labelParams),
49310 + (uint8_t*)&reply,
49311 + &replyLength,
49312 + NULL,
49313 + NULL);
49314 + if (err != E_OK)
49315 + RETURN_ERROR(MAJOR, err, NO_MSG);
49316 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
49317 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
49318 +
49319 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
49320 + return prsOffset;
49321 + }
49322 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49323 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49324 + ("running in guest-mode without IPC!"));
49325 +
49326 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
49327 +
49328 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
49329 + {
49330 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
49331 +
49332 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
49333 + return p_Label->instructionOffset;
49334 + }
49335 +
49336 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
49337 + return (uint32_t)ILLEGAL_BASE;
49338 +}
49339 +
49340 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
49341 +{
49342 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49343 + struct fman_prs_regs *PrsRegs;
49344 +
49345 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49346 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
49347 +
49348 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
49349 +
49350 +
49351 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49352 + {
49353 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
49354 + return;
49355 + }
49356 +
49357 + fman_prs_set_stst(PrsRegs, enable);
49358 +}
49359 +
49360 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
49361 +{
49362 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49363 + uint32_t *p_LoadTarget;
49364 + uint32_t *p_TmpCode;
49365 + int i;
49366 +
49367 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49368 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
49369 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
49370 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
49371 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
49372 +
49373 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49374 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
49375 +
49376 + if (!p_SwPrs->override)
49377 + {
49378 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
49379 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
49380 + }
49381 + else
49382 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
49383 +
49384 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
49385 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
49386 +
49387 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
49388 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
49389 +
49390 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
49391 + if (!p_TmpCode)
49392 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
49393 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
49394 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
49395 +
49396 + /* save sw parser labels */
49397 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
49398 + p_SwPrs->labelsTable,
49399 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
49400 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
49401 +
49402 + /* load sw parser code */
49403 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
49404 +
49405 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
49406 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
49407 +
49408 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
49409 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
49410 +
49411 + /* copy data parameters */
49412 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
49413 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
49414 +
49415 + /* Clear last 4 bytes */
49416 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
49417 +
49418 + XX_FreeSmart(p_TmpCode);
49419 +
49420 + return E_OK;
49421 +}
49422 +
49423 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
49424 +{
49425 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49426 +
49427 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49428 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49429 +
49430 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
49431 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
49432 +
49433 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
49434 +
49435 + return E_OK;
49436 +}
49437 --- /dev/null
49438 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
49439 @@ -0,0 +1,316 @@
49440 +/*
49441 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49442 + *
49443 + * Redistribution and use in source and binary forms, with or without
49444 + * modification, are permitted provided that the following conditions are met:
49445 + * * Redistributions of source code must retain the above copyright
49446 + * notice, this list of conditions and the following disclaimer.
49447 + * * Redistributions in binary form must reproduce the above copyright
49448 + * notice, this list of conditions and the following disclaimer in the
49449 + * documentation and/or other materials provided with the distribution.
49450 + * * Neither the name of Freescale Semiconductor nor the
49451 + * names of its contributors may be used to endorse or promote products
49452 + * derived from this software without specific prior written permission.
49453 + *
49454 + *
49455 + * ALTERNATIVELY, this software may be distributed under the terms of the
49456 + * GNU General Public License ("GPL") as published by the Free Software
49457 + * Foundation, either version 2 of that License or (at your option) any
49458 + * later version.
49459 + *
49460 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49461 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49462 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49463 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49464 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49465 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49466 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49467 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49468 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49469 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49470 + */
49471 +
49472 +
49473 +/******************************************************************************
49474 + @File fm_prs.h
49475 +
49476 + @Description FM Parser private header
49477 + *//***************************************************************************/
49478 +#ifndef __FM_PRS_H
49479 +#define __FM_PRS_H
49480 +
49481 +#include "std_ext.h"
49482 +
49483 +/***********************************************************************/
49484 +/* SW parser IP_FRAG patch */
49485 +/***********************************************************************/
49486 +
49487 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
49488 +#define SW_PRS_UDP_LITE_PATCH \
49489 +{\
49490 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49491 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
49492 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
49493 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49494 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
49495 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49496 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
49497 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49498 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49499 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49500 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49501 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
49502 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
49503 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
49504 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49505 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49506 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
49507 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
49508 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
49509 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
49510 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
49511 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49512 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
49513 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49514 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49515 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49516 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49517 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
49518 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
49519 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
49520 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
49521 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
49522 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
49523 + 0x00,0x01,0x1B,0xFF \
49524 +}
49525 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
49526 +
49527 +#if (DPAA_VERSION == 10)
49528 +/* Version: 106.1.9 */
49529 +#define SW_PRS_OFFLOAD_PATCH \
49530 +{ \
49531 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
49532 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49533 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
49534 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
49535 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49536 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
49537 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
49538 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
49539 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
49540 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
49541 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
49542 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
49543 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
49544 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
49545 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
49546 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49547 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49548 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49549 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
49550 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49551 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
49552 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49553 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49554 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
49555 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
49556 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
49557 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
49558 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49559 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
49560 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
49561 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
49562 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
49563 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49564 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49565 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
49566 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
49567 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
49568 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
49569 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49570 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49571 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
49572 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
49573 +}
49574 +
49575 +#else
49576 +#define SW_PRS_OFFLOAD_PATCH \
49577 +{ \
49578 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
49579 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
49580 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
49581 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
49582 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
49583 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
49584 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
49585 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
49586 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
49587 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
49588 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
49589 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
49590 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
49591 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
49592 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
49593 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
49594 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
49595 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
49596 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
49597 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
49598 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
49599 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
49600 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
49601 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
49602 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
49603 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
49604 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
49605 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
49606 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
49607 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
49608 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
49609 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
49610 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
49611 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
49612 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
49613 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
49614 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
49615 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
49616 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
49617 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49618 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
49619 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
49620 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
49621 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
49622 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
49623 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
49624 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
49625 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
49626 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
49627 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
49628 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49629 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49630 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
49631 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49632 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
49633 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49634 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
49635 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49636 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49637 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
49638 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49639 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
49640 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
49641 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49642 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
49643 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49644 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
49645 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
49646 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49647 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49648 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
49649 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
49650 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
49651 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
49652 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
49653 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
49654 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
49655 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
49656 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
49657 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
49658 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
49659 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
49660 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
49661 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
49662 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
49663 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
49664 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
49665 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
49666 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
49667 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
49668 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
49669 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
49670 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
49671 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
49672 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
49673 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
49674 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
49675 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
49676 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
49677 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
49678 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
49679 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49680 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
49681 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
49682 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
49683 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
49684 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
49685 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
49686 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
49687 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
49688 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
49689 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
49690 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
49691 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
49692 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
49693 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
49694 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
49695 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
49696 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
49697 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
49698 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
49699 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
49700 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
49701 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
49702 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
49703 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
49704 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
49705 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
49706 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
49707 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
49708 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
49709 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
49710 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
49711 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
49712 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
49713 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
49714 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
49715 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
49716 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
49717 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
49718 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
49719 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
49720 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
49721 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
49722 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
49723 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
49724 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
49725 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
49726 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
49727 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
49728 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
49729 +}
49730 +#endif /* (DPAA_VERSION == 10) */
49731 +
49732 +/****************************/
49733 +/* Parser defines */
49734 +/****************************/
49735 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
49736 + the end of the SW parser area */
49737 +
49738 +/* masks */
49739 +#define PRS_ERR_CAP 0x80000000
49740 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
49741 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
49742 +#define PRS_ERR_ADDR_MASK 0x000001FF
49743 +
49744 +/* others */
49745 +#define PRS_MAX_CYCLE_LIMIT 8191
49746 +#define PRS_SW_DATA 0x00000800
49747 +#define PRS_REGS_OFFSET 0x00000840
49748 +
49749 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
49750 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
49751 +
49752 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
49753 + bitMask = 0x80000000>>prsPortId
49754 +
49755 +#endif /* __FM_PRS_H */
49756 --- /dev/null
49757 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
49758 @@ -0,0 +1,984 @@
49759 +/*
49760 + * Copyright 2008-2012 Freescale Semiconductor Inc.
49761 + *
49762 + * Redistribution and use in source and binary forms, with or without
49763 + * modification, are permitted provided that the following conditions are met:
49764 + * * Redistributions of source code must retain the above copyright
49765 + * notice, this list of conditions and the following disclaimer.
49766 + * * Redistributions in binary form must reproduce the above copyright
49767 + * notice, this list of conditions and the following disclaimer in the
49768 + * documentation and/or other materials provided with the distribution.
49769 + * * Neither the name of Freescale Semiconductor nor the
49770 + * names of its contributors may be used to endorse or promote products
49771 + * derived from this software without specific prior written permission.
49772 + *
49773 + *
49774 + * ALTERNATIVELY, this software may be distributed under the terms of the
49775 + * GNU General Public License ("GPL") as published by the Free Software
49776 + * Foundation, either version 2 of that License or (at your option) any
49777 + * later version.
49778 + *
49779 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
49780 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49781 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49782 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
49783 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49784 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
49785 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49786 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49787 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
49788 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49789 + */
49790 +
49791 +
49792 +/******************************************************************************
49793 + @File fm_replic.c
49794 +
49795 + @Description FM frame replicator
49796 +*//***************************************************************************/
49797 +#include "std_ext.h"
49798 +#include "error_ext.h"
49799 +#include "string_ext.h"
49800 +#include "debug_ext.h"
49801 +#include "fm_pcd_ext.h"
49802 +#include "fm_muram_ext.h"
49803 +#include "fm_common.h"
49804 +#include "fm_hc.h"
49805 +#include "fm_replic.h"
49806 +#include "fm_cc.h"
49807 +#include "list_ext.h"
49808 +
49809 +
49810 +/****************************************/
49811 +/* static functions */
49812 +/****************************************/
49813 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49814 + uint32_t memberIndex,
49815 + bool isAddOperation)
49816 +{
49817 + uint8_t memberPosition;
49818 + uint32_t lastMemberIndex;
49819 +
49820 + ASSERT_COND(p_ReplicGroup);
49821 +
49822 + /* the last member index is different between add and remove operation -
49823 + in case of remove - this is exactly the last member index
49824 + in case of add - this is the last member index + 1 - e.g.
49825 + if we have 4 members, the index of the actual last member is 3(because the
49826 + index starts from 0) therefore in order to add a new member as the last
49827 + member we shall use memberIndex = 4 and not 3
49828 + */
49829 + if (isAddOperation)
49830 + lastMemberIndex = p_ReplicGroup->numOfEntries;
49831 + else
49832 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
49833 +
49834 + /* last */
49835 + if (memberIndex == lastMemberIndex)
49836 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
49837 + else
49838 + {
49839 + /* first */
49840 + if (memberIndex == 0)
49841 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
49842 + else
49843 + {
49844 + /* middle */
49845 + ASSERT_COND(memberIndex < lastMemberIndex);
49846 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
49847 + }
49848 + }
49849 + return memberPosition;
49850 +}
49851 +
49852 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
49853 + t_FmPcdCcNextEngineParams *p_MemberParams)
49854 +{
49855 + t_Error err;
49856 +
49857 +
49858 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
49859 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
49860 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
49861 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
49862 +
49863 + /* check the regular parameters of the next engine */
49864 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
49865 + if (err)
49866 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
49867 +
49868 + return E_OK;
49869 +}
49870 +
49871 +static t_Error CheckParams(t_Handle h_FmPcd,
49872 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
49873 +{
49874 + int i;
49875 + t_Error err;
49876 +
49877 + /* check that max num of entries is at least 2 */
49878 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
49879 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("maxNumOfEntries in the frame replicator parameters should be 2-%d",FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
49880 +
49881 + /* check that number of entries is greater than zero */
49882 + if (!p_ReplicGroupParam->numOfEntries)
49883 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
49884 +
49885 + /* check that max num of entries is equal or greater than number of entries */
49886 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
49887 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
49888 +
49889 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
49890 + {
49891 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
49892 + if (err)
49893 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
49894 + }
49895 + return E_OK;
49896 +}
49897 +
49898 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
49899 +{
49900 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
49901 + t_List *p_Next;
49902 +
49903 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
49904 + {
49905 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
49906 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
49907 + ASSERT_COND(p_ReplicMember);
49908 + LIST_DelAndInit(p_Next);
49909 + }
49910 + return p_ReplicMember;
49911 +}
49912 +
49913 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49914 + t_FmPcdFrmReplicMember *p_ReplicMember)
49915 +{
49916 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
49917 +}
49918 +
49919 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49920 + t_FmPcdFrmReplicMember *p_CurrentMember,
49921 + t_List *p_ListHead)
49922 +{
49923 + LIST_Add(&p_CurrentMember->node, p_ListHead);
49924 +
49925 + p_ReplicGroup->numOfEntries++;
49926 +}
49927 +
49928 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49929 + t_FmPcdFrmReplicMember *p_CurrentMember)
49930 +{
49931 + ASSERT_COND(p_ReplicGroup->numOfEntries);
49932 + LIST_DelAndInit(&p_CurrentMember->node);
49933 + p_ReplicGroup->numOfEntries--;
49934 +}
49935 +
49936 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49937 + t_AdOfTypeContLookup *p_SourceTd,
49938 + t_FmPcdFrmReplicMember *p_ReplicMember)
49939 +{
49940 + t_FmPcd *p_FmPcd;
49941 +
49942 + ASSERT_COND(p_SourceTd);
49943 + ASSERT_COND(p_ReplicMember);
49944 + ASSERT_COND(p_ReplicGroup);
49945 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49946 +
49947 + /* Link the first member in the group to the source TD */
49948 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49949 +
49950 + WRITE_UINT32(p_SourceTd->matchTblPtr,
49951 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
49952 + p_FmPcd->physicalMuramBase));
49953 +}
49954 +
49955 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49956 + t_FmPcdFrmReplicMember *p_CurrentMember,
49957 + t_FmPcdFrmReplicMember *p_NextMember)
49958 +{
49959 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
49960 + t_AdOfTypeResult *p_NextReplicAd = NULL;
49961 + t_FmPcd *p_FmPcd;
49962 + uint32_t offset = 0;
49963 +
49964 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
49965 + if (p_NextMember)
49966 + {
49967 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
49968 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49969 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
49970 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
49971 + }
49972 +
49973 + /* link the current AD to point to the AD of the next member */
49974 + WRITE_UINT32(p_CurrReplicAd->res, offset);
49975 +}
49976 +
49977 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
49978 + void *p_OldDescriptor,
49979 + void *p_NewDescriptor)
49980 +{
49981 + t_Handle h_Hc;
49982 + t_Error err;
49983 + t_FmPcd *p_FmPcd;
49984 +
49985 + ASSERT_COND(p_ReplicGroup);
49986 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
49987 + ASSERT_COND(p_OldDescriptor);
49988 + ASSERT_COND(p_NewDescriptor);
49989 +
49990 + p_FmPcd = p_ReplicGroup->h_FmPcd;
49991 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
49992 + if (!h_Hc)
49993 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
49994 +
49995 + err = FmHcPcdCcDoDynamicChange(h_Hc,
49996 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
49997 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
49998 + if (err)
49999 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
50000 +
50001 + return E_OK;
50002 +}
50003 +
50004 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
50005 +{
50006 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
50007 + uint32_t tmp;
50008 +
50009 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
50010 + if (last)
50011 + /* clear the NL bit in case it's the last member in the group*/
50012 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
50013 + else
50014 + /* set the NL bit in case it's not the last member in the group */
50015 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
50016 +
50017 + /* set FR bit in the action descriptor */
50018 + tmp = GET_UINT32(p_CurrReplicAd->nia);
50019 + WRITE_UINT32(p_CurrReplicAd->nia,
50020 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
50021 +}
50022 +
50023 +static void BuildSourceTd(void *p_Ad)
50024 +{
50025 + t_AdOfTypeContLookup *p_SourceTd;
50026 +
50027 + ASSERT_COND(p_Ad);
50028 +
50029 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
50030 +
50031 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50032 +
50033 + /* initialize the source table descriptor */
50034 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
50035 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
50036 +}
50037 +
50038 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50039 + t_FmPcdFrmReplicMember *p_NextMember,
50040 + t_FmPcdFrmReplicMember *p_CurrentMember,
50041 + bool sourceDescriptor,
50042 + bool last)
50043 +{
50044 + t_FmPcd *p_FmPcd;
50045 + t_FmPcdFrmReplicMember shadowMember;
50046 + t_Error err;
50047 +
50048 + ASSERT_COND(p_ReplicGroup);
50049 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50050 +
50051 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50052 + ASSERT_COND(p_FmPcd->p_CcShadow);
50053 +
50054 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
50055 + return ERROR_CODE(E_BUSY);
50056 +
50057 + if (sourceDescriptor)
50058 + {
50059 + BuildSourceTd(p_FmPcd->p_CcShadow);
50060 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
50061 +
50062 + /* Modify the source table descriptor according to the prepared shadow descriptor */
50063 + err = ModifyDescriptor(p_ReplicGroup,
50064 + p_ReplicGroup->p_SourceTd,
50065 + p_FmPcd->p_CcShadow/* new prepared source td */);
50066 +
50067 + RELEASE_LOCK(p_FmPcd->shadowLock);
50068 + if (err)
50069 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
50070 +
50071 + }
50072 + else
50073 + {
50074 + IO2IOCpy32(p_FmPcd->p_CcShadow,
50075 + p_CurrentMember->p_MemberAd,
50076 + FM_PCD_CC_AD_ENTRY_SIZE);
50077 +
50078 + /* update the last bit in the shadow ad */
50079 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
50080 +
50081 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
50082 +
50083 + /* update the next FR member index */
50084 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
50085 +
50086 + /* Modify the next member according to the prepared shadow descriptor */
50087 + err = ModifyDescriptor(p_ReplicGroup,
50088 + p_CurrentMember->p_MemberAd,
50089 + p_FmPcd->p_CcShadow);
50090 +
50091 + RELEASE_LOCK(p_FmPcd->shadowLock);
50092 + if (err)
50093 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
50094 + }
50095 +
50096 +
50097 + return E_OK;
50098 +}
50099 +
50100 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50101 + uint16_t memberIndex)
50102 +{
50103 + int i=0;
50104 + t_List *p_Pos;
50105 + t_FmPcdFrmReplicMember *p_Member = NULL;
50106 +
50107 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
50108 + {
50109 + if (i == memberIndex)
50110 + {
50111 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
50112 + return p_Member;
50113 + }
50114 + i++;
50115 + }
50116 + return p_Member;
50117 +}
50118 +
50119 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50120 +{
50121 + t_FmPcdFrmReplicMember *p_CurrentMember;
50122 + t_Handle h_Muram;
50123 +
50124 + ASSERT_COND(p_ReplicGroup);
50125 +
50126 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50127 + ASSERT_COND(h_Muram);
50128 +
50129 + /* Initialize an internal structure of a member to add to the available members list */
50130 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
50131 + if (!p_CurrentMember)
50132 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
50133 +
50134 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
50135 +
50136 + /* Allocate the member AD */
50137 + p_CurrentMember->p_MemberAd =
50138 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
50139 + FM_PCD_CC_AD_ENTRY_SIZE,
50140 + FM_PCD_CC_AD_TABLE_ALIGN);
50141 + if (!p_CurrentMember->p_MemberAd)
50142 + {
50143 + XX_Free(p_CurrentMember);
50144 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
50145 + }
50146 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50147 +
50148 + /* Add the new member to the available members list */
50149 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
50150 +
50151 + return E_OK;
50152 +}
50153 +
50154 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50155 + t_FmPcdCcNextEngineParams *p_MemberParams,
50156 + bool last)
50157 +{
50158 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
50159 +
50160 + ASSERT_COND(p_ReplicGroup);
50161 +
50162 + /* Get an available member from the internal members list */
50163 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
50164 + if (!p_CurrentMember)
50165 + {
50166 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
50167 + return NULL;
50168 + }
50169 + p_CurrentMember->h_Manip = NULL;
50170 +
50171 + /* clear the Ad of the new member */
50172 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50173 +
50174 + INIT_LIST(&p_CurrentMember->node);
50175 +
50176 + /* Initialize the Ad of the member */
50177 + NextStepAd(p_CurrentMember->p_MemberAd,
50178 + NULL,
50179 + p_MemberParams,
50180 + p_ReplicGroup->h_FmPcd);
50181 +
50182 + /* save Manip handle (for free needs) */
50183 + if (p_MemberParams->h_Manip)
50184 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
50185 +
50186 + /* Initialize the relevant frame replicator fields in the AD */
50187 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
50188 +
50189 + return p_CurrentMember;
50190 +}
50191 +
50192 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50193 + t_FmPcdFrmReplicMember *p_Member)
50194 +{
50195 + /* Note: Can't free the member AD just returns the member to the available
50196 + member list - therefore only memset the AD */
50197 +
50198 + /* zero the AD */
50199 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
50200 +
50201 +
50202 + /* return the member to the available members list */
50203 + PutAvailableMember(p_ReplicGroup, p_Member);
50204 +}
50205 +
50206 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
50207 + uint16_t memberIndex)
50208 +{
50209 + t_FmPcd *p_FmPcd = NULL;
50210 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
50211 + t_Error err;
50212 + uint8_t memberPosition;
50213 +
50214 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50215 + ASSERT_COND(p_FmPcd);
50216 + UNUSED(p_FmPcd);
50217 +
50218 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50219 + ASSERT_COND(p_CurrentMember);
50220 +
50221 + /* determine the member position in the group */
50222 + memberPosition = GetMemberPosition(p_ReplicGroup,
50223 + memberIndex,
50224 + FALSE/*remove operation*/);
50225 +
50226 + switch (memberPosition)
50227 + {
50228 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50229 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50230 + ASSERT_COND(p_NextMember);
50231 +
50232 + /* update the source td itself by using a host command */
50233 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50234 + p_NextMember,
50235 + NULL,
50236 + TRUE/*sourceDescriptor*/,
50237 + FALSE/*last*/);
50238 + break;
50239 +
50240 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50241 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50242 + ASSERT_COND(p_PreviousMember);
50243 +
50244 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
50245 + ASSERT_COND(p_NextMember);
50246 +
50247 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50248 + p_NextMember,
50249 + p_PreviousMember,
50250 + FALSE/*sourceDescriptor*/,
50251 + FALSE/*last*/);
50252 +
50253 + break;
50254 +
50255 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50256 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50257 + ASSERT_COND(p_PreviousMember);
50258 +
50259 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
50260 + NULL,
50261 + p_PreviousMember,
50262 + FALSE/*sourceDescriptor*/,
50263 + TRUE/*last*/);
50264 + break;
50265 +
50266 + default:
50267 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
50268 + }
50269 +
50270 + if (err)
50271 + RETURN_ERROR(MAJOR, err, NO_MSG);
50272 +
50273 + if (p_CurrentMember->h_Manip)
50274 + {
50275 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50276 + p_CurrentMember->h_Manip = NULL;
50277 + }
50278 +
50279 + /* remove the member from the driver internal members list */
50280 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50281 +
50282 + /* return the member to the available members list */
50283 + FreeMember(p_ReplicGroup, p_CurrentMember);
50284 +
50285 + return E_OK;
50286 +}
50287 +
50288 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
50289 +{
50290 + int i, j;
50291 + t_Handle h_Muram;
50292 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
50293 +
50294 + if (p_ReplicGroup)
50295 + {
50296 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
50297 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50298 + ASSERT_COND(h_Muram);
50299 +
50300 + /* free the source table descriptor */
50301 + if (p_ReplicGroup->p_SourceTd)
50302 + {
50303 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
50304 + p_ReplicGroup->p_SourceTd = NULL;
50305 + }
50306 +
50307 + /* Remove all members from the members linked list (hw and sw) and
50308 + return the members to the available members list */
50309 + if (p_ReplicGroup->numOfEntries)
50310 + {
50311 + j = p_ReplicGroup->numOfEntries-1;
50312 +
50313 + /* manually removal of the member because there are no owners of
50314 + this group */
50315 + for (i=j; i>=0; i--)
50316 + {
50317 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
50318 + ASSERT_COND(p_CurrentMember);
50319 +
50320 + if (p_CurrentMember->h_Manip)
50321 + {
50322 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
50323 + p_CurrentMember->h_Manip = NULL;
50324 + }
50325 +
50326 + /* remove the member from the internal driver members list */
50327 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
50328 +
50329 + /* return the member to the available members list */
50330 + FreeMember(p_ReplicGroup, p_CurrentMember);
50331 + }
50332 + }
50333 +
50334 + /* Free members AD */
50335 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50336 + {
50337 + p_Member = GetAvailableMember(p_ReplicGroup);
50338 + ASSERT_COND(p_Member);
50339 + if (p_Member->p_MemberAd)
50340 + {
50341 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
50342 + p_Member->p_MemberAd = NULL;
50343 + }
50344 + XX_Free(p_Member);
50345 + }
50346 +
50347 + /* release the group lock */
50348 + if (p_ReplicGroup->p_Lock)
50349 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
50350 +
50351 + /* free the replicator group */
50352 + XX_Free(p_ReplicGroup);
50353 + }
50354 +}
50355 +
50356 +
50357 +/*****************************************************************************/
50358 +/* Inter-module API routines */
50359 +/*****************************************************************************/
50360 +
50361 +/* NOTE: the inter-module routines are locked by cc in case of using them */
50362 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
50363 +{
50364 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50365 + ASSERT_COND(p_ReplicGroup);
50366 +
50367 + return (p_ReplicGroup->p_SourceTd);
50368 +}
50369 +
50370 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
50371 + void *p_Ad,
50372 + t_Handle *h_AdNew)
50373 +{
50374 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50375 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
50376 + t_FmPcd *p_FmPcd;
50377 +
50378 + ASSERT_COND(p_ReplicGroup);
50379 + p_FmPcd = p_ReplicGroup->h_FmPcd;
50380 +
50381 + /* build a bypass ad */
50382 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
50383 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
50384 +
50385 + *h_AdNew = NULL;
50386 +}
50387 +
50388 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
50389 + bool add)
50390 +{
50391 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50392 + ASSERT_COND(p_ReplicGroup);
50393 +
50394 + /* update the group owner counter */
50395 + if (add)
50396 + p_ReplicGroup->owners++;
50397 + else
50398 + {
50399 + ASSERT_COND(p_ReplicGroup->owners);
50400 + p_ReplicGroup->owners--;
50401 + }
50402 +}
50403 +
50404 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
50405 +{
50406 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50407 +
50408 + ASSERT_COND(h_ReplicGroup);
50409 +
50410 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
50411 + return E_OK;
50412 +
50413 + return ERROR_CODE(E_BUSY);
50414 +}
50415 +
50416 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
50417 +{
50418 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50419 +
50420 + ASSERT_COND(h_ReplicGroup);
50421 +
50422 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
50423 +}
50424 +/*********************** End of inter-module routines ************************/
50425 +
50426 +
50427 +/****************************************/
50428 +/* API Init unit functions */
50429 +/****************************************/
50430 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
50431 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
50432 +{
50433 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
50434 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
50435 + int i;
50436 + t_Error err;
50437 + bool last = FALSE;
50438 + t_Handle h_Muram;
50439 +
50440 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50441 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
50442 +
50443 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
50444 + {
50445 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
50446 + return NULL;
50447 + }
50448 +
50449 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
50450 + if (err)
50451 + {
50452 + REPORT_ERROR(MAJOR, err, (NO_MSG));
50453 + return NULL;
50454 + }
50455 +
50456 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
50457 + if (!p_ReplicGroup)
50458 + {
50459 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
50460 + return NULL;
50461 + }
50462 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
50463 +
50464 + /* initialize lists for internal driver use */
50465 + INIT_LIST(&p_ReplicGroup->availableMembersList);
50466 + INIT_LIST(&p_ReplicGroup->membersList);
50467 +
50468 + p_ReplicGroup->h_FmPcd = h_FmPcd;
50469 +
50470 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
50471 + ASSERT_COND(h_Muram);
50472 +
50473 + /* initialize the group lock */
50474 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
50475 + if (!p_ReplicGroup->p_Lock)
50476 + {
50477 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
50478 + DeleteGroup(p_ReplicGroup);
50479 + return NULL;
50480 + }
50481 +
50482 + /* Allocate the frame replicator source table descriptor */
50483 + p_ReplicGroup->p_SourceTd =
50484 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
50485 + FM_PCD_CC_AD_ENTRY_SIZE,
50486 + FM_PCD_CC_AD_TABLE_ALIGN);
50487 + if (!p_ReplicGroup->p_SourceTd)
50488 + {
50489 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
50490 + DeleteGroup(p_ReplicGroup);
50491 + return NULL;
50492 + }
50493 +
50494 + /* update the shadow size - required for the host commands */
50495 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
50496 + FM_PCD_CC_AD_ENTRY_SIZE,
50497 + FM_PCD_CC_AD_TABLE_ALIGN);
50498 + if (err)
50499 + {
50500 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
50501 + DeleteGroup(p_ReplicGroup);
50502 + return NULL;
50503 + }
50504 +
50505 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
50506 +
50507 + /* Allocate the maximal number of members ADs and Statistics AD for the group
50508 + It prevents allocation of Muram in run-time */
50509 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
50510 + {
50511 + err = AllocMember(p_ReplicGroup);
50512 + if (err)
50513 + {
50514 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
50515 + DeleteGroup(p_ReplicGroup);
50516 + return NULL;
50517 + }
50518 + }
50519 +
50520 + /* Initialize the members linked lists:
50521 + (hw - the one that is used by the FMan controller and
50522 + sw - the one that is managed by the driver internally) */
50523 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
50524 + {
50525 + /* check if this is the last member in the group */
50526 + if (i == (p_ReplicGroupParam->numOfEntries-1))
50527 + last = TRUE;
50528 + else
50529 + last = FALSE;
50530 +
50531 + /* Initialize a new member */
50532 + p_CurrentMember = InitMember(p_ReplicGroup,
50533 + &(p_ReplicGroupParam->nextEngineParams[i]),
50534 + last);
50535 + if (!p_CurrentMember)
50536 + {
50537 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50538 + DeleteGroup(p_ReplicGroup);
50539 + return NULL;
50540 + }
50541 +
50542 + /* Build the members group - link two consecutive members in the hw linked list */
50543 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
50544 +
50545 + /* update the driver internal members list to be compatible to the hw members linked list */
50546 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
50547 +
50548 + p_NextMember = p_CurrentMember;
50549 + }
50550 +
50551 + /* initialize the source table descriptor */
50552 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
50553 +
50554 + /* link the source table descriptor to point to the first member in the group */
50555 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
50556 +
50557 + return p_ReplicGroup;
50558 +}
50559 +
50560 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
50561 +{
50562 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
50563 +
50564 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50565 +
50566 + if (p_ReplicGroup->owners)
50567 + RETURN_ERROR(MAJOR,
50568 + E_INVALID_STATE,
50569 + ("the group has owners and can't be deleted"));
50570 +
50571 + DeleteGroup(p_ReplicGroup);
50572 +
50573 + return E_OK;
50574 +}
50575 +
50576 +
50577 +/*****************************************************************************/
50578 +/* API Run-time Frame replicator Control unit functions */
50579 +/*****************************************************************************/
50580 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
50581 + uint16_t memberIndex,
50582 + t_FmPcdCcNextEngineParams *p_MemberParams)
50583 +{
50584 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50585 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
50586 + t_Error err;
50587 + uint8_t memberPosition;
50588 +
50589 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50590 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
50591 +
50592 + /* group lock */
50593 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50594 + if (GET_ERROR_TYPE(err) == E_BUSY)
50595 + return ERROR_CODE(E_BUSY);
50596 +
50597 + if (memberIndex > p_ReplicGroup->numOfEntries)
50598 + {
50599 + /* unlock */
50600 + FrmReplicGroupUnlock(p_ReplicGroup);
50601 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
50602 + ("memberIndex is greater than the members in the list"));
50603 + }
50604 +
50605 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
50606 + {
50607 + /* unlock */
50608 + FrmReplicGroupUnlock(p_ReplicGroup);
50609 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
50610 + }
50611 +
50612 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
50613 + {
50614 + /* unlock */
50615 + FrmReplicGroupUnlock(p_ReplicGroup);
50616 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
50617 + ("numOfEntries with new entry can not be larger than %d\n",
50618 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
50619 + }
50620 +
50621 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
50622 + if (err)
50623 + {
50624 + /* unlock */
50625 + FrmReplicGroupUnlock(p_ReplicGroup);
50626 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
50627 + }
50628 + /* determine the member position in the group */
50629 + memberPosition = GetMemberPosition(p_ReplicGroup,
50630 + memberIndex,
50631 + TRUE/* add operation */);
50632 +
50633 + /* Initialize a new member */
50634 + p_NewMember = InitMember(p_ReplicGroup,
50635 + p_MemberParams,
50636 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
50637 + if (!p_NewMember)
50638 + {
50639 + /* unlock */
50640 + FrmReplicGroupUnlock(p_ReplicGroup);
50641 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
50642 + }
50643 +
50644 + switch (memberPosition)
50645 + {
50646 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
50647 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50648 + ASSERT_COND(p_CurrentMember);
50649 +
50650 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50651 +
50652 + /* update the internal group source TD */
50653 + LinkSourceToMember(p_ReplicGroup,
50654 + p_ReplicGroup->p_SourceTd,
50655 + p_NewMember);
50656 +
50657 + /* add member to the internal sw member list */
50658 + AddMemberToList(p_ReplicGroup,
50659 + p_NewMember,
50660 + &p_ReplicGroup->membersList);
50661 + break;
50662 +
50663 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
50664 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
50665 + ASSERT_COND(p_CurrentMember);
50666 +
50667 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50668 + ASSERT_COND(p_PreviousMember);
50669 +
50670 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
50671 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50672 +
50673 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50674 + break;
50675 +
50676 + case FRM_REPLIC_LAST_MEMBER_INDEX:
50677 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
50678 + ASSERT_COND(p_PreviousMember);
50679 +
50680 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
50681 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
50682 +
50683 + /* add the new member to the internal sw member list */
50684 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
50685 + break;
50686 +
50687 + default:
50688 + /* unlock */
50689 + FrmReplicGroupUnlock(p_ReplicGroup);
50690 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
50691 +
50692 + }
50693 +
50694 + /* unlock */
50695 + FrmReplicGroupUnlock(p_ReplicGroup);
50696 +
50697 + return E_OK;
50698 +}
50699 +
50700 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
50701 + uint16_t memberIndex)
50702 +{
50703 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
50704 + t_Error err;
50705 +
50706 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
50707 +
50708 + /* lock */
50709 + err = FrmReplicGroupTryLock(p_ReplicGroup);
50710 + if (GET_ERROR_TYPE(err) == E_BUSY)
50711 + return ERROR_CODE(E_BUSY);
50712 +
50713 + if (memberIndex >= p_ReplicGroup->numOfEntries)
50714 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
50715 +
50716 + /* Design decision: group must contain at least one member
50717 + No possibility to remove the last member from the group */
50718 + if (p_ReplicGroup->numOfEntries == 1)
50719 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
50720 +
50721 + err = RemoveMember(p_ReplicGroup, memberIndex);
50722 +
50723 + /* unlock */
50724 + FrmReplicGroupUnlock(p_ReplicGroup);
50725 +
50726 + switch (GET_ERROR_TYPE(err))
50727 + {
50728 + case E_OK:
50729 + return E_OK;
50730 +
50731 + case E_BUSY:
50732 + DBG(TRACE, ("E_BUSY error"));
50733 + return ERROR_CODE(E_BUSY);
50734 +
50735 + default:
50736 + RETURN_ERROR(MAJOR, err, NO_MSG);
50737 + }
50738 +}
50739 +
50740 +/*********************** End of API routines ************************/
50741 +
50742 +
50743 --- /dev/null
50744 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
50745 @@ -0,0 +1,101 @@
50746 +/*
50747 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50748 + *
50749 + * Redistribution and use in source and binary forms, with or without
50750 + * modification, are permitted provided that the following conditions are met:
50751 + * * Redistributions of source code must retain the above copyright
50752 + * notice, this list of conditions and the following disclaimer.
50753 + * * Redistributions in binary form must reproduce the above copyright
50754 + * notice, this list of conditions and the following disclaimer in the
50755 + * documentation and/or other materials provided with the distribution.
50756 + * * Neither the name of Freescale Semiconductor nor the
50757 + * names of its contributors may be used to endorse or promote products
50758 + * derived from this software without specific prior written permission.
50759 + *
50760 + *
50761 + * ALTERNATIVELY, this software may be distributed under the terms of the
50762 + * GNU General Public License ("GPL") as published by the Free Software
50763 + * Foundation, either version 2 of that License or (at your option) any
50764 + * later version.
50765 + *
50766 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50767 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50768 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50769 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50770 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50771 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50772 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50773 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50774 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50775 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50776 + */
50777 +
50778 +
50779 +/******************************************************************************
50780 + @File fm_replic.h
50781 +
50782 + @Description FM frame replicator
50783 +*//***************************************************************************/
50784 +#ifndef __FM_REPLIC_H
50785 +#define __FM_REPLIC_H
50786 +
50787 +#include "std_ext.h"
50788 +#include "error_ext.h"
50789 +
50790 +
50791 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
50792 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
50793 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
50794 +#define FRM_REPLIC_FR_BIT 0x08000000
50795 +#define FRM_REPLIC_NL_BIT 0x10000000
50796 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
50797 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
50798 +
50799 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
50800 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
50801 +
50802 +#define SOURCE_TD_ITSELF_OPTION 0x01
50803 +#define SOURCE_TD_COPY_OPTION 0x02
50804 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
50805 +#define SOURCE_TD_NONE 0x04
50806 +
50807 +/*typedef enum e_SourceTdOption
50808 +{
50809 + e_SOURCE_TD_NONE = 0,
50810 + e_SOURCE_TD_ITSELF_OPTION = 1,
50811 + e_SOURCE_TD_COPY_OPTION = 2,
50812 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
50813 +} e_SourceTdOption;
50814 +*/
50815 +
50816 +typedef struct
50817 +{
50818 + volatile uint32_t type;
50819 + volatile uint32_t frGroupPointer;
50820 + volatile uint32_t operationCode;
50821 + volatile uint32_t reserved;
50822 +} t_FrmReplicGroupSourceAd;
50823 +
50824 +typedef struct t_FmPcdFrmReplicMember
50825 +{
50826 + void *p_MemberAd; /**< pointer to the member AD */
50827 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
50828 + t_Handle h_Manip; /**< manip handle - need for free routines */
50829 + t_List node;
50830 +} t_FmPcdFrmReplicMember;
50831 +
50832 +typedef struct t_FmPcdFrmReplicGroup
50833 +{
50834 + t_Handle h_FmPcd;
50835 +
50836 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
50837 + uint8_t numOfEntries; /**< actual number of members in the group */
50838 + uint16_t owners; /**< how many keys share this frame replicator group */
50839 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
50840 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
50841 + t_List availableMembersList;/**< list of all the available members in the group */
50842 + t_FmPcdLock *p_Lock;
50843 +} t_FmPcdFrmReplicGroup;
50844 +
50845 +
50846 +#endif /* __FM_REPLIC_H */
50847 --- /dev/null
50848 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
50849 @@ -0,0 +1,888 @@
50850 +/*
50851 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50852 + *
50853 + * Redistribution and use in source and binary forms, with or without
50854 + * modification, are permitted provided that the following conditions are met:
50855 + * * Redistributions of source code must retain the above copyright
50856 + * notice, this list of conditions and the following disclaimer.
50857 + * * Redistributions in binary form must reproduce the above copyright
50858 + * notice, this list of conditions and the following disclaimer in the
50859 + * documentation and/or other materials provided with the distribution.
50860 + * * Neither the name of Freescale Semiconductor nor the
50861 + * names of its contributors may be used to endorse or promote products
50862 + * derived from this software without specific prior written permission.
50863 + *
50864 + *
50865 + * ALTERNATIVELY, this software may be distributed under the terms of the
50866 + * GNU General Public License ("GPL") as published by the Free Software
50867 + * Foundation, either version 2 of that License or (at your option) any
50868 + * later version.
50869 + *
50870 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50871 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50872 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50873 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50874 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50875 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50876 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50877 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50878 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50879 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50880 + */
50881 +
50882 +#include "fsl_fman_kg.h"
50883 +
50884 +/****************************************/
50885 +/* static functions */
50886 +/****************************************/
50887 +
50888 +
50889 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
50890 +{
50891 + uint32_t rw;
50892 +
50893 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50894 +
50895 + return (uint32_t)(FM_KG_KGAR_GO |
50896 + rw |
50897 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50898 + hwport_id |
50899 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
50900 +}
50901 +
50902 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
50903 +{
50904 + uint32_t ar;
50905 +
50906 + fman_kg_write_sp(regs, 0xffffffff, 0);
50907 +
50908 + ar = build_ar_bind_scheme(hwport_id, TRUE);
50909 + fman_kg_write_ar_wait(regs, ar);
50910 +}
50911 +
50912 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
50913 +{
50914 + uint32_t rw;
50915 +
50916 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
50917 +
50918 + return (uint32_t)(FM_KG_KGAR_GO |
50919 + rw |
50920 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
50921 + hwport_id |
50922 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
50923 +}
50924 +
50925 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
50926 +{
50927 + uint32_t ar;
50928 +
50929 + fman_kg_write_cpp(regs, 0);
50930 +
50931 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
50932 + fman_kg_write_ar_wait(regs, ar);
50933 +}
50934 +
50935 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
50936 + bool no_validation,
50937 + uint8_t *offset)
50938 +{
50939 + int code;
50940 +
50941 + switch (src) {
50942 + case E_FMAN_KG_GEN_EXTRACT_ETH:
50943 + code = no_validation ? 0x73 : 0x3;
50944 + break;
50945 +
50946 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
50947 + code = no_validation ? 0x77 : 0x7;
50948 + break;
50949 +
50950 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
50951 + code = no_validation ? 0x74 : 0x4;
50952 + break;
50953 +
50954 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
50955 + code = no_validation ? 0x75 : 0x5;
50956 + break;
50957 +
50958 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
50959 + code = no_validation ? 0x76 : 0x6;
50960 + break;
50961 +
50962 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
50963 + code = no_validation ? 0x78 : 0x8;
50964 + break;
50965 +
50966 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
50967 + code = no_validation ? 0x79 : 0x9;
50968 + break;
50969 +
50970 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
50971 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
50972 + break;
50973 +
50974 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
50975 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
50976 + break;
50977 +
50978 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
50979 + code = no_validation ? 0x7a : 0xa;
50980 + break;
50981 +
50982 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
50983 + code = no_validation ? 0x7b : 0xb;
50984 + break;
50985 +
50986 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
50987 + code = no_validation ? 0x7b : 0x1b;
50988 + break;
50989 +
50990 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
50991 + code = no_validation ? 0x7c : 0xc;
50992 + break;
50993 +
50994 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
50995 + code = no_validation ? 0x7c : 0x1c;
50996 + break;
50997 +
50998 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
50999 + code = no_validation ? 0x7c : 0x2c;
51000 + break;
51001 +
51002 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
51003 + code = no_validation ? 0x72 : 0x2;
51004 + break;
51005 +
51006 + case E_FMAN_KG_GEN_EXTRACT_GRE:
51007 + code = no_validation ? 0x7d : 0xd;
51008 + break;
51009 +
51010 + case E_FMAN_KG_GEN_EXTRACT_TCP:
51011 + code = no_validation ? 0x7e : 0xe;
51012 + break;
51013 +
51014 + case E_FMAN_KG_GEN_EXTRACT_UDP:
51015 + code = no_validation ? 0x7e : 0x1e;
51016 + break;
51017 +
51018 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
51019 + code = no_validation ? 0x7e : 0x3e;
51020 + break;
51021 +
51022 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
51023 + code = no_validation ? 0x7e : 0x4e;
51024 + break;
51025 +
51026 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
51027 + code = no_validation ? 0x7e : 0x2e;
51028 + break;
51029 +
51030 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
51031 + code = no_validation ? 0x7e : 0x6e;
51032 + break;
51033 +
51034 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
51035 + code = 0x70;
51036 + break;
51037 +
51038 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
51039 + code = 0x71;
51040 + break;
51041 +
51042 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
51043 + code = 0x10;
51044 + break;
51045 +
51046 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
51047 + code = 0x40;
51048 + break;
51049 +
51050 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
51051 + code = 0x20;
51052 + break;
51053 +
51054 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
51055 + code = 0x7f;
51056 + break;
51057 +
51058 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
51059 + code = 0x20;
51060 + *offset += 0x20;
51061 + break;
51062 +
51063 + default:
51064 + code = FM_KG_SCH_GEN_HT_INVALID;
51065 + }
51066 +
51067 + return (uint8_t)code;
51068 +}
51069 +
51070 +static uint32_t build_ar_scheme(uint8_t scheme,
51071 + uint8_t hwport_id,
51072 + bool update_counter,
51073 + bool write)
51074 +{
51075 + uint32_t rw;
51076 +
51077 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
51078 +
51079 + return (uint32_t)(FM_KG_KGAR_GO |
51080 + rw |
51081 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
51082 + hwport_id |
51083 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
51084 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
51085 +}
51086 +
51087 +static uint32_t build_ar_cls_plan(uint8_t grp,
51088 + uint8_t entries_mask,
51089 + uint8_t hwport_id,
51090 + bool write)
51091 +{
51092 + uint32_t rw;
51093 +
51094 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
51095 +
51096 + return (uint32_t)(FM_KG_KGAR_GO |
51097 + rw |
51098 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
51099 + hwport_id |
51100 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
51101 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
51102 +}
51103 +
51104 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
51105 +{
51106 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
51107 + /* Wait for GO to be idle and read error */
51108 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
51109 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
51110 + return -EINVAL;
51111 + return 0;
51112 +}
51113 +
51114 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
51115 +{
51116 +
51117 + struct fman_kg_pe_regs *kgpe_regs;
51118 + uint32_t tmp;
51119 +
51120 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51121 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
51122 +
51123 + if (add)
51124 + tmp |= sp;
51125 + else /* clear */
51126 + tmp &= ~sp;
51127 +
51128 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
51129 +
51130 +}
51131 +
51132 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
51133 +{
51134 + struct fman_kg_pe_regs *kgpe_regs;
51135 +
51136 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51137 +
51138 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
51139 +}
51140 +
51141 +void fman_kg_get_event(struct fman_kg_regs *regs,
51142 + uint32_t *event,
51143 + uint32_t *scheme_idx)
51144 +{
51145 + uint32_t mask, force;
51146 +
51147 + *event = ioread32be(&regs->fmkg_eer);
51148 + mask = ioread32be(&regs->fmkg_eeer);
51149 + *scheme_idx = ioread32be(&regs->fmkg_seer);
51150 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
51151 +
51152 + *event &= mask;
51153 +
51154 + /* clear the forced events */
51155 + force = ioread32be(&regs->fmkg_feer);
51156 + if (force & *event)
51157 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
51158 +
51159 + iowrite32be(*event, &regs->fmkg_eer);
51160 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
51161 +}
51162 +
51163 +
51164 +void fman_kg_init(struct fman_kg_regs *regs,
51165 + uint32_t exceptions,
51166 + uint32_t dflt_nia)
51167 +{
51168 + uint32_t tmp;
51169 + int i;
51170 +
51171 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
51172 + &regs->fmkg_eer);
51173 +
51174 + tmp = 0;
51175 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
51176 + tmp |= FM_EX_KG_DOUBLE_ECC;
51177 +
51178 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
51179 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
51180 +
51181 + iowrite32be(tmp, &regs->fmkg_eeer);
51182 + iowrite32be(0, &regs->fmkg_fdor);
51183 + iowrite32be(0, &regs->fmkg_gdv0r);
51184 + iowrite32be(0, &regs->fmkg_gdv1r);
51185 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
51186 +
51187 + /* Clear binding between ports to schemes and classification plans
51188 + * so that all ports are not bound to any scheme/classification plan */
51189 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
51190 + clear_pe_all_scheme(regs, (uint8_t)i);
51191 + clear_pe_all_cls_plan(regs, (uint8_t)i);
51192 + }
51193 +}
51194 +
51195 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
51196 +{
51197 + /* enable and enable all scheme interrupts */
51198 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
51199 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
51200 +}
51201 +
51202 +void fman_kg_enable(struct fman_kg_regs *regs)
51203 +{
51204 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
51205 + &regs->fmkg_gcr);
51206 +}
51207 +
51208 +void fman_kg_disable(struct fman_kg_regs *regs)
51209 +{
51210 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
51211 + &regs->fmkg_gcr);
51212 +}
51213 +
51214 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
51215 +{
51216 + iowrite32be(offset, &regs->fmkg_fdor);
51217 +}
51218 +
51219 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
51220 + uint8_t def_id,
51221 + uint32_t val)
51222 +{
51223 + if(def_id == 0)
51224 + iowrite32be(val, &regs->fmkg_gdv0r);
51225 + else
51226 + iowrite32be(val, &regs->fmkg_gdv1r);
51227 +}
51228 +
51229 +
51230 +void fman_kg_set_exception(struct fman_kg_regs *regs,
51231 + uint32_t exception,
51232 + bool enable)
51233 +{
51234 + uint32_t tmp;
51235 +
51236 + tmp = ioread32be(&regs->fmkg_eeer);
51237 +
51238 + if (enable) {
51239 + tmp |= exception;
51240 + } else {
51241 + tmp &= ~exception;
51242 + }
51243 +
51244 + iowrite32be(tmp, &regs->fmkg_eeer);
51245 +}
51246 +
51247 +void fman_kg_get_exception(struct fman_kg_regs *regs,
51248 + uint32_t *events,
51249 + uint32_t *scheme_ids,
51250 + bool clear)
51251 +{
51252 + uint32_t mask;
51253 +
51254 + *events = ioread32be(&regs->fmkg_eer);
51255 + mask = ioread32be(&regs->fmkg_eeer);
51256 + *events &= mask;
51257 +
51258 + *scheme_ids = 0;
51259 +
51260 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
51261 + *scheme_ids = ioread32be(&regs->fmkg_seer);
51262 + mask = ioread32be(&regs->fmkg_seeer);
51263 + *scheme_ids &= mask;
51264 + }
51265 +
51266 + if (clear) {
51267 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
51268 + iowrite32be(*events, &regs->fmkg_eer);
51269 + }
51270 +}
51271 +
51272 +void fman_kg_get_capture(struct fman_kg_regs *regs,
51273 + struct fman_kg_ex_ecc_attr *ecc_attr,
51274 + bool clear)
51275 +{
51276 + uint32_t tmp;
51277 +
51278 + tmp = ioread32be(&regs->fmkg_serc);
51279 +
51280 + if (tmp & KG_FMKG_SERC_CAP) {
51281 + /* Captured data is valid */
51282 + ecc_attr->valid = TRUE;
51283 + ecc_attr->double_ecc =
51284 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
51285 + ecc_attr->single_ecc_count =
51286 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
51287 + KG_FMKG_SERC_CNT_SHIFT);
51288 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
51289 +
51290 + if (clear)
51291 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
51292 + } else {
51293 + /* No ECC error is captured */
51294 + ecc_attr->valid = FALSE;
51295 + }
51296 +}
51297 +
51298 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
51299 + struct fman_kg_scheme_regs *scheme_regs)
51300 +{
51301 + struct fman_kg_extract_params *extract_params;
51302 + struct fman_kg_gen_extract_params *gen_params;
51303 + uint32_t tmp_reg, i, select, mask, fqb;
51304 + uint8_t offset, shift, ht;
51305 +
51306 + /* Zero out all registers so no need to care about unused ones */
51307 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
51308 +
51309 + /* Mode register */
51310 + tmp_reg = fm_kg_build_nia(params->next_engine,
51311 + params->next_engine_action);
51312 + if (tmp_reg == KG_NIA_INVALID) {
51313 + return -EINVAL;
51314 + }
51315 +
51316 + if (params->next_engine == E_FMAN_PCD_PLCR) {
51317 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
51318 + }
51319 + else if (params->next_engine == E_FMAN_PCD_CC) {
51320 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
51321 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
51322 + }
51323 +
51324 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
51325 + scheme_regs->kgse_mode = tmp_reg;
51326 +
51327 + /* Match vector */
51328 + scheme_regs->kgse_mv = params->match_vector;
51329 +
51330 + extract_params = &params->extract_params;
51331 +
51332 + /* Scheme default values registers */
51333 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
51334 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
51335 +
51336 + /* Extract Known Fields Command register */
51337 + scheme_regs->kgse_ekfc = extract_params->known_fields;
51338 +
51339 + /* Entry Extract Known Default Value register */
51340 + tmp_reg = 0;
51341 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
51342 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
51343 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
51344 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
51345 + tmp_reg |= extract_params->known_fields_def.etype <<
51346 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
51347 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
51348 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
51349 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
51350 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
51351 + tmp_reg |= extract_params->known_fields_def.mpls <<
51352 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
51353 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
51354 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
51355 + tmp_reg |= extract_params->known_fields_def.ptype <<
51356 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
51357 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
51358 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
51359 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
51360 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
51361 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
51362 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
51363 + tmp_reg |= extract_params->known_fields_def.l4_port <<
51364 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
51365 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
51366 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
51367 +
51368 + scheme_regs->kgse_ekdv = tmp_reg;
51369 +
51370 + /* Generic extract registers */
51371 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
51372 + return -EINVAL;
51373 + }
51374 +
51375 + for (i = 0; i < extract_params->gen_extract_num; i++) {
51376 + gen_params = extract_params->gen_extract + i;
51377 +
51378 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
51379 + tmp_reg |= (uint32_t)gen_params->def_val <<
51380 + FMAN_KG_SCH_GEN_DEF_SHIFT;
51381 +
51382 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
51383 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
51384 + (gen_params->extract == 0)) {
51385 + return -EINVAL;
51386 + }
51387 + } else {
51388 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
51389 + }
51390 +
51391 + tmp_reg |= (uint32_t)gen_params->extract <<
51392 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
51393 + tmp_reg |= (uint32_t)gen_params->mask <<
51394 + FMAN_KG_SCH_GEN_MASK_SHIFT;
51395 +
51396 + offset = gen_params->offset;
51397 + ht = get_gen_ht_code(gen_params->src,
51398 + gen_params->no_validation,
51399 + &offset);
51400 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
51401 + tmp_reg |= offset;
51402 +
51403 + scheme_regs->kgse_gec[i] = tmp_reg;
51404 + }
51405 +
51406 + /* Masks registers */
51407 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
51408 + return -EINVAL;
51409 + }
51410 +
51411 + select = 0;
51412 + mask = 0;
51413 + fqb = 0;
51414 + for (i = 0; i < extract_params->masks_num; i++) {
51415 + /* MCSx fields */
51416 + KG_GET_MASK_SEL_SHIFT(shift, i);
51417 + if (extract_params->masks[i].is_known) {
51418 + /* Mask known field */
51419 + select |= extract_params->masks[i].field_or_gen_idx <<
51420 + shift;
51421 + } else {
51422 + /* Mask generic extract */
51423 + select |= (extract_params->masks[i].field_or_gen_idx +
51424 + FM_KG_MASK_SEL_GEN_BASE) << shift;
51425 + }
51426 +
51427 + /* MOx fields - spread between se_bmch and se_fqb registers */
51428 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
51429 + if (i < 2) {
51430 + select |= (uint32_t)extract_params->masks[i].offset <<
51431 + shift;
51432 + } else {
51433 + fqb |= (uint32_t)extract_params->masks[i].offset <<
51434 + shift;
51435 + }
51436 +
51437 + /* BMx fields */
51438 + KG_GET_MASK_SHIFT(shift, i);
51439 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
51440 + }
51441 +
51442 + /* Finish with rest of BMx fileds -
51443 + * don't mask bits for unused masks by setting
51444 + * corresponding BMx field = 0xFF */
51445 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
51446 + KG_GET_MASK_SHIFT(shift, i);
51447 + mask |= 0xFF << shift;
51448 + }
51449 +
51450 + scheme_regs->kgse_bmch = select;
51451 + scheme_regs->kgse_bmcl = mask;
51452 +
51453 + /* Finish with FQB register initialization.
51454 + * Check fqid is 24-bit value. */
51455 + if (params->base_fqid & ~0x00FFFFFF) {
51456 + return -EINVAL;
51457 + }
51458 +
51459 + fqb |= params->base_fqid;
51460 + scheme_regs->kgse_fqb = fqb;
51461 +
51462 + /* Hash Configuration register */
51463 + tmp_reg = 0;
51464 + if (params->hash_params.use_hash) {
51465 + /* Check hash mask is 24-bit value */
51466 + if (params->hash_params.mask & ~0x00FFFFFF) {
51467 + return -EINVAL;
51468 + }
51469 +
51470 + /* Hash function produces 64-bit value, 24 bits of that
51471 + * are used to generate fq_id and policer profile.
51472 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
51473 + */
51474 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
51475 + return -EINVAL;
51476 + }
51477 +
51478 + tmp_reg |= params->hash_params.mask;
51479 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
51480 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
51481 +
51482 + if (params->hash_params.sym) {
51483 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
51484 + }
51485 +
51486 + }
51487 +
51488 + if (params->bypass_fqid_gen) {
51489 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
51490 + }
51491 +
51492 + scheme_regs->kgse_hc = tmp_reg;
51493 +
51494 + /* Policer Profile register */
51495 + if (params->policer_params.bypass_pp_gen) {
51496 + tmp_reg = 0;
51497 + } else {
51498 + /* Lower 8 bits of 24-bits extracted from hash result
51499 + * are used for policer profile generation.
51500 + * That leaves maximum shift value = 23. */
51501 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
51502 + return -EINVAL;
51503 + }
51504 +
51505 + tmp_reg = params->policer_params.base;
51506 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51507 + FMAN_KG_SCH_PP_SH_SHIFT) &
51508 + FMAN_KG_SCH_PP_SH_MASK;
51509 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
51510 + FMAN_KG_SCH_PP_SL_SHIFT) &
51511 + FMAN_KG_SCH_PP_SL_MASK;
51512 + tmp_reg |= (uint32_t)params->policer_params.mask <<
51513 + FMAN_KG_SCH_PP_MASK_SHIFT;
51514 + }
51515 +
51516 + scheme_regs->kgse_ppc = tmp_reg;
51517 +
51518 + /* Coarse Classification Bit Select register */
51519 + if (params->next_engine == E_FMAN_PCD_CC) {
51520 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
51521 + }
51522 +
51523 + /* Packets Counter register */
51524 + if (params->update_counter) {
51525 + scheme_regs->kgse_spc = params->counter_value;
51526 + }
51527 +
51528 + return 0;
51529 +}
51530 +
51531 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
51532 + uint8_t scheme_id,
51533 + uint8_t hwport_id,
51534 + struct fman_kg_scheme_regs *scheme_regs,
51535 + bool update_counter)
51536 +{
51537 + struct fman_kg_scheme_regs *kgse_regs;
51538 + uint32_t tmp_reg;
51539 + int err, i;
51540 +
51541 + /* Write indirect scheme registers */
51542 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51543 +
51544 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
51545 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
51546 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
51547 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
51548 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
51549 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
51550 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
51551 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
51552 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
51553 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
51554 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
51555 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
51556 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
51557 +
51558 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
51559 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
51560 +
51561 + /* Write AR (Action register) */
51562 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
51563 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51564 + return err;
51565 +}
51566 +
51567 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
51568 + uint8_t scheme_id,
51569 + uint8_t hwport_id)
51570 +{
51571 + struct fman_kg_scheme_regs *kgse_regs;
51572 + uint32_t tmp_reg;
51573 + int err, i;
51574 +
51575 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51576 +
51577 + /* Clear all registers including enable bit in mode register */
51578 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
51579 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
51580 + }
51581 +
51582 + /* Write AR (Action register) */
51583 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
51584 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51585 + return err;
51586 +}
51587 +
51588 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
51589 + uint8_t scheme_id,
51590 + uint8_t hwport_id,
51591 + uint32_t *counter)
51592 +{
51593 + struct fman_kg_scheme_regs *kgse_regs;
51594 + uint32_t tmp_reg;
51595 + int err;
51596 +
51597 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51598 +
51599 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51600 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51601 +
51602 + if (err != 0)
51603 + return err;
51604 +
51605 + *counter = ioread32be(&kgse_regs->kgse_spc);
51606 +
51607 + return 0;
51608 +}
51609 +
51610 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
51611 + uint8_t scheme_id,
51612 + uint8_t hwport_id,
51613 + uint32_t counter)
51614 +{
51615 + struct fman_kg_scheme_regs *kgse_regs;
51616 + uint32_t tmp_reg;
51617 + int err;
51618 +
51619 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
51620 +
51621 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
51622 +
51623 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51624 + if (err != 0)
51625 + return err;
51626 +
51627 + /* Keygen indirect access memory contains all scheme_id registers
51628 + * by now. Change only counter value. */
51629 + iowrite32be(counter, &kgse_regs->kgse_spc);
51630 +
51631 + /* Write back scheme registers */
51632 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
51633 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51634 +
51635 + return err;
51636 +}
51637 +
51638 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
51639 +{
51640 + return ioread32be(&regs->fmkg_tpc);
51641 +}
51642 +
51643 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
51644 + struct fman_kg_cp_regs *cls_plan_regs)
51645 +{
51646 + uint8_t entries_set, entry_bit;
51647 + int i;
51648 +
51649 + /* Zero out all group's register */
51650 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
51651 +
51652 + /* Go over all classification entries in params->entries_mask and
51653 + * configure the corresponding cpe register */
51654 + entries_set = params->entries_mask;
51655 + for (i = 0; entries_set; i++) {
51656 + entry_bit = (uint8_t)(0x80 >> i);
51657 + if ((entry_bit & entries_set) == 0)
51658 + continue;
51659 + entries_set ^= entry_bit;
51660 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
51661 + }
51662 +
51663 + return 0;
51664 +}
51665 +
51666 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
51667 + uint8_t grp_id,
51668 + uint8_t entries_mask,
51669 + uint8_t hwport_id,
51670 + struct fman_kg_cp_regs *cls_plan_regs)
51671 +{
51672 + struct fman_kg_cp_regs *kgcpe_regs;
51673 + uint32_t tmp_reg;
51674 + int i, err;
51675 +
51676 + /* Check group index is valid and the group isn't empty */
51677 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
51678 + return -EINVAL;
51679 +
51680 + /* Write indirect classification plan registers */
51681 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
51682 +
51683 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
51684 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
51685 + }
51686 +
51687 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
51688 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51689 + return err;
51690 +}
51691 +
51692 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
51693 + uint8_t hwport_id,
51694 + uint32_t schemes)
51695 +{
51696 + struct fman_kg_pe_regs *kg_pe_regs;
51697 + uint32_t tmp_reg;
51698 + int err;
51699 +
51700 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51701 +
51702 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
51703 +
51704 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
51705 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51706 + return err;
51707 +}
51708 +
51709 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
51710 + uint8_t grp_mask,
51711 + uint32_t *bind_cls_plans)
51712 +{
51713 + /* Check grp_base and grp_mask are 5-bits values */
51714 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
51715 + return -EINVAL;
51716 +
51717 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
51718 + return 0;
51719 +}
51720 +
51721 +
51722 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
51723 + uint8_t hwport_id,
51724 + uint32_t bind_cls_plans)
51725 +{
51726 + struct fman_kg_pe_regs *kg_pe_regs;
51727 + uint32_t tmp_reg;
51728 + int err;
51729 +
51730 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
51731 +
51732 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
51733 +
51734 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
51735 + err = fman_kg_write_ar_wait(regs, tmp_reg);
51736 + return err;
51737 +}
51738 --- /dev/null
51739 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
51740 @@ -0,0 +1,129 @@
51741 +/*
51742 + * Copyright 2012 Freescale Semiconductor Inc.
51743 + *
51744 + * Redistribution and use in source and binary forms, with or without
51745 + * modification, are permitted provided that the following conditions are met:
51746 + * * Redistributions of source code must retain the above copyright
51747 + * notice, this list of conditions and the following disclaimer.
51748 + * * Redistributions in binary form must reproduce the above copyright
51749 + * notice, this list of conditions and the following disclaimer in the
51750 + * documentation and/or other materials provided with the distribution.
51751 + * * Neither the name of Freescale Semiconductor nor the
51752 + * names of its contributors may be used to endorse or promote products
51753 + * derived from this software without specific prior written permission.
51754 + *
51755 + *
51756 + * ALTERNATIVELY, this software may be distributed under the terms of the
51757 + * GNU General Public License ("GPL") as published by the Free Software
51758 + * Foundation, either version 2 of that License or (at your option) any
51759 + * later version.
51760 + *
51761 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51762 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51763 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51764 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51765 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51766 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51767 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51768 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51769 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51770 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51771 + */
51772 +
51773 +#include "fsl_fman_prs.h"
51774 +
51775 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51776 +{
51777 + return ioread32be(&regs->fmpr_perr) & ev_mask;
51778 +}
51779 +
51780 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
51781 +{
51782 + return ioread32be(&regs->fmpr_perer);
51783 +}
51784 +
51785 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
51786 +{
51787 + iowrite32be(event, &regs->fmpr_perr);
51788 +}
51789 +
51790 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
51791 +{
51792 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
51793 +}
51794 +
51795 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
51796 +{
51797 + return ioread32be(&regs->fmpr_pever);
51798 +}
51799 +
51800 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
51801 +{
51802 + iowrite32be(event, &regs->fmpr_pevr);
51803 +}
51804 +
51805 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
51806 +{
51807 + cfg->port_id_stat = 0;
51808 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
51809 + cfg->prs_exceptions = 0x03000000;
51810 +}
51811 +
51812 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
51813 +{
51814 + uint32_t tmp;
51815 +
51816 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
51817 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
51818 + &regs->fmpr_pevr);
51819 +
51820 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
51821 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
51822 + else
51823 + iowrite32be(0, &regs->fmpr_pever);
51824 +
51825 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
51826 +
51827 + tmp = 0;
51828 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
51829 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
51830 + iowrite32be(tmp, &regs->fmpr_perer);
51831 +
51832 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
51833 +
51834 + return 0;
51835 +}
51836 +
51837 +void fman_prs_enable(struct fman_prs_regs *regs)
51838 +{
51839 + uint32_t tmp;
51840 +
51841 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
51842 + iowrite32be(tmp, &regs->fmpr_rpimac);
51843 +}
51844 +
51845 +void fman_prs_disable(struct fman_prs_regs *regs)
51846 +{
51847 + uint32_t tmp;
51848 +
51849 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
51850 + iowrite32be(tmp, &regs->fmpr_rpimac);
51851 +}
51852 +
51853 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
51854 +{
51855 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
51856 +}
51857 +
51858 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
51859 +{
51860 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
51861 +}
51862 +
51863 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
51864 +{
51865 + if (enable)
51866 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
51867 + else
51868 + iowrite32be(0, &regs->fmpr_ppsc);
51869 +}
51870 --- /dev/null
51871 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
51872 @@ -0,0 +1,15 @@
51873 +#
51874 +# Makefile for the Freescale Ethernet controllers
51875 +#
51876 +ccflags-y += -DVERSION=\"\"
51877 +#
51878 +#Include netcomm SW specific definitions
51879 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
51880 +
51881 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
51882 +
51883 +ccflags-y += -I$(NCSW_FM_INC)
51884 +
51885 +obj-y += fsl-ncsw-Pcd.o
51886 +
51887 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
51888 --- /dev/null
51889 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
51890 @@ -0,0 +1,6436 @@
51891 +/*
51892 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51893 + *
51894 + * Redistribution and use in source and binary forms, with or without
51895 + * modification, are permitted provided that the following conditions are met:
51896 + * * Redistributions of source code must retain the above copyright
51897 + * notice, this list of conditions and the following disclaimer.
51898 + * * Redistributions in binary form must reproduce the above copyright
51899 + * notice, this list of conditions and the following disclaimer in the
51900 + * documentation and/or other materials provided with the distribution.
51901 + * * Neither the name of Freescale Semiconductor nor the
51902 + * names of its contributors may be used to endorse or promote products
51903 + * derived from this software without specific prior written permission.
51904 + *
51905 + *
51906 + * ALTERNATIVELY, this software may be distributed under the terms of the
51907 + * GNU General Public License ("GPL") as published by the Free Software
51908 + * Foundation, either version 2 of that License or (at your option) any
51909 + * later version.
51910 + *
51911 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51912 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51913 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51914 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51915 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51916 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51917 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51918 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51919 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51920 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51921 + */
51922 +
51923 +
51924 +/******************************************************************************
51925 + @File fm_port.c
51926 +
51927 + @Description FM driver routines implementation.
51928 + *//***************************************************************************/
51929 +#include "error_ext.h"
51930 +#include "std_ext.h"
51931 +#include "string_ext.h"
51932 +#include "sprint_ext.h"
51933 +#include "debug_ext.h"
51934 +#include "fm_muram_ext.h"
51935 +
51936 +#include "fman_common.h"
51937 +#include "fm_port.h"
51938 +#include "fm_port_dsar.h"
51939 +#include "common/general.h"
51940 +
51941 +/****************************************/
51942 +/* static functions */
51943 +/****************************************/
51944 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
51945 +
51946 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
51947 +{
51948 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
51949 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
51950 + t_Error ans = E_OK;
51951 + uint32_t unusedMask;
51952 +
51953 + if (p_FmPort->imEn)
51954 + {
51955 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
51956 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
51957 + > 2)
51958 + RETURN_ERROR(
51959 + MAJOR,
51960 + E_INVALID_VALUE,
51961 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
51962 +
51963 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
51964 + return ERROR_CODE(ans);
51965 + }
51966 + else
51967 + {
51968 + /****************************************/
51969 + /* Rx only */
51970 + /****************************************/
51971 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
51972 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
51973 + {
51974 + /* external buffer pools */
51975 + if (!p_Params->extBufPools.numOfPoolsUsed)
51976 + RETURN_ERROR(
51977 + MAJOR,
51978 + E_INVALID_VALUE,
51979 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
51980 +
51981 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
51982 + p_Params->p_BackupBmPools,
51983 + &p_Params->bufPoolDepletion) != E_OK)
51984 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
51985 +
51986 + /* Check that part of IC that needs copying is small enough to enter start margin */
51987 + if (p_Params->intContext.size
51988 + && (p_Params->intContext.size
51989 + + p_Params->intContext.extBufOffset
51990 + > p_Params->bufMargins.startMargins))
51991 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
51992 + ("intContext.size is larger than start margins"));
51993 +
51994 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
51995 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
51996 + RETURN_ERROR(
51997 + MAJOR,
51998 + E_INVALID_VALUE,
51999 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
52000 +
52001 +#ifdef FM_NO_BACKUP_POOLS
52002 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
52003 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52004 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
52005 +#endif /* FM_NO_BACKUP_POOLS */
52006 + }
52007 +
52008 + /****************************************/
52009 + /* Non Rx ports */
52010 + /****************************************/
52011 + else
52012 + {
52013 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
52014 + RETURN_ERROR(
52015 + MAJOR,
52016 + E_INVALID_VALUE,
52017 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
52018 +
52019 + /* to protect HW internal-context from overwrite */
52020 + if ((p_Params->intContext.size)
52021 + && (p_Params->intContext.intContextOffset
52022 + < MIN_TX_INT_OFFSET))
52023 + RETURN_ERROR(
52024 + MAJOR,
52025 + E_INVALID_VALUE,
52026 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
52027 +
52028 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52029 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52030 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
52031 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52032 + != DEFAULT_notSupported))
52033 + {
52034 + /* Check that not larger than 8 */
52035 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
52036 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52037 + > MAX_FIFO_PIPELINE_DEPTH))
52038 + RETURN_ERROR(
52039 + MAJOR,
52040 + E_INVALID_VALUE,
52041 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
52042 + }
52043 + }
52044 +
52045 + /****************************************/
52046 + /* Rx Or Offline Parsing */
52047 + /****************************************/
52048 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52049 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52050 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52051 + {
52052 + if (!p_Params->dfltFqid)
52053 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52054 + ("dfltFqid must be between 1 and 2^24-1"));
52055 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
52056 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
52057 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
52058 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
52059 + }
52060 +
52061 + /****************************************/
52062 + /* All ports */
52063 + /****************************************/
52064 + /* common BMI registers values */
52065 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
52066 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
52067 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52068 + ("errFqid must be between 1 and 2^24-1"));
52069 + if (p_Params->dfltFqid & ~0x00FFFFFF)
52070 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52071 + ("dfltFqid must be between 1 and 2^24-1"));
52072 + }
52073 +
52074 + /****************************************/
52075 + /* Rx only */
52076 + /****************************************/
52077 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52078 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52079 + {
52080 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
52081 + RETURN_ERROR(
52082 + MAJOR,
52083 + E_INVALID_VALUE,
52084 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
52085 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
52086 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
52087 + RETURN_ERROR(
52088 + MAJOR,
52089 + E_INVALID_VALUE,
52090 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52091 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
52092 + RETURN_ERROR(
52093 + MAJOR,
52094 + E_INVALID_VALUE,
52095 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
52096 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
52097 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
52098 + RETURN_ERROR(
52099 + MAJOR,
52100 + E_INVALID_VALUE,
52101 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52102 +
52103 + /* Check that not larger than 16 */
52104 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
52105 + RETURN_ERROR(
52106 + MAJOR,
52107 + E_INVALID_VALUE,
52108 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
52109 +
52110 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
52111 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52112 +
52113 + /* extra FIFO size (allowed only to Rx ports) */
52114 + if (p_Params->setSizeOfFifo
52115 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
52116 + RETURN_ERROR(
52117 + MAJOR,
52118 + E_INVALID_VALUE,
52119 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
52120 +
52121 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
52122 + && !p_Params->bufPoolDepletion.numOfPools)
52123 + RETURN_ERROR(
52124 + MAJOR,
52125 + E_INVALID_VALUE,
52126 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
52127 +#ifdef FM_CSI_CFED_LIMIT
52128 + if (p_FmPort->fmRevInfo.majorRev == 4)
52129 + {
52130 + /* Check that not larger than 16 */
52131 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
52132 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
52133 + }
52134 +#endif /* FM_CSI_CFED_LIMIT */
52135 + }
52136 +
52137 + /****************************************/
52138 + /* Non Rx ports */
52139 + /****************************************/
52140 + /* extra FIFO size (allowed only to Rx ports) */
52141 + else
52142 + if (p_FmPort->fifoBufs.extra)
52143 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52144 + (" No fifoBufs.extra for non Rx ports"));
52145 +
52146 + /****************************************/
52147 + /* Tx only */
52148 + /****************************************/
52149 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52150 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52151 + {
52152 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
52153 + RETURN_ERROR(
52154 + MAJOR,
52155 + E_INVALID_VALUE,
52156 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
52157 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
52158 + RETURN_ERROR(
52159 + MAJOR,
52160 + E_INVALID_VALUE,
52161 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
52162 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
52163 + RETURN_ERROR(
52164 + MAJOR,
52165 + E_INVALID_VALUE,
52166 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
52167 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
52168 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
52169 + RETURN_ERROR(
52170 + MAJOR,
52171 + E_INVALID_VALUE,
52172 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52173 +
52174 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
52175 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52176 + > 2)
52177 + RETURN_ERROR(
52178 + MAJOR, E_INVALID_VALUE,
52179 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
52180 + }
52181 +
52182 + /****************************************/
52183 + /* Non Tx Ports */
52184 + /****************************************/
52185 + /* If discard override was selected , no frames may be discarded. */
52186 + else
52187 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
52188 + RETURN_ERROR(
52189 + MAJOR,
52190 + E_CONFLICT,
52191 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
52192 +
52193 + /****************************************/
52194 + /* Rx and Offline parsing */
52195 + /****************************************/
52196 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52197 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52198 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
52199 + {
52200 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52201 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
52202 + else
52203 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
52204 +
52205 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
52206 + if (p_Params->errorsToDiscard & unusedMask)
52207 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
52208 + ("errorsToDiscard contains undefined bits"));
52209 + }
52210 +
52211 + /****************************************/
52212 + /* Offline Ports */
52213 + /****************************************/
52214 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
52215 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
52216 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52217 + && p_Params->setNumOfOpenDmas
52218 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
52219 + RETURN_ERROR(
52220 + MAJOR,
52221 + E_INVALID_VALUE,
52222 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
52223 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
52224 +
52225 + /****************************************/
52226 + /* Offline & HC Ports */
52227 + /****************************************/
52228 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52229 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52230 + {
52231 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
52232 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
52233 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
52234 + /* this is an indication that user called config for this mode which is not supported in this integration */
52235 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
52236 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
52237 +
52238 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
52239 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
52240 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
52241 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
52242 + /* this is an indication that user called config for this mode which is not supported in this integration */
52243 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
52244 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
52245 + }
52246 +
52247 + /****************************************/
52248 + /* All ports */
52249 + /****************************************/
52250 + /* Check that not larger than 16 */
52251 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
52252 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
52253 + RETURN_ERROR(
52254 + MAJOR,
52255 + E_INVALID_VALUE,
52256 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
52257 +
52258 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
52259 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52260 +
52261 + /* common BMI registers values */
52262 + if (p_Params->setNumOfTasks
52263 + && ((!p_FmPort->tasks.num)
52264 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
52265 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52266 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
52267 + if (p_Params->setNumOfTasks
52268 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
52269 + RETURN_ERROR(
52270 + MAJOR,
52271 + E_INVALID_VALUE,
52272 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
52273 + if (p_Params->setNumOfOpenDmas
52274 + && ((!p_FmPort->openDmas.num)
52275 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
52276 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52277 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
52278 + if (p_Params->setNumOfOpenDmas
52279 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
52280 + RETURN_ERROR(
52281 + MAJOR,
52282 + E_INVALID_VALUE,
52283 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
52284 + if (p_Params->setSizeOfFifo
52285 + && (!p_FmPort->fifoBufs.num
52286 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
52287 + RETURN_ERROR(
52288 + MAJOR,
52289 + E_INVALID_VALUE,
52290 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
52291 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
52292 + RETURN_ERROR(
52293 + MAJOR, E_INVALID_VALUE,
52294 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
52295 +
52296 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
52297 + if (p_FmPort->fmRevInfo.majorRev == 4)
52298 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
52299 + /* this is an indication that user called config for this mode which is not supported in this integration */
52300 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
52301 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
52302 +
52303 + return E_OK;
52304 +}
52305 +
52306 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
52307 +{
52308 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
52309 +
52310 + /*************************/
52311 + /* TX PORTS */
52312 + /*************************/
52313 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
52314 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
52315 + {
52316 + minFifoSizeRequired =
52317 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52318 + + (3 * BMI_FIFO_UNITS));
52319 + if (!p_FmPort->imEn)
52320 + minFifoSizeRequired +=
52321 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52322 + * BMI_FIFO_UNITS;
52323 +
52324 + optFifoSizeForB2B = minFifoSizeRequired;
52325 +
52326 + /* Add some margin for back-to-back capability to improve performance,
52327 + allows the hardware to pipeline new frame dma while the previous
52328 + frame not yet transmitted. */
52329 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52330 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52331 + else
52332 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
52333 + }
52334 +
52335 + /*************************/
52336 + /* RX IM PORTS */
52337 + /*************************/
52338 + else
52339 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52340 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52341 + && p_FmPort->imEn)
52342 + {
52343 + optFifoSizeForB2B =
52344 + minFifoSizeRequired =
52345 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52346 + + (4 * BMI_FIFO_UNITS));
52347 + }
52348 +
52349 + /*************************/
52350 + /* RX non-IM PORTS */
52351 + /*************************/
52352 + else
52353 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
52354 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
52355 + && !p_FmPort->imEn)
52356 + {
52357 + if (p_FmPort->fmRevInfo.majorRev == 4)
52358 + {
52359 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
52360 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
52361 + else
52362 + minFifoSizeRequired =
52363 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
52364 + + (7 * BMI_FIFO_UNITS));
52365 + }
52366 + else
52367 + {
52368 +#if (DPAA_VERSION >= 11)
52369 + minFifoSizeRequired =
52370 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52371 + + (5 * BMI_FIFO_UNITS));
52372 + /* 4 according to spec + 1 for FOF>0 */
52373 +#else
52374 + minFifoSizeRequired = (uint32_t)
52375 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
52376 + + (7*BMI_FIFO_UNITS));
52377 +#endif /* (DPAA_VERSION >= 11) */
52378 + }
52379 +
52380 + optFifoSizeForB2B = minFifoSizeRequired;
52381 +
52382 + /* Add some margin for back-to-back capability to improve performance,
52383 + allows the hardware to pipeline new frame dma while the previous
52384 + frame not yet transmitted. */
52385 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
52386 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
52387 + else
52388 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
52389 + }
52390 +
52391 + /* For O/H ports, check fifo size and update if necessary */
52392 + else
52393 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52394 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
52395 + {
52396 +#if (DPAA_VERSION >= 11)
52397 + optFifoSizeForB2B =
52398 + minFifoSizeRequired =
52399 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
52400 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
52401 + + 5) * BMI_FIFO_UNITS));
52402 + /* 4 according to spec + 1 for FOF>0 */
52403 +#else
52404 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
52405 +#endif /* (DPAA_VERSION >= 11) */
52406 + }
52407 +
52408 + ASSERT_COND(minFifoSizeRequired > 0);
52409 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
52410 +
52411 + /* Verify the size */
52412 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
52413 + DBG(INFO,
52414 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
52415 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
52416 + DBG(INFO,
52417 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
52418 +
52419 + return E_OK;
52420 +}
52421 +
52422 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
52423 +{
52424 + if (p_FmPort->p_FmPortDriverParam)
52425 + {
52426 + XX_Free(p_FmPort->p_FmPortDriverParam);
52427 + p_FmPort->p_FmPortDriverParam = NULL;
52428 + }
52429 +}
52430 +
52431 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
52432 +{
52433 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
52434 + t_FmBufPoolDepletion *p_BufPoolDepletion =
52435 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
52436 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
52437 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
52438 + int i = 0, j = 0, err;
52439 + struct fman_port_bpools bpools;
52440 +
52441 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
52442 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
52443 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
52444 +
52445 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
52446 + sizesArray);
52447 +
52448 + /* Prepare flibs bpools structure */
52449 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
52450 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
52451 + bpools.counters_enable = TRUE;
52452 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
52453 + {
52454 + bpools.bpool[i].bpid = orderedArray[i];
52455 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
52456 + /* functionality available only for some derivatives (limited by config) */
52457 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52458 + for (j = 0;
52459 + j
52460 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
52461 + j++)
52462 + if (orderedArray[i]
52463 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
52464 + {
52465 + bpools.bpool[i].is_backup = TRUE;
52466 + break;
52467 + }
52468 + }
52469 +
52470 + /* save pools parameters for later use */
52471 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
52472 + p_FmPort->rxPoolsParams.largestBufSize =
52473 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
52474 + p_FmPort->rxPoolsParams.secondLargestBufSize =
52475 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
52476 +
52477 + /* FMBM_RMPD reg. - pool depletion */
52478 + if (p_BufPoolDepletion->poolsGrpModeEnable)
52479 + {
52480 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
52481 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52482 + {
52483 + if (p_BufPoolDepletion->poolsToConsider[i])
52484 + {
52485 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52486 + {
52487 + if (i == orderedArray[j])
52488 + {
52489 + bpools.bpool[j].grp_bp_depleted = TRUE;
52490 + break;
52491 + }
52492 + }
52493 + }
52494 + }
52495 + }
52496 +
52497 + if (p_BufPoolDepletion->singlePoolModeEnable)
52498 + {
52499 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
52500 + {
52501 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
52502 + {
52503 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
52504 + {
52505 + if (i == orderedArray[j])
52506 + {
52507 + bpools.bpool[j].single_bp_depleted = TRUE;
52508 + break;
52509 + }
52510 + }
52511 + }
52512 + }
52513 + }
52514 +
52515 +#if (DPAA_VERSION >= 11)
52516 + /* fill QbbPEV */
52517 + if (p_BufPoolDepletion->poolsGrpModeEnable
52518 + || p_BufPoolDepletion->singlePoolModeEnable)
52519 + {
52520 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
52521 + {
52522 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
52523 + {
52524 + bpools.bpool[i].pfc_priorities_en = TRUE;
52525 + }
52526 + }
52527 + }
52528 +#endif /* (DPAA_VERSION >= 11) */
52529 +
52530 + /* Issue flibs function */
52531 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
52532 + if (err != 0)
52533 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
52534 +
52535 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
52536 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
52537 +
52538 + return E_OK;
52539 +}
52540 +
52541 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
52542 +{
52543 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
52544 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
52545 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
52546 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
52547 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
52548 + return E_OK;
52549 +}
52550 +
52551 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
52552 +{
52553 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
52554 + struct fman_port_params portParams;
52555 + uint32_t tmpVal;
52556 + t_Error err;
52557 +
52558 + /* Set up flibs parameters and issue init function */
52559 +
52560 + memset(&portParams, 0, sizeof(struct fman_port_params));
52561 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
52562 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
52563 + portParams.err_fqid = p_DriverParams->errFqid;
52564 + portParams.deq_sp = p_DriverParams->deqSubPortal;
52565 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
52566 + switch (p_FmPort->portType)
52567 + {
52568 + case (e_FM_PORT_TYPE_RX_10G):
52569 + case (e_FM_PORT_TYPE_RX):
52570 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
52571 + if (!p_FmPort->imEn)
52572 + {
52573 + if (p_DriverParams->forwardReuseIntContext)
52574 + p_DriverParams->dfltCfg.rx_fd_bits =
52575 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
52576 + }
52577 + break;
52578 +
52579 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52580 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
52581 + break;
52582 + break;
52583 +
52584 + default:
52585 + break;
52586 + }
52587 +
52588 + tmpVal =
52589 + (uint32_t)(
52590 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
52591 + / OFFSET_UNITS + 1) :
52592 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
52593 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
52594 + p_DriverParams->dfltCfg.int_buf_start_margin =
52595 + p_FmPort->internalBufferOffset;
52596 +
52597 + p_DriverParams->dfltCfg.ext_buf_start_margin =
52598 + p_DriverParams->bufMargins.startMargins;
52599 + p_DriverParams->dfltCfg.ext_buf_end_margin =
52600 + p_DriverParams->bufMargins.endMargins;
52601 +
52602 + p_DriverParams->dfltCfg.ic_ext_offset =
52603 + p_DriverParams->intContext.extBufOffset;
52604 + p_DriverParams->dfltCfg.ic_int_offset =
52605 + p_DriverParams->intContext.intContextOffset;
52606 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
52607 +
52608 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
52609 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
52610 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
52611 +
52612 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
52613 + (uint8_t)p_FmPort->tasks.num;
52614 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
52615 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
52616 + else
52617 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
52618 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
52619 + (uint8_t)p_FmPort->openDmas.num;
52620 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
52621 +
52622 + if (0
52623 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
52624 + &portParams))
52625 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
52626 +
52627 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
52628 + RETURN_ERROR(MAJOR, err, NO_MSG);
52629 + else
52630 + {
52631 + // from QMIInit
52632 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52633 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52634 + {
52635 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
52636 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52637 + FALSE);
52638 + else
52639 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
52640 + TRUE);
52641 + }
52642 + }
52643 + /* The code bellow is a trick so the FM will not release the buffer
52644 + to BM nor will try to enqueue the frame to QM */
52645 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
52646 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
52647 + {
52648 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
52649 + {
52650 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
52651 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
52652 + * buffers to BM regardless of fmbm_tfene
52653 + */
52654 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
52655 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
52656 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
52657 + }
52658 + }
52659 +
52660 + return E_OK;
52661 +}
52662 +
52663 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52664 +{
52665 + UNUSED(p_FmPort);
52666 +
52667 + switch (counter)
52668 + {
52669 + case (e_FM_PORT_COUNTERS_CYCLE):
52670 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52671 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52672 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52673 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52674 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52675 + case (e_FM_PORT_COUNTERS_FRAME):
52676 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52677 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52678 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52679 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52680 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52681 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52682 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52683 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
52684 + return TRUE;
52685 + default:
52686 + return FALSE;
52687 + }
52688 +}
52689 +
52690 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52691 +{
52692 + UNUSED(p_FmPort);
52693 +
52694 + switch (counter)
52695 + {
52696 + case (e_FM_PORT_COUNTERS_CYCLE):
52697 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52698 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52699 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52700 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52701 + case (e_FM_PORT_COUNTERS_FRAME):
52702 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52703 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52704 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52705 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52706 + return TRUE;
52707 + default:
52708 + return FALSE;
52709 + }
52710 +}
52711 +
52712 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
52713 +{
52714 + switch (counter)
52715 + {
52716 + case (e_FM_PORT_COUNTERS_CYCLE):
52717 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52718 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52719 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52720 + case (e_FM_PORT_COUNTERS_FRAME):
52721 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52722 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52723 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52724 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52725 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52726 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52727 + return TRUE;
52728 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52729 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
52730 + return FALSE;
52731 + else
52732 + return TRUE;
52733 + default:
52734 + return FALSE;
52735 + }
52736 +}
52737 +
52738 +static t_Error BmiPortCheckAndGetCounterType(
52739 + t_FmPort *p_FmPort, e_FmPortCounters counter,
52740 + enum fman_port_stats_counters *p_StatsType,
52741 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
52742 +{
52743 + volatile uint32_t *p_Reg;
52744 + bool isValid;
52745 +
52746 + switch (p_FmPort->portType)
52747 + {
52748 + case (e_FM_PORT_TYPE_RX_10G):
52749 + case (e_FM_PORT_TYPE_RX):
52750 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
52751 + isValid = CheckRxBmiCounter(p_FmPort, counter);
52752 + break;
52753 + case (e_FM_PORT_TYPE_TX_10G):
52754 + case (e_FM_PORT_TYPE_TX):
52755 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
52756 + isValid = CheckTxBmiCounter(p_FmPort, counter);
52757 + break;
52758 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
52759 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
52760 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
52761 + isValid = CheckOhBmiCounter(p_FmPort, counter);
52762 + break;
52763 + default:
52764 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
52765 + }
52766 +
52767 + if (!isValid)
52768 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52769 + ("Requested counter is not available for this port type"));
52770 +
52771 + /* check that counters are enabled */
52772 + switch (counter)
52773 + {
52774 + case (e_FM_PORT_COUNTERS_CYCLE):
52775 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52776 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52777 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52778 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52779 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52780 + /* performance counters - may be read when disabled */
52781 + *p_IsStats = FALSE;
52782 + break;
52783 + case (e_FM_PORT_COUNTERS_FRAME):
52784 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52785 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52786 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52787 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52788 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52789 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52790 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52791 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52792 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52793 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52794 + *p_IsStats = TRUE;
52795 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
52796 + RETURN_ERROR(MINOR, E_INVALID_STATE,
52797 + ("Requested counter was not enabled"));
52798 + break;
52799 + default:
52800 + break;
52801 + }
52802 +
52803 + /* Set counter */
52804 + switch (counter)
52805 + {
52806 + case (e_FM_PORT_COUNTERS_CYCLE):
52807 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
52808 + break;
52809 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
52810 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
52811 + break;
52812 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
52813 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
52814 + break;
52815 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
52816 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
52817 + break;
52818 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
52819 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
52820 + break;
52821 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
52822 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
52823 + break;
52824 + case (e_FM_PORT_COUNTERS_FRAME):
52825 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
52826 + break;
52827 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
52828 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
52829 + break;
52830 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
52831 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
52832 + break;
52833 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
52834 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
52835 + break;
52836 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
52837 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
52838 + break;
52839 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
52840 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
52841 + break;
52842 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
52843 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
52844 + break;
52845 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
52846 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
52847 + break;
52848 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
52849 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
52850 + break;
52851 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
52852 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
52853 + break;
52854 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
52855 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
52856 + break;
52857 + default:
52858 + break;
52859 + }
52860 +
52861 + return E_OK;
52862 +}
52863 +
52864 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
52865 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
52866 + uint32_t *p_SoftSeqAttachReg)
52867 +{
52868 + uint8_t hdrNum, Ipv4HdrNum;
52869 + u_FmPcdHdrPrsOpts *p_prsOpts;
52870 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
52871 +
52872 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
52873 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
52874 + RETURN_ERROR(
52875 + MAJOR, E_NOT_SUPPORTED,
52876 + ("No additional parameters for private or special headers."));
52877 +
52878 + if (p_HdrParams->errDisable)
52879 + tmpReg |= PRS_HDR_ERROR_DIS;
52880 +
52881 + /* Set parser options */
52882 + if (p_HdrParams->usePrsOpts)
52883 + {
52884 + p_prsOpts = &p_HdrParams->prsOpts;
52885 + switch (p_HdrParams->hdr)
52886 + {
52887 + case (HEADER_TYPE_MPLS):
52888 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
52889 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
52890 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
52891 + if (hdrNum == ILLEGAL_HDR_NUM)
52892 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52893 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
52894 + if (hdrNum < Ipv4HdrNum)
52895 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52896 + ("Header must be equal or higher than IPv4"));
52897 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
52898 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
52899 + break;
52900 + case (HEADER_TYPE_PPPoE):
52901 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
52902 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
52903 + break;
52904 + case (HEADER_TYPE_IPv6):
52905 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
52906 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
52907 + break;
52908 + case (HEADER_TYPE_TCP):
52909 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
52910 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
52911 + else
52912 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
52913 + break;
52914 + case (HEADER_TYPE_UDP):
52915 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
52916 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
52917 + else
52918 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
52919 + break;
52920 + default:
52921 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
52922 + }
52923 + }
52924 +
52925 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
52926 + if (p_HdrParams->swPrsEnable)
52927 + {
52928 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
52929 + p_HdrParams->indexPerHdr);
52930 + if (tmpPrsOffset == ILLEGAL_BASE)
52931 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
52932 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
52933 + }
52934 + *p_SoftSeqAttachReg = tmpReg;
52935 +
52936 + return E_OK;
52937 +}
52938 +
52939 +static uint32_t GetPortSchemeBindParams(
52940 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
52941 +{
52942 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52943 + uint32_t walking1Mask = 0x80000000, tmp;
52944 + uint8_t idx = 0;
52945 +
52946 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
52947 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
52948 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
52949 + p_SchemeBind->numOfSchemes = 0;
52950 + tmp = p_FmPort->schemesPerPortVector;
52951 + if (tmp)
52952 + {
52953 + while (tmp)
52954 + {
52955 + if (tmp & walking1Mask)
52956 + {
52957 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
52958 + p_SchemeBind->numOfSchemes++;
52959 + tmp &= ~walking1Mask;
52960 + }
52961 + walking1Mask >>= 1;
52962 + idx++;
52963 + }
52964 + }
52965 +
52966 + return tmp;
52967 +}
52968 +
52969 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
52970 +{
52971 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
52972 + volatile uint32_t *p_BmiCfgReg = NULL;
52973 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
52974 + uint32_t lcv, walking1Mask = 0x80000000;
52975 + uint8_t cnt = 0;
52976 +
52977 + ASSERT_COND(p_FmPort);
52978 + ASSERT_COND(p_FmPort->h_FmPcd);
52979 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
52980 +
52981 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
52982 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
52983 + return;
52984 +
52985 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
52986 + /* get LCV for MACSEC */
52987 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
52988 + != 0)
52989 + {
52990 + while (!(lcv & walking1Mask))
52991 + {
52992 + cnt++;
52993 + walking1Mask >>= 1;
52994 + }
52995 +
52996 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
52997 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
52998 + }
52999 +}
53000 +
53001 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
53002 +{
53003 + t_Error err = E_OK;
53004 + uint32_t tmpReg;
53005 + volatile uint32_t *p_BmiNia = NULL;
53006 + volatile uint32_t *p_BmiPrsNia = NULL;
53007 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53008 + volatile uint32_t *p_BmiInitPrsResult = NULL;
53009 + volatile uint32_t *p_BmiCcBase = NULL;
53010 + uint16_t hdrNum, L3HdrNum, greHdrNum;
53011 + int i;
53012 + bool isEmptyClsPlanGrp;
53013 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
53014 + uint16_t absoluteProfileId;
53015 + uint8_t physicalSchemeId;
53016 + uint32_t ccTreePhysOffset;
53017 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53018 + uint32_t initialSwPrs = 0;
53019 +
53020 + ASSERT_COND(p_FmPort);
53021 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53022 +
53023 + if (p_FmPort->imEn)
53024 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53025 + ("available for non-independant mode ports only"));
53026 +
53027 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53028 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53029 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53030 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53031 + ("available for Rx and offline parsing ports only"));
53032 +
53033 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
53034 +
53035 + p_FmPort->pcdEngines = 0;
53036 +
53037 + /* initialize p_FmPort->pcdEngines field in port's structure */
53038 + switch (p_PcdParams->pcdSupport)
53039 + {
53040 + case (e_FM_PORT_PCD_SUPPORT_NONE):
53041 + RETURN_ERROR(
53042 + MAJOR,
53043 + E_INVALID_STATE,
53044 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
53045 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53046 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53047 + break;
53048 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
53049 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53050 + break;
53051 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53052 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53053 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53054 + break;
53055 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53056 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53057 + p_FmPort->pcdEngines |= FM_PCD_KG;
53058 + break;
53059 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53060 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53061 + p_FmPort->pcdEngines |= FM_PCD_CC;
53062 + p_FmPort->pcdEngines |= FM_PCD_KG;
53063 + break;
53064 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53065 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53066 + p_FmPort->pcdEngines |= FM_PCD_KG;
53067 + p_FmPort->pcdEngines |= FM_PCD_CC;
53068 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53069 + break;
53070 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53071 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53072 + p_FmPort->pcdEngines |= FM_PCD_CC;
53073 + break;
53074 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53075 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53076 + p_FmPort->pcdEngines |= FM_PCD_CC;
53077 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53078 + break;
53079 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53080 + p_FmPort->pcdEngines |= FM_PCD_PRS;
53081 + p_FmPort->pcdEngines |= FM_PCD_KG;
53082 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53083 + break;
53084 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
53085 + p_FmPort->pcdEngines |= FM_PCD_CC;
53086 + break;
53087 +#ifdef FM_CAPWAP_SUPPORT
53088 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
53089 + p_FmPort->pcdEngines |= FM_PCD_CC;
53090 + p_FmPort->pcdEngines |= FM_PCD_KG;
53091 + break;
53092 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
53093 + p_FmPort->pcdEngines |= FM_PCD_CC;
53094 + p_FmPort->pcdEngines |= FM_PCD_KG;
53095 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
53096 + break;
53097 +#endif /* FM_CAPWAP_SUPPORT */
53098 +
53099 + default:
53100 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
53101 + }
53102 +
53103 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
53104 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
53105 + > FM_PCD_PRS_NUM_OF_HDRS))
53106 + RETURN_ERROR(
53107 + MAJOR,
53108 + E_INVALID_VALUE,
53109 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
53110 +
53111 + /* check that parameters exist for each and only each defined engine */
53112 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
53113 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
53114 + != !!p_PcdParams->p_KgParams)
53115 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
53116 + != !!p_PcdParams->p_CcParams))
53117 + RETURN_ERROR(
53118 + MAJOR,
53119 + E_INVALID_STATE,
53120 + ("PCD initialization structure is not consistent with pcdSupport"));
53121 +
53122 + /* get PCD registers pointers */
53123 + switch (p_FmPort->portType)
53124 + {
53125 + case (e_FM_PORT_TYPE_RX_10G):
53126 + case (e_FM_PORT_TYPE_RX):
53127 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53128 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
53129 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53130 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
53131 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
53132 + break;
53133 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53134 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53135 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
53136 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53137 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
53138 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
53139 + break;
53140 + default:
53141 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53142 + }
53143 +
53144 + /* set PCD port parameter */
53145 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53146 + {
53147 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
53148 + p_PcdParams->p_CcParams->h_CcTree,
53149 + &ccTreePhysOffset, p_FmPort);
53150 + if (err)
53151 + RETURN_ERROR(MAJOR, err, NO_MSG);
53152 +
53153 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
53154 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
53155 + }
53156 +
53157 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53158 + {
53159 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
53160 + RETURN_ERROR(
53161 + MAJOR,
53162 + E_INVALID_VALUE,
53163 + ("For ports using Keygen, at least one scheme must be bound. "));
53164 +
53165 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
53166 + p_FmPort->hardwarePortId,
53167 + p_FmPort->netEnvId,
53168 + p_FmPort->optArray,
53169 + &p_FmPort->clsPlanGrpId,
53170 + &isEmptyClsPlanGrp);
53171 + if (err)
53172 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53173 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
53174 +
53175 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
53176 +
53177 + schemeBind.netEnvId = p_FmPort->netEnvId;
53178 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
53179 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
53180 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
53181 +
53182 + /* for each scheme */
53183 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53184 + {
53185 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
53186 + physicalSchemeId = FmPcdKgGetSchemeId(
53187 + p_PcdParams->p_KgParams->h_Schemes[i]);
53188 + schemeBind.schemesIds[i] = physicalSchemeId;
53189 + /* build vector */
53190 + p_FmPort->schemesPerPortVector |= 1
53191 + << (31 - (uint32_t)physicalSchemeId);
53192 +#if (DPAA_VERSION >= 11)
53193 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
53194 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
53195 + if (!p_FmPort->vspe
53196 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
53197 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53198 + ("VSPE is not at port level"));
53199 +#endif /* (DPAA_VERSION >= 11) */
53200 + }
53201 +
53202 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53203 + if (err)
53204 + RETURN_ERROR(MAJOR, err, NO_MSG);
53205 + }
53206 +
53207 + /***************************/
53208 + /* configure NIA after BMI */
53209 + /***************************/
53210 + /* rfne may contain FDCS bits, so first we read them. */
53211 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
53212 +
53213 + /* If policer is used directly after BMI or PRS */
53214 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
53215 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
53216 + || (p_PcdParams->pcdSupport
53217 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
53218 + {
53219 + if (!p_PcdParams->p_PlcrParams->h_Profile)
53220 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53221 + ("Profile should be initialized"));
53222 +
53223 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
53224 + p_PcdParams->p_PlcrParams->h_Profile);
53225 +
53226 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
53227 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53228 + ("Private port profile not valid."));
53229 +
53230 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
53231 +
53232 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
53233 + /* update BMI HPNIA */
53234 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
53235 + else
53236 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
53237 + /* update BMI NIA */
53238 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
53239 + }
53240 +
53241 + /* if CC is used directly after BMI */
53242 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
53243 +#ifdef FM_CAPWAP_SUPPORT
53244 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
53245 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
53246 +#endif /* FM_CAPWAP_SUPPORT */
53247 + )
53248 + {
53249 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53250 + RETURN_ERROR(
53251 + MAJOR,
53252 + E_INVALID_OPERATION,
53253 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
53254 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
53255 + /* check that prs start offset == RIM[FOF] */
53256 + }
53257 +
53258 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53259 + {
53260 + ASSERT_COND(p_PcdParams->p_PrsParams);
53261 +#if (DPAA_VERSION >= 11)
53262 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
53263 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
53264 + else
53265 + {
53266 +#endif /* (DPAA_VERSION >= 11) */
53267 + /* if PRS is used it is always first */
53268 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
53269 + if (hdrNum == ILLEGAL_HDR_NUM)
53270 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
53271 +#if (DPAA_VERSION >= 11)
53272 + }
53273 +#endif /* (DPAA_VERSION >= 11) */
53274 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
53275 + /* set after parser NIA */
53276 + tmpReg = 0;
53277 + switch (p_PcdParams->pcdSupport)
53278 + {
53279 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
53280 + WRITE_UINT32(*p_BmiPrsNia,
53281 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
53282 + break;
53283 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
53284 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
53285 + tmpReg = NIA_KG_CC_EN;
53286 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
53287 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
53288 + if (p_PcdParams->p_KgParams->directScheme)
53289 + {
53290 + physicalSchemeId = FmPcdKgGetSchemeId(
53291 + p_PcdParams->p_KgParams->h_DirectScheme);
53292 + /* check that this scheme was bound to this port */
53293 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
53294 + if (p_PcdParams->p_KgParams->h_DirectScheme
53295 + == p_PcdParams->p_KgParams->h_Schemes[i])
53296 + break;
53297 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
53298 + RETURN_ERROR(
53299 + MAJOR,
53300 + E_INVALID_VALUE,
53301 + ("Direct scheme is not one of the port selected schemes."));
53302 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
53303 + }
53304 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
53305 + break;
53306 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
53307 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
53308 + WRITE_UINT32(*p_BmiPrsNia,
53309 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
53310 + break;
53311 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
53312 + break;
53313 + default:
53314 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
53315 + }
53316 +
53317 + /* set start parsing offset */
53318 + WRITE_UINT32(*p_BmiPrsStartOffset,
53319 + p_PcdParams->p_PrsParams->parsingOffset);
53320 +
53321 + /************************************/
53322 + /* Parser port parameters */
53323 + /************************************/
53324 + /* stop before configuring */
53325 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53326 + /* wait for parser to be in idle state */
53327 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53328 + ;
53329 +
53330 + /* set soft seq attachment register */
53331 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
53332 +
53333 + /* set protocol options */
53334 + for (i = 0; p_FmPort->optArray[i]; i++)
53335 + switch (p_FmPort->optArray[i])
53336 + {
53337 + case (ETH_BROADCAST):
53338 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53339 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
53340 + break;
53341 + case (ETH_MULTICAST):
53342 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
53343 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
53344 + break;
53345 + case (VLAN_STACKED):
53346 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
53347 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
53348 + break;
53349 + case (MPLS_STACKED):
53350 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53351 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
53352 + break;
53353 + case (IPV4_BROADCAST_1):
53354 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53355 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
53356 + break;
53357 + case (IPV4_MULTICAST_1):
53358 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53359 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
53360 + break;
53361 + case (IPV4_UNICAST_2):
53362 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53363 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
53364 + break;
53365 + case (IPV4_MULTICAST_BROADCAST_2):
53366 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53367 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
53368 + break;
53369 + case (IPV6_MULTICAST_1):
53370 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53371 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
53372 + break;
53373 + case (IPV6_UNICAST_2):
53374 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53375 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
53376 + break;
53377 + case (IPV6_MULTICAST_2):
53378 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53379 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
53380 + break;
53381 + }
53382 +
53383 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53384 + HEADER_TYPE_UDP_ENCAP_ESP))
53385 + {
53386 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
53387 + RETURN_ERROR(
53388 + MINOR, E_INVALID_VALUE,
53389 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
53390 +
53391 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
53392 + HEADER_TYPE_UDP;
53393 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
53394 + TRUE;
53395 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
53396 + }
53397 +
53398 + /* set MPLS default next header - HW reset workaround */
53399 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
53400 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
53401 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
53402 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
53403 +
53404 + /* for GRE, disable errors */
53405 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
53406 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
53407 +
53408 + /* For UDP remove PAD from L4 checksum calculation */
53409 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
53410 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
53411 + /* For TCP remove PAD from L4 checksum calculation */
53412 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
53413 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
53414 +
53415 + /* config additional params for specific headers */
53416 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
53417 + i++)
53418 + {
53419 + /* case for using sw parser as the initial NIA address, before
53420 + * HW parsing
53421 + */
53422 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
53423 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
53424 + {
53425 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
53426 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
53427 + if (initialSwPrs == ILLEGAL_BASE)
53428 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53429 +
53430 + /* clear parser first HXS */
53431 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
53432 + /* rewrite with soft parser start */
53433 + p_FmPort->savedBmiNia |= initialSwPrs;
53434 + continue;
53435 + }
53436 +
53437 + hdrNum =
53438 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
53439 + if (hdrNum == ILLEGAL_HDR_NUM)
53440 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53441 + if (hdrNum == NO_HDR_NUM)
53442 + RETURN_ERROR(
53443 + MAJOR, E_INVALID_VALUE,
53444 + ("Private headers may not use additional parameters"));
53445 +
53446 + err = AdditionalPrsParams(
53447 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
53448 + &tmpHxs[hdrNum]);
53449 + if (err)
53450 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53451 + }
53452 +
53453 + /* Check if ip-reassembly port - need to link sw-parser code */
53454 + if (p_FmPort->h_IpReassemblyManip)
53455 + {
53456 + /* link to sw parser code for IP Frag - only if no other code is applied. */
53457 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
53458 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53459 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
53460 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53461 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53462 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
53463 + } else {
53464 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
53465 + {
53466 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53467 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53468 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53469 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53470 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
53471 + {
53472 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53473 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53474 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
53475 + }
53476 + }
53477 +
53478 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
53479 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
53480 + HEADER_TYPE_UDP_LITE))
53481 + {
53482 + /* link to sw parser code for udp lite - only if no other code is applied. */
53483 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53484 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
53485 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
53486 + }
53487 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
53488 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
53489 + {
53490 + /* For all header set LCV as taken from netEnv*/
53491 + WRITE_UINT32(
53492 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
53493 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
53494 + /* set HXS register according to default+Additional params+protocol options */
53495 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
53496 + tmpHxs[i]);
53497 + }
53498 +
53499 + /* set tpid. */
53500 + tmpReg = PRS_TPID_DFLT;
53501 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
53502 + {
53503 + tmpReg &= PRS_TPID2_MASK;
53504 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
53505 + << PRS_PCTPID_SHIFT;
53506 + }
53507 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
53508 + {
53509 + tmpReg &= PRS_TPID1_MASK;
53510 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
53511 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
53512 +
53513 + /* enable parser */
53514 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
53515 +
53516 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
53517 + p_FmPort->privateInfo =
53518 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
53519 +
53520 + } /* end parser */
53521 + else {
53522 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
53523 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53524 + {
53525 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
53526 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
53527 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
53528 + }
53529 +
53530 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53531 +
53532 + p_FmPort->privateInfo = 0;
53533 + }
53534 +
53535 + FmPortCheckNApplyMacsec(p_FmPort);
53536 +
53537 + WRITE_UINT32(
53538 + *p_BmiPrsStartOffset,
53539 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
53540 +
53541 + /* set initial parser result - used for all engines */
53542 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
53543 + {
53544 + if (!i)
53545 + WRITE_UINT32(
53546 + *(p_BmiInitPrsResult),
53547 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
53548 + else
53549 + {
53550 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
53551 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
53552 + else
53553 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
53554 + }
53555 + }
53556 +
53557 + return E_OK;
53558 +}
53559 +
53560 +static t_Error DeletePcd(t_FmPort *p_FmPort)
53561 +{
53562 + t_Error err = E_OK;
53563 + volatile uint32_t *p_BmiNia = NULL;
53564 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53565 +
53566 + ASSERT_COND(p_FmPort);
53567 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53568 +
53569 + if (p_FmPort->imEn)
53570 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53571 + ("available for non-independant mode ports only"));
53572 +
53573 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
53574 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
53575 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53576 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53577 + ("available for Rx and offline parsing ports only"));
53578 +
53579 + if (!p_FmPort->pcdEngines)
53580 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
53581 +
53582 + /* get PCD registers pointers */
53583 + switch (p_FmPort->portType)
53584 + {
53585 + case (e_FM_PORT_TYPE_RX_10G):
53586 + case (e_FM_PORT_TYPE_RX):
53587 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53588 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
53589 + break;
53590 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53591 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53592 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
53593 + break;
53594 + default:
53595 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53596 + }
53597 +
53598 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53599 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53600 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
53601 + ("port has to be detached previousely"));
53602 +
53603 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
53604 +
53605 + /* "cut" PCD out of the port's flow - go to BMI */
53606 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
53607 +
53608 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
53609 + {
53610 + /* stop parser */
53611 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
53612 + /* wait for parser to be in idle state */
53613 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
53614 + ;
53615 + }
53616 +
53617 + if (p_FmPort->pcdEngines & FM_PCD_KG)
53618 + {
53619 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
53620 +
53621 + /* unbind all schemes */
53622 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
53623 + &schemeBind);
53624 +
53625 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
53626 + if (err)
53627 + RETURN_ERROR(MAJOR, err, NO_MSG);
53628 +
53629 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
53630 + p_FmPort->hardwarePortId,
53631 + p_FmPort->clsPlanGrpId);
53632 + if (err)
53633 + RETURN_ERROR(MAJOR, err, NO_MSG);
53634 + p_FmPort->useClsPlan = FALSE;
53635 + }
53636 +
53637 + if (p_FmPort->pcdEngines & FM_PCD_CC)
53638 + {
53639 + /* unbind - we need to get the treeId too */
53640 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
53641 + if (err)
53642 + RETURN_ERROR(MAJOR, err, NO_MSG);
53643 + }
53644 +
53645 + p_FmPort->pcdEngines = 0;
53646 +
53647 + return E_OK;
53648 +}
53649 +
53650 +static t_Error AttachPCD(t_FmPort *p_FmPort)
53651 +{
53652 + volatile uint32_t *p_BmiNia = NULL;
53653 +
53654 + ASSERT_COND(p_FmPort);
53655 +
53656 + /* get PCD registers pointers */
53657 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53658 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53659 + else
53660 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53661 +
53662 + /* check that current NIA is BMI to BMI */
53663 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
53664 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
53665 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
53666 + ("may be called only for ports in BMI-to-BMI state."));
53667 +
53668 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53669 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
53670 + p_FmPort->orFmanCtrl) != E_OK)
53671 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53672 +
53673 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
53674 + {
53675 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53676 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
53677 + p_FmPort->savedBmiCmne);
53678 + else
53679 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
53680 + p_FmPort->savedBmiCmne);
53681 + }
53682 +
53683 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53684 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
53685 + p_FmPort->savedQmiPnen);
53686 +
53687 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53688 + {
53689 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53690 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53691 + p_FmPort->savedBmiFene);
53692 + else
53693 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53694 + p_FmPort->savedBmiFene);
53695 + }
53696 +
53697 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
53698 + {
53699 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53700 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
53701 + p_FmPort->savedBmiFpne);
53702 + else
53703 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
53704 + p_FmPort->savedBmiFpne);
53705 + }
53706 +
53707 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
53708 + {
53709 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
53710 +
53711 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
53712 + p_FmPort->savedBmiOfp);
53713 + }
53714 +
53715 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
53716 +
53717 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53718 + {
53719 + p_FmPort->origNonRxQmiRegsPndn =
53720 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
53721 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53722 + p_FmPort->savedNonRxQmiRegsPndn);
53723 + }
53724 +
53725 + return E_OK;
53726 +}
53727 +
53728 +static t_Error DetachPCD(t_FmPort *p_FmPort)
53729 +{
53730 + volatile uint32_t *p_BmiNia = NULL;
53731 +
53732 + ASSERT_COND(p_FmPort);
53733 +
53734 + /* get PCD registers pointers */
53735 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
53736 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
53737 + p_FmPort->origNonRxQmiRegsPndn);
53738 +
53739 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53740 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
53741 + else
53742 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
53743 +
53744 + WRITE_UINT32(
53745 + *p_BmiNia,
53746 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
53747 +
53748 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
53749 + FmPcdHcSync(p_FmPort->h_FmPcd);
53750 +
53751 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
53752 + {
53753 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53754 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
53755 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53756 + else
53757 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
53758 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
53759 + }
53760 +
53761 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
53762 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
53763 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
53764 +
53765 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53766 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
53767 + p_FmPort->orFmanCtrl) != E_OK)
53768 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
53769 +
53770 + p_FmPort->requiredAction = 0;
53771 +
53772 + return E_OK;
53773 +}
53774 +
53775 +/*****************************************************************************/
53776 +/* Inter-module API routines */
53777 +/*****************************************************************************/
53778 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
53779 +{
53780 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53781 + volatile uint32_t *p_BmiCfgReg = NULL;
53782 + uint32_t tmpReg;
53783 +
53784 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
53785 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
53786 +
53787 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
53788 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
53789 + {
53790 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
53791 + return;
53792 + }
53793 +
53794 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
53795 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
53796 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
53797 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
53798 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
53799 +
53800 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
53801 +}
53802 +
53803 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
53804 +{
53805 + return ((t_FmPort*)h_FmPort)->netEnvId;
53806 +}
53807 +
53808 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
53809 +{
53810 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
53811 +}
53812 +
53813 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
53814 +{
53815 + return ((t_FmPort*)h_FmPort)->pcdEngines;
53816 +}
53817 +
53818 +#if (DPAA_VERSION >= 11)
53819 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
53820 + void **p_Value)
53821 +{
53822 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53823 + uint32_t muramPageOffset;
53824 +
53825 + ASSERT_COND(p_FmPort);
53826 + ASSERT_COND(p_Value);
53827 +
53828 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
53829 + {
53830 + if (p_FmPort->gprFunc != gprFunc)
53831 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53832 + ("gpr was assigned with different func"));
53833 + }
53834 + else
53835 + {
53836 + switch (gprFunc)
53837 + {
53838 + case (e_FM_PORT_GPR_MURAM_PAGE):
53839 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
53840 + 256, 8);
53841 + if (!p_FmPort->p_ParamsPage)
53842 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
53843 +
53844 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
53845 + muramPageOffset =
53846 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
53847 + - p_FmPort->fmMuramPhysBaseAddr);
53848 + switch (p_FmPort->portType)
53849 + {
53850 + case (e_FM_PORT_TYPE_RX_10G):
53851 + case (e_FM_PORT_TYPE_RX):
53852 + WRITE_UINT32(
53853 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
53854 + muramPageOffset);
53855 + break;
53856 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
53857 + WRITE_UINT32(
53858 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
53859 + muramPageOffset);
53860 + break;
53861 + default:
53862 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53863 + ("Invalid port type"));
53864 + }
53865 + break;
53866 + default:
53867 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53868 + }
53869 + p_FmPort->gprFunc = gprFunc;
53870 + }
53871 +
53872 + switch (p_FmPort->gprFunc)
53873 + {
53874 + case (e_FM_PORT_GPR_MURAM_PAGE):
53875 + *p_Value = p_FmPort->p_ParamsPage;
53876 + break;
53877 + default:
53878 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
53879 + }
53880 +
53881 + return E_OK;
53882 +}
53883 +#endif /* (DPAA_VERSION >= 11) */
53884 +
53885 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
53886 + t_FmPortGetSetCcParams *p_CcParams)
53887 +{
53888 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
53889 + int tmpInt;
53890 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
53891 +
53892 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
53893 +
53894 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
53895 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
53896 + {
53897 + p_CcParams->getCcParams.prOffset =
53898 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
53899 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
53900 + }
53901 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
53902 + {
53903 + p_CcParams->getCcParams.hardwarePortId =
53904 + (uint8_t)p_FmPort->hardwarePortId;
53905 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
53906 + }
53907 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
53908 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
53909 + {
53910 + p_CcParams->getCcParams.dataOffset =
53911 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
53912 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
53913 + }
53914 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
53915 + {
53916 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
53917 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
53918 + }
53919 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
53920 + {
53921 + p_CcParams->getCcParams.numOfExtraTasks =
53922 + (uint8_t)p_FmPort->tasks.extra;
53923 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
53924 + }
53925 + if (p_CcParams->getCcParams.type & FM_REV)
53926 + {
53927 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
53928 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
53929 + p_CcParams->getCcParams.type &= ~FM_REV;
53930 + }
53931 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
53932 + {
53933 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53934 + p_CcParams->getCcParams.discardMask =
53935 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
53936 + else
53937 + p_CcParams->getCcParams.discardMask =
53938 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
53939 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
53940 + }
53941 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
53942 + {
53943 + p_CcParams->getCcParams.internalBufferOffset =
53944 + p_FmPort->internalBufferOffset;
53945 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
53946 + }
53947 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
53948 + {
53949 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53950 + p_CcParams->getCcParams.nia =
53951 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
53952 + else
53953 + p_CcParams->getCcParams.nia =
53954 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
53955 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
53956 + }
53957 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
53958 + {
53959 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53960 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
53961 + p_CcParams->getCcParams.nia =
53962 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
53963 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
53964 + }
53965 +
53966 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
53967 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
53968 + {
53969 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
53970 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
53971 + }
53972 +
53973 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53974 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
53975 + {
53976 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
53977 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
53978 + }
53979 + else
53980 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
53981 + {
53982 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
53983 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53984 + ("PNEN was defined previously different"));
53985 + }
53986 +
53987 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53988 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
53989 + {
53990 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
53991 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
53992 + }
53993 + else
53994 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
53995 + {
53996 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
53997 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
53998 + ("PNDN was defined previously different"));
53999 + }
54000 +
54001 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
54002 + && (p_CcParams->setCcParams.overwrite
54003 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
54004 + {
54005 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
54006 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
54007 + }
54008 + else
54009 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
54010 + {
54011 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
54012 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54013 + ("xFENE was defined previously different"));
54014 + }
54015 +
54016 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
54017 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
54018 + {
54019 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
54020 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
54021 + }
54022 + else
54023 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
54024 + {
54025 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
54026 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54027 + ("xFPNE was defined previously different"));
54028 + }
54029 +
54030 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
54031 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
54032 + {
54033 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
54034 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
54035 + }
54036 + else
54037 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
54038 + {
54039 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
54040 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
54041 + ("xCMNE was defined previously different"));
54042 + }
54043 +
54044 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
54045 + && !(p_FmPort->requiredAction & UPDATE_PSO))
54046 + {
54047 + /* get PCD registers pointers */
54048 + switch (p_FmPort->portType)
54049 + {
54050 + case (e_FM_PORT_TYPE_RX_10G):
54051 + case (e_FM_PORT_TYPE_RX):
54052 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
54053 + break;
54054 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54055 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
54056 + break;
54057 + default:
54058 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54059 + }
54060 +
54061 + /* set start parsing offset */
54062 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
54063 + + p_CcParams->setCcParams.psoSize;
54064 + if (tmpInt > 0)
54065 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
54066 +
54067 + p_FmPort->requiredAction |= UPDATE_PSO;
54068 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
54069 + }
54070 + else
54071 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
54072 + {
54073 + if (p_FmPort->savedPrsStartOffset
54074 + != p_CcParams->setCcParams.psoSize)
54075 + RETURN_ERROR(
54076 + MAJOR,
54077 + E_INVALID_STATE,
54078 + ("parser start offset was defoned previousley different"));
54079 + }
54080 +
54081 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
54082 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
54083 + {
54084 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54085 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54086 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
54087 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
54088 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
54089 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
54090 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
54091 + }
54092 +
54093 + return E_OK;
54094 +}
54095 +/*********************** End of inter-module routines ************************/
54096 +
54097 +/****************************************/
54098 +/* API Init unit functions */
54099 +/****************************************/
54100 +
54101 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
54102 +{
54103 + t_FmPort *p_FmPort;
54104 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
54105 + uint32_t tmpReg;
54106 +
54107 + /* Allocate FM structure */
54108 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
54109 + if (!p_FmPort)
54110 + {
54111 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
54112 + return NULL;
54113 + }
54114 + memset(p_FmPort, 0, sizeof(t_FmPort));
54115 +
54116 + /* Allocate the FM driver's parameters structure */
54117 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
54118 + sizeof(t_FmPortDriverParam));
54119 + if (!p_FmPort->p_FmPortDriverParam)
54120 + {
54121 + XX_Free(p_FmPort);
54122 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
54123 + return NULL;
54124 + }
54125 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
54126 +
54127 + /* Initialize FM port parameters which will be kept by the driver */
54128 + p_FmPort->portType = p_FmPortParams->portType;
54129 + p_FmPort->portId = p_FmPortParams->portId;
54130 + p_FmPort->pcdEngines = FM_PCD_NONE;
54131 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
54132 + p_FmPort->h_App = p_FmPortParams->h_App;
54133 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
54134 +
54135 + /* get FM revision */
54136 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
54137 +
54138 + /* calculate global portId number */
54139 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
54140 + p_FmPortParams->portId,
54141 + p_FmPort->fmRevInfo.majorRev,
54142 + p_FmPort->fmRevInfo.minorRev);
54143 +
54144 + if (p_FmPort->fmRevInfo.majorRev >= 6)
54145 + {
54146 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54147 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54148 + DBG(WARNING,
54149 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
54150 + FM_OH_PORT_ID));
54151 +
54152 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54153 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
54154 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
54155 + }
54156 +
54157 + /* Set up FM port parameters for initialization phase only */
54158 +
54159 + /* First, fill in flibs struct */
54160 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
54161 + (enum fman_port_type)p_FmPort->portType);
54162 + /* Overwrite some integration specific parameters */
54163 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
54164 + DEFAULT_PORT_rxFifoPriElevationLevel;
54165 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
54166 + DEFAULT_PORT_rxFifoThreshold;
54167 +
54168 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
54169 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
54170 +#else
54171 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
54172 +#endif
54173 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54174 + && (p_FmPort->fmRevInfo.minorRev == 0))
54175 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
54176 + else
54177 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
54178 +
54179 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
54180 + if (p_FmPort->fmRevInfo.majorRev < 6)
54181 + {
54182 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
54183 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54184 + TRUE;
54185 +#endif
54186 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
54187 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
54188 + }
54189 + else
54190 + {
54191 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
54192 + FALSE;
54193 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
54194 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
54195 + }
54196 + if (p_FmPort->fmRevInfo.majorRev == 4)
54197 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
54198 + else
54199 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
54200 +
54201 + /* Continue with other parameters */
54202 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
54203 + /* set memory map pointers */
54204 + p_FmPort->p_FmPortQmiRegs =
54205 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
54206 + p_FmPort->p_FmPortBmiRegs =
54207 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
54208 + p_FmPort->p_FmPortPrsRegs =
54209 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
54210 +
54211 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
54212 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
54213 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
54214 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
54215 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
54216 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54217 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
54218 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
54219 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54220 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54221 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
54222 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
54223 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
54224 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
54225 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
54226 + */
54227 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
54228 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
54229 + DEFAULT_PORT_cheksumLastBytesIgnore;
54230 +
54231 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
54232 + /* resource distribution. */
54233 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
54234 + * BMI_FIFO_UNITS;
54235 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
54236 + * BMI_FIFO_UNITS;
54237 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
54238 + p_FmPort->openDmas.extra =
54239 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
54240 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
54241 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
54242 +
54243 +
54244 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
54245 + if ((p_FmPort->fmRevInfo.majorRev == 6)
54246 + && (p_FmPort->fmRevInfo.minorRev == 0)
54247 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54248 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
54249 + {
54250 + p_FmPort->openDmas.num = 16;
54251 + p_FmPort->openDmas.extra = 0;
54252 + }
54253 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
54254 +
54255 + /* Port type specific initialization: */
54256 + switch (p_FmPort->portType)
54257 + {
54258 + case (e_FM_PORT_TYPE_RX):
54259 + case (e_FM_PORT_TYPE_RX_10G):
54260 + /* Initialize FM port parameters for initialization phase only */
54261 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
54262 + DEFAULT_PORT_cutBytesFromEnd;
54263 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
54264 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
54265 + DEFAULT_PORT_frmDiscardOverride;
54266 +
54267 + tmpReg =
54268 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
54269 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
54270 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
54271 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
54272 + * BMI_FIFO_UNITS;
54273 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
54274 + & BMI_RX_FIFO_THRESHOLD_MASK)
54275 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
54276 +
54277 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
54278 + DEFAULT_PORT_BufMargins_endMargins;
54279 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54280 + DEFAULT_PORT_errorsToDiscard;
54281 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
54282 + DEFAULT_PORT_forwardIntContextReuse;
54283 +#if (DPAA_VERSION >= 11)
54284 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54285 + DEFAULT_PORT_noScatherGather;
54286 +#endif /* (DPAA_VERSION >= 11) */
54287 + break;
54288 +
54289 + case (e_FM_PORT_TYPE_TX):
54290 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
54291 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
54292 + tmpReg = 0x00001013;
54293 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
54294 + tmpReg);
54295 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
54296 + case (e_FM_PORT_TYPE_TX_10G):
54297 + tmpReg =
54298 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
54299 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
54300 + & BMI_TX_FIFO_MIN_FILL_MASK)
54301 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
54302 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54303 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54304 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54305 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
54306 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
54307 + * BMI_FIFO_UNITS;
54308 +
54309 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54310 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54311 + DEFAULT_PORT_deqPrefetchOption;
54312 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54313 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
54314 + DEFAULT_PORT_deqHighPriority_10G);
54315 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54316 + (uint16_t)(
54317 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
54318 + DEFAULT_PORT_deqByteCnt_10G);
54319 + break;
54320 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54321 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
54322 + DEFAULT_PORT_errorsToDiscard;
54323 +#if (DPAA_VERSION >= 11)
54324 + p_FmPort->p_FmPortDriverParam->noScatherGather =
54325 + DEFAULT_PORT_noScatherGather;
54326 +#endif /* (DPAA_VERSION >= 11) */
54327 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54328 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
54329 + DEFAULT_PORT_deqPrefetchOption_HC;
54330 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
54331 + DEFAULT_PORT_deqHighPriority_1G;
54332 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
54333 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
54334 + DEFAULT_PORT_deqByteCnt_1G;
54335 +
54336 + tmpReg =
54337 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
54338 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54339 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
54340 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
54341 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54342 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
54343 + {
54344 + /* Overwrite HC defaults */
54345 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54346 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
54347 + }
54348 +
54349 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
54350 + if (p_FmPort->fmRevInfo.majorRev < 6)
54351 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
54352 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
54353 +
54354 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54355 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54356 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54357 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
54358 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54359 + break;
54360 +
54361 + default:
54362 + XX_Free(p_FmPort->p_FmPortDriverParam);
54363 + XX_Free(p_FmPort);
54364 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54365 + return NULL;
54366 + }
54367 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
54368 + if (p_FmPort->fmRevInfo.majorRev == 4)
54369 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
54370 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
54371 +
54372 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
54373 +
54374 + if (p_FmPort->imEn)
54375 + {
54376 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
54377 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
54378 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
54379 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
54380 + FmPortConfigIM(p_FmPort, p_FmPortParams);
54381 + }
54382 + else
54383 + {
54384 + switch (p_FmPort->portType)
54385 + {
54386 + case (e_FM_PORT_TYPE_RX):
54387 + case (e_FM_PORT_TYPE_RX_10G):
54388 + /* Initialize FM port parameters for initialization phase only */
54389 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54390 + &p_FmPortParams->specificParams.rxParams.extBufPools,
54391 + sizeof(t_FmExtPools));
54392 + p_FmPort->p_FmPortDriverParam->errFqid =
54393 + p_FmPortParams->specificParams.rxParams.errFqid;
54394 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54395 + p_FmPortParams->specificParams.rxParams.dfltFqid;
54396 + p_FmPort->p_FmPortDriverParam->liodnOffset =
54397 + p_FmPortParams->specificParams.rxParams.liodnOffset;
54398 + break;
54399 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54400 + case (e_FM_PORT_TYPE_TX):
54401 + case (e_FM_PORT_TYPE_TX_10G):
54402 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54403 + p_FmPort->p_FmPortDriverParam->errFqid =
54404 + p_FmPortParams->specificParams.nonRxParams.errFqid;
54405 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
54406 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
54407 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
54408 + p_FmPort->p_FmPortDriverParam->dfltFqid =
54409 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
54410 + break;
54411 + default:
54412 + XX_Free(p_FmPort->p_FmPortDriverParam);
54413 + XX_Free(p_FmPort);
54414 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54415 + return NULL;
54416 + }
54417 + }
54418 +
54419 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
54420 + if (Sprint(
54421 + p_FmPort->name,
54422 + "FM-%d-port-%s-%d",
54423 + FmGetId(p_FmPort->h_Fm),
54424 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
54425 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
54426 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
54427 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
54428 + (p_FmPort->portType
54429 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
54430 + "10g-TX")))),
54431 + p_FmPort->portId) == 0)
54432 + {
54433 + XX_Free(p_FmPort->p_FmPortDriverParam);
54434 + XX_Free(p_FmPort);
54435 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54436 + return NULL;
54437 + }
54438 +
54439 + p_FmPort->h_Spinlock = XX_InitSpinlock();
54440 + if (!p_FmPort->h_Spinlock)
54441 + {
54442 + XX_Free(p_FmPort->p_FmPortDriverParam);
54443 + XX_Free(p_FmPort);
54444 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
54445 + return NULL;
54446 + }
54447 +
54448 + return p_FmPort;
54449 +}
54450 +
54451 +t_FmPort *rx_port = 0;
54452 +t_FmPort *tx_port = 0;
54453 +
54454 +/**************************************************************************//**
54455 + @Function FM_PORT_Init
54456 +
54457 + @Description Initializes the FM module
54458 +
54459 + @Param[in] h_FmPort - FM module descriptor
54460 +
54461 + @Return E_OK on success; Error code otherwise.
54462 + *//***************************************************************************/
54463 +t_Error FM_PORT_Init(t_Handle h_FmPort)
54464 +{
54465 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54466 + t_FmPortDriverParam *p_DriverParams;
54467 + t_Error errCode;
54468 + t_FmInterModulePortInitParams fmParams;
54469 + t_FmRevisionInfo revInfo;
54470 +
54471 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
54472 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54473 +
54474 + errCode = FmSpBuildBufferStructure(
54475 + &p_FmPort->p_FmPortDriverParam->intContext,
54476 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54477 + &p_FmPort->p_FmPortDriverParam->bufMargins,
54478 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
54479 + if (errCode != E_OK)
54480 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54481 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
54482 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
54483 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54484 + {
54485 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
54486 + if (!p_FmPort->fifoBufs.num)
54487 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
54488 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
54489 + }
54490 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
54491 +
54492 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
54493 +
54494 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
54495 +
54496 + /* Set up flibs port structure */
54497 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
54498 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
54499 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54500 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
54501 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
54502 + p_FmPort->port.bmi_regs =
54503 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
54504 + p_FmPort->port.qmi_regs =
54505 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
54506 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
54507 + p_FmPort->port.im_en = p_FmPort->imEn;
54508 + p_FmPort->p_FmPortPrsRegs =
54509 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
54510 +
54511 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54512 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
54513 + {
54514 + /* Call the external Buffer routine which also checks fifo
54515 + size and updates it if necessary */
54516 + /* define external buffer pools and pool depletion*/
54517 + errCode = SetExtBufferPools(p_FmPort);
54518 + if (errCode)
54519 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54520 + /* check if the largest external buffer pool is large enough */
54521 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
54522 + + p_DriverParams->bufMargins.endMargins
54523 + > p_FmPort->rxPoolsParams.largestBufSize)
54524 + RETURN_ERROR(
54525 + MAJOR,
54526 + E_INVALID_VALUE,
54527 + ("bufMargins.startMargins (%d) + minimum buf size (64) + bufMargins.endMargins (%d) is larger than maximum external buffer size (%d)", p_DriverParams->bufMargins.startMargins, p_DriverParams->bufMargins.endMargins, p_FmPort->rxPoolsParams.largestBufSize));
54528 + }
54529 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54530 + {
54531 + {
54532 +#ifdef FM_NO_OP_OBSERVED_POOLS
54533 + t_FmRevisionInfo revInfo;
54534 +
54535 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
54536 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
54537 +#endif /* FM_NO_OP_OBSERVED_POOLS */
54538 + {
54539 + /* define external buffer pools */
54540 + errCode = SetExtBufferPools(p_FmPort);
54541 + if (errCode)
54542 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54543 + }
54544 + }
54545 + }
54546 +
54547 + /************************************************************/
54548 + /* Call FM module routine for communicating parameters */
54549 + /************************************************************/
54550 + memset(&fmParams, 0, sizeof(fmParams));
54551 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54552 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54553 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
54554 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
54555 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
54556 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
54557 +
54558 + if (p_FmPort->fifoBufs.num)
54559 + {
54560 + errCode = VerifySizeOfFifo(p_FmPort);
54561 + if (errCode != E_OK)
54562 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54563 + }
54564 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
54565 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
54566 + fmParams.independentMode = p_FmPort->imEn;
54567 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
54568 + fmParams.liodnBase = p_DriverParams->liodnBase;
54569 + fmParams.deqPipelineDepth =
54570 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54571 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
54572 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
54573 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
54574 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54575 + {
54576 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
54577 + (p_FmPort->fmRevInfo.majorRev >= 6)))
54578 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
54579 + * for deq threshold calculation.
54580 + */
54581 + fmParams.deqPipelineDepth = 2;
54582 + }
54583 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
54584 +
54585 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
54586 + if (errCode)
54587 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54588 +
54589 + /* get params for use in init */
54590 + p_FmPort->fmMuramPhysBaseAddr =
54591 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
54592 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
54593 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
54594 +
54595 + errCode = InitLowLevelDriver(p_FmPort);
54596 + if (errCode != E_OK)
54597 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
54598 +
54599 + FmPortDriverParamFree(p_FmPort);
54600 +
54601 +#if (DPAA_VERSION >= 11)
54602 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54603 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
54604 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54605 + {
54606 + t_FmPcdCtrlParamsPage *p_ParamsPage;
54607 +
54608 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
54609 + (void**)&p_ParamsPage);
54610 + ASSERT_COND(p_ParamsPage);
54611 +
54612 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
54613 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
54614 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54615 + {
54616 + WRITE_UINT32(
54617 + p_ParamsPage->misc,
54618 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
54619 + WRITE_UINT32(
54620 + p_ParamsPage->discardMask,
54621 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
54622 + }
54623 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
54624 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
54625 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54626 + WRITE_UINT32(
54627 + p_ParamsPage->errorsDiscardMask,
54628 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
54629 + else
54630 + WRITE_UINT32(
54631 + p_ParamsPage->errorsDiscardMask,
54632 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
54633 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
54634 + }
54635 +#endif /* (DPAA_VERSION >= 11) */
54636 +
54637 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
54638 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
54639 + return E_OK;
54640 +}
54641 +
54642 +/**************************************************************************//**
54643 + @Function FM_PORT_Free
54644 +
54645 + @Description Frees all resources that were assigned to FM module.
54646 +
54647 + Calling this routine invalidates the descriptor.
54648 +
54649 + @Param[in] h_FmPort - FM module descriptor
54650 +
54651 + @Return E_OK on success; Error code otherwise.
54652 + *//***************************************************************************/
54653 +t_Error FM_PORT_Free(t_Handle h_FmPort)
54654 +{
54655 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54656 + t_FmInterModulePortFreeParams fmParams;
54657 +
54658 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54659 +
54660 + if (p_FmPort->pcdEngines)
54661 + RETURN_ERROR(
54662 + MAJOR,
54663 + E_INVALID_STATE,
54664 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
54665 +
54666 + if (p_FmPort->enabled)
54667 + {
54668 + if (FM_PORT_Disable(p_FmPort) != E_OK)
54669 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
54670 + }
54671 +
54672 + if (p_FmPort->imEn)
54673 + FmPortImFree(p_FmPort);
54674 +
54675 + FmPortDriverParamFree(p_FmPort);
54676 +
54677 + memset(&fmParams, 0, sizeof(fmParams));
54678 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
54679 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
54680 + fmParams.deqPipelineDepth =
54681 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
54682 +
54683 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
54684 +
54685 +#if (DPAA_VERSION >= 11)
54686 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
54687 + != E_OK)
54688 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
54689 +
54690 + if (p_FmPort->p_ParamsPage)
54691 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
54692 +#endif /* (DPAA_VERSION >= 11) */
54693 +
54694 + if (p_FmPort->h_Spinlock)
54695 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
54696 +
54697 + XX_Free(p_FmPort);
54698 +
54699 + return E_OK;
54700 +}
54701 +
54702 +/*************************************************/
54703 +/* API Advanced Init unit functions */
54704 +/*************************************************/
54705 +
54706 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
54707 +{
54708 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54709 +
54710 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54711 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54712 +
54713 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
54714 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
54715 +
54716 + return E_OK;
54717 +}
54718 +
54719 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
54720 +{
54721 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54722 +
54723 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54724 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54725 +
54726 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
54727 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
54728 + return E_OK;
54729 +}
54730 +
54731 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
54732 +{
54733 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54734 +
54735 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54736 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54737 +
54738 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
54739 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
54740 +
54741 + return E_OK;
54742 +}
54743 +
54744 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
54745 +{
54746 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54747 +
54748 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54749 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54750 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54751 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54752 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
54753 +
54754 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
54755 +
54756 + return E_OK;
54757 +}
54758 +
54759 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
54760 +{
54761 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54762 +
54763 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54764 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54765 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54766 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54767 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54768 + ("not available for Rx ports"));
54769 +
54770 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
54771 + (enum fman_port_deq_type)deqType;
54772 +
54773 + return E_OK;
54774 +}
54775 +
54776 +t_Error FM_PORT_ConfigDeqPrefetchOption(
54777 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
54778 +{
54779 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54780 +
54781 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54782 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54783 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54784 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54785 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54786 + ("not available for Rx ports"));
54787 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
54788 + (enum fman_port_deq_prefetch)deqPrefetchOption;
54789 +
54790 + return E_OK;
54791 +}
54792 +
54793 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
54794 + t_FmBackupBmPools *p_BackupBmPools)
54795 +{
54796 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54797 +
54798 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54799 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54800 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54801 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54802 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54803 + ("available for Rx ports only"));
54804 +
54805 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
54806 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
54807 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54808 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
54809 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
54810 + sizeof(t_FmBackupBmPools));
54811 +
54812 + return E_OK;
54813 +}
54814 +
54815 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
54816 +{
54817 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54818 +
54819 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54820 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54821 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54822 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
54823 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54824 + ("not available for Rx ports"));
54825 +
54826 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
54827 +
54828 + return E_OK;
54829 +}
54830 +
54831 +t_Error FM_PORT_ConfigBufferPrefixContent(
54832 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
54833 +{
54834 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54835 +
54836 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54837 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54838 +
54839 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
54840 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
54841 + /* if dataAlign was not initialized by user, we return to driver's default */
54842 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
54843 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
54844 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
54845 +
54846 + return E_OK;
54847 +}
54848 +
54849 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
54850 + uint8_t checksumLastBytesIgnore)
54851 +{
54852 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54853 +
54854 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54855 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54856 +
54857 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
54858 + checksumLastBytesIgnore;
54859 +
54860 + return E_OK;
54861 +}
54862 +
54863 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
54864 + uint8_t cutBytesFromEnd)
54865 +{
54866 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54867 +
54868 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54869 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54870 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54871 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54872 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54873 + ("available for Rx ports only"));
54874 +
54875 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
54876 +
54877 + return E_OK;
54878 +}
54879 +
54880 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
54881 + t_FmBufPoolDepletion *p_BufPoolDepletion)
54882 +{
54883 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54884 +
54885 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54886 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54887 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54888 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54889 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54890 + ("available for Rx ports only"));
54891 +
54892 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54893 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
54894 + sizeof(t_FmBufPoolDepletion));
54895 +
54896 + return E_OK;
54897 +}
54898 +
54899 +t_Error FM_PORT_ConfigObservedPoolDepletion(
54900 + t_Handle h_FmPort,
54901 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
54902 +{
54903 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54904 +
54905 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54906 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54907 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54908 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54909 + ("available for OP ports only"));
54910 +
54911 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
54912 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
54913 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
54914 + sizeof(t_FmBufPoolDepletion));
54915 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
54916 + &p_FmPortObservedBufPoolDepletion->poolsParams,
54917 + sizeof(t_FmExtPools));
54918 +
54919 + return E_OK;
54920 +}
54921 +
54922 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
54923 +{
54924 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54925 +
54926 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54927 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54928 +
54929 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54930 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54931 + ("available for OP ports only"));
54932 +
54933 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
54934 + sizeof(t_FmExtPools));
54935 +
54936 + return E_OK;
54937 +}
54938 +
54939 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
54940 +{
54941 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54942 +
54943 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54944 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54945 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
54946 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
54947 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54948 + ("available for Tx ports only"));
54949 +
54950 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
54951 +
54952 + return E_OK;
54953 +}
54954 +
54955 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
54956 +{
54957 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54958 +
54959 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54960 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54961 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
54962 +
54963 + return E_OK;
54964 +}
54965 +
54966 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
54967 +{
54968 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54969 +
54970 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54971 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54972 +
54973 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54974 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54975 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54976 + ("Not available for Tx ports"));
54977 +
54978 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
54979 +
54980 + return E_OK;
54981 +}
54982 +
54983 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
54984 +{
54985 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54986 +
54987 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
54988 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
54989 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54990 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
54991 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54992 + ("Not available for Tx ports"));
54993 +
54994 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
54995 +
54996 + return E_OK;
54997 +}
54998 +
54999 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
55000 + fmPortFrameErrSelect_t errs)
55001 +{
55002 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55003 +
55004 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55005 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55006 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55007 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
55008 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
55009 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55010 + ("available for Rx and offline parsing ports only"));
55011 +
55012 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
55013 +
55014 + return E_OK;
55015 +}
55016 +
55017 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
55018 +{
55019 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55020 +
55021 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55022 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55023 +
55024 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
55025 + (enum fman_port_dma_swap)swapData;
55026 +
55027 + return E_OK;
55028 +}
55029 +
55030 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
55031 + e_FmDmaCacheOption intContextCacheAttr)
55032 +{
55033 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55034 +
55035 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55036 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55037 +
55038 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
55039 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
55040 +
55041 + return E_OK;
55042 +}
55043 +
55044 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
55045 + e_FmDmaCacheOption headerCacheAttr)
55046 +{
55047 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55048 +
55049 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55050 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55051 +
55052 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
55053 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
55054 +
55055 + return E_OK;
55056 +}
55057 +
55058 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
55059 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
55060 +{
55061 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55062 +
55063 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55064 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55065 +
55066 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
55067 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
55068 +
55069 + return E_OK;
55070 +}
55071 +
55072 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
55073 +{
55074 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55075 +
55076 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55077 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55078 +
55079 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
55080 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
55081 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55082 + ("Not available for Tx ports"));
55083 +
55084 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
55085 +
55086 + return E_OK;
55087 +}
55088 +
55089 +#if (DPAA_VERSION >= 11)
55090 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
55091 +{
55092 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55093 +
55094 + UNUSED(noScatherGather);
55095 + UNUSED(p_FmPort);
55096 +
55097 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55098 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55099 +
55100 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
55101 +
55102 + return E_OK;
55103 +}
55104 +#endif /* (DPAA_VERSION >= 11) */
55105 +
55106 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
55107 + bool forwardReuse)
55108 +{
55109 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55110 +
55111 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55112 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55113 +
55114 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55115 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55116 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55117 + ("available for Rx ports only"));
55118 +
55119 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
55120 +
55121 + return E_OK;
55122 +}
55123 +
55124 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
55125 +{
55126 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55127 +
55128 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55129 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55130 +
55131 + p_FmPort->maxFrameLength = length;
55132 +
55133 + return E_OK;
55134 +}
55135 +
55136 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
55137 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
55138 +{
55139 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55140 +
55141 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55142 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55143 +
55144 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
55145 +
55146 + return E_OK;
55147 +}
55148 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
55149 +
55150 +/****************************************************/
55151 +/* Hidden-DEBUG Only API */
55152 +/****************************************************/
55153 +
55154 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
55155 + uint32_t minFillLevel)
55156 +{
55157 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55158 +
55159 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55160 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55161 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55162 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55163 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55164 + ("available for Tx ports only"));
55165 +
55166 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
55167 +
55168 + return E_OK;
55169 +}
55170 +
55171 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
55172 + uint8_t deqPipelineDepth)
55173 +{
55174 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55175 +
55176 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55177 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55178 +
55179 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55180 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
55181 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55182 + ("Not available for Rx ports"));
55183 +
55184 + if (p_FmPort->imEn)
55185 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55186 + ("Not available for IM ports!"));
55187 +
55188 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55189 + deqPipelineDepth;
55190 +
55191 + return E_OK;
55192 +}
55193 +
55194 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
55195 + uint32_t fifoLowComfLevel)
55196 +{
55197 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55198 +
55199 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55200 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55201 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55202 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55203 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55204 + ("available for Tx ports only"));
55205 +
55206 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
55207 + fifoLowComfLevel;
55208 +
55209 + return E_OK;
55210 +}
55211 +
55212 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
55213 +{
55214 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55215 +
55216 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55217 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55218 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55219 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55220 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55221 + ("available for Rx ports only"));
55222 +
55223 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
55224 +
55225 + return E_OK;
55226 +}
55227 +
55228 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
55229 + uint32_t priElevationLevel)
55230 +{
55231 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55232 +
55233 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55234 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55235 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55236 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55237 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55238 + ("available for Rx ports only"));
55239 +
55240 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
55241 +
55242 + return E_OK;
55243 +}
55244 +/****************************************************/
55245 +/* API Run-time Control unit functions */
55246 +/****************************************************/
55247 +
55248 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
55249 + t_FmPortRsrc *p_NumOfOpenDmas)
55250 +{
55251 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55252 + t_Error err;
55253 +
55254 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55255 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55256 +
55257 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
55258 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
55259 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
55260 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
55261 + RETURN_ERROR(
55262 + MAJOR,
55263 + E_INVALID_VALUE,
55264 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
55265 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55266 + (uint8_t*)&p_NumOfOpenDmas->num,
55267 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
55268 + if (err)
55269 + RETURN_ERROR(MAJOR, err, NO_MSG);
55270 +
55271 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
55272 +
55273 + return E_OK;
55274 +}
55275 +
55276 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
55277 +{
55278 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55279 + t_Error err;
55280 +
55281 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55282 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55283 +
55284 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
55285 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
55286 +
55287 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
55288 + RETURN_ERROR(
55289 + MAJOR, E_INVALID_VALUE,
55290 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
55291 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
55292 + RETURN_ERROR(
55293 + MAJOR,
55294 + E_INVALID_VALUE,
55295 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
55296 +
55297 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55298 + (uint8_t*)&p_NumOfTasks->num,
55299 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
55300 + if (err)
55301 + RETURN_ERROR(MAJOR, err, NO_MSG);
55302 +
55303 + /* update driver's struct */
55304 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
55305 + return E_OK;
55306 +}
55307 +
55308 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
55309 +{
55310 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55311 + t_Error err;
55312 +
55313 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55314 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55315 +
55316 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
55317 + RETURN_ERROR(
55318 + MAJOR,
55319 + E_INVALID_VALUE,
55320 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
55321 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
55322 + RETURN_ERROR(
55323 + MAJOR, E_INVALID_VALUE,
55324 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
55325 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55326 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
55327 + {
55328 + /* extra FIFO size (allowed only to Rx ports) */
55329 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
55330 + RETURN_ERROR(
55331 + MAJOR,
55332 + E_INVALID_VALUE,
55333 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
55334 + }
55335 + else
55336 + if (p_SizeOfFifo->extra)
55337 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
55338 + (" No SizeOfFifo-extra for non Rx ports"));
55339 +
55340 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
55341 +
55342 + /* we do not change user's parameter */
55343 + err = VerifySizeOfFifo(p_FmPort);
55344 + if (err)
55345 + RETURN_ERROR(MAJOR, err, NO_MSG);
55346 +
55347 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
55348 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
55349 + if (err)
55350 + RETURN_ERROR(MAJOR, err, NO_MSG);
55351 +
55352 + return E_OK;
55353 +}
55354 +
55355 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
55356 +{
55357 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55358 +
55359 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
55360 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55361 + 0);
55362 +
55363 + return p_FmPort->bufferOffsets.dataOffset;
55364 +}
55365 +
55366 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
55367 +{
55368 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55369 +
55370 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55371 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55372 + NULL);
55373 +
55374 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
55375 + return NULL;
55376 +
55377 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
55378 +}
55379 +
55380 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
55381 +{
55382 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55383 +
55384 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55385 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55386 + NULL);
55387 +
55388 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
55389 + return NULL;
55390 +
55391 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
55392 +}
55393 +
55394 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
55395 +{
55396 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55397 +
55398 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55399 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55400 + NULL);
55401 +
55402 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
55403 + return NULL;
55404 +
55405 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
55406 +}
55407 +
55408 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
55409 +{
55410 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55411 +
55412 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
55413 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
55414 + NULL);
55415 +
55416 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
55417 + return NULL;
55418 +
55419 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
55420 +}
55421 +
55422 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
55423 +{
55424 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55425 + int err;
55426 +
55427 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55428 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55429 +
55430 + if (p_FmPort->imEn)
55431 + FmPortImDisable(p_FmPort);
55432 +
55433 + err = fman_port_disable(&p_FmPort->port);
55434 + if (err == -EBUSY)
55435 + {
55436 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
55437 + p_FmPort->name));
55438 + }
55439 + else
55440 + if (err != 0)
55441 + {
55442 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
55443 + }
55444 +
55445 + p_FmPort->enabled = FALSE;
55446 +
55447 + return E_OK;
55448 +}
55449 +
55450 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
55451 +{
55452 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55453 + int err;
55454 +
55455 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55456 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55457 +
55458 + /* Used by FM_PORT_Free routine as indication
55459 + if to disable port. Thus set it to TRUE prior
55460 + to enabling itself. This way if part of enable
55461 + process fails there will be still things
55462 + to disable during Free. For example, if BMI
55463 + enable succeeded but QMI failed, still BMI
55464 + needs to be disabled by Free. */
55465 + p_FmPort->enabled = TRUE;
55466 +
55467 + if (p_FmPort->imEn)
55468 + FmPortImEnable(p_FmPort);
55469 +
55470 + err = fman_port_enable(&p_FmPort->port);
55471 + if (err != 0)
55472 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
55473 +
55474 + return E_OK;
55475 +}
55476 +
55477 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
55478 +{
55479 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55480 + uint8_t factor, countUnitBit;
55481 + uint16_t baseGran;
55482 + struct fman_port_rate_limiter params;
55483 + int err;
55484 +
55485 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55486 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55487 +
55488 + switch (p_FmPort->portType)
55489 + {
55490 + case (e_FM_PORT_TYPE_TX_10G):
55491 + case (e_FM_PORT_TYPE_TX):
55492 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
55493 + break;
55494 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55495 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
55496 + break;
55497 + default:
55498 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55499 + ("available for Tx and Offline parsing ports only"));
55500 + }
55501 +
55502 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
55503 + /* normally, we use 1 usec as the reference count */
55504 + factor = 1;
55505 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
55506 + while (p_RateLimit->rateLimit < baseGran / factor)
55507 + {
55508 + if (countUnitBit == 31)
55509 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
55510 +
55511 + countUnitBit++;
55512 + factor <<= 1;
55513 + }
55514 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
55515 + if (p_RateLimit->rateLimit
55516 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
55517 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
55518 +
55519 + if (!p_RateLimit->maxBurstSize
55520 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
55521 + RETURN_ERROR(
55522 + MAJOR,
55523 + E_INVALID_VALUE,
55524 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
55525 +
55526 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
55527 + params.high_burst_size_gran = FALSE;
55528 + params.burst_size = p_RateLimit->maxBurstSize;
55529 + params.rate = p_RateLimit->rateLimit;
55530 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
55531 +
55532 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55533 + {
55534 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
55535 +
55536 + if ((p_FmPort->fmRevInfo.majorRev == 4)
55537 + || (p_FmPort->fmRevInfo.majorRev >= 6))
55538 + {
55539 + params.high_burst_size_gran = TRUE;
55540 + }
55541 + else
55542 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
55543 + {
55544 + if (p_RateLimit->rateLimitDivider
55545 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
55546 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
55547 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
55548 +
55549 + if (p_RateLimit->maxBurstSize % 1000)
55550 + {
55551 + p_RateLimit->maxBurstSize =
55552 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
55553 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
55554 + }
55555 + else
55556 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
55557 + / 1000);
55558 + }
55559 + params.rate_factor =
55560 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
55561 + params.burst_size = p_RateLimit->maxBurstSize;
55562 + }
55563 +
55564 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
55565 + if (err != 0)
55566 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55567 +
55568 + return E_OK;
55569 +}
55570 +
55571 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
55572 +{
55573 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55574 + int err;
55575 +
55576 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55577 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
55578 +
55579 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
55580 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
55581 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55582 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55583 + ("available for Tx and Offline parsing ports only"));
55584 +
55585 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
55586 + if (err != 0)
55587 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
55588 + return E_OK;
55589 +}
55590 +
55591 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
55592 + uint8_t wq)
55593 +{
55594 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55595 + uint32_t tmpReg;
55596 + uint32_t wqTmpReg;
55597 +
55598 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55599 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55600 +
55601 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
55602 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
55603 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55604 + ("PFC mapping is available for Tx ports only"));
55605 +
55606 + if (prio > 7)
55607 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55608 + ("PFC priority (%d) is out of range (0-7)", prio));
55609 + if (wq > 7)
55610 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
55611 + ("WQ (%d) is out of range (0-7)", wq));
55612 +
55613 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
55614 + tmpReg &= ~(0xf << ((7 - prio) * 4));
55615 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
55616 + tmpReg |= wqTmpReg;
55617 +
55618 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
55619 + tmpReg);
55620 +
55621 + return E_OK;
55622 +}
55623 +
55624 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
55625 +{
55626 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55627 +
55628 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55629 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55630 +
55631 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
55632 +
55633 + return E_OK;
55634 +}
55635 +
55636 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
55637 +{
55638 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55639 + int err;
55640 +
55641 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55642 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55643 +
55644 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
55645 + if (err != 0)
55646 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
55647 + return E_OK;
55648 +}
55649 +
55650 +t_Error FM_PORT_SetPerformanceCountersParams(
55651 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
55652 +{
55653 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55654 + struct fman_port_perf_cnt_params params;
55655 + int err;
55656 +
55657 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55658 +
55659 + /* check parameters */
55660 + if (!p_FmPortPerformanceCnt->taskCompVal
55661 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
55662 + RETURN_ERROR(
55663 + MAJOR,
55664 + E_INVALID_VALUE,
55665 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
55666 + if (!p_FmPortPerformanceCnt->dmaCompVal
55667 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
55668 + RETURN_ERROR(
55669 + MAJOR,
55670 + E_INVALID_VALUE,
55671 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
55672 + if (!p_FmPortPerformanceCnt->fifoCompVal
55673 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
55674 + RETURN_ERROR(
55675 + MAJOR,
55676 + E_INVALID_VALUE,
55677 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
55678 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
55679 + RETURN_ERROR(
55680 + MAJOR,
55681 + E_INVALID_VALUE,
55682 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
55683 +
55684 + switch (p_FmPort->portType)
55685 + {
55686 + case (e_FM_PORT_TYPE_RX_10G):
55687 + case (e_FM_PORT_TYPE_RX):
55688 + if (!p_FmPortPerformanceCnt->queueCompVal
55689 + || (p_FmPortPerformanceCnt->queueCompVal
55690 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
55691 + RETURN_ERROR(
55692 + MAJOR,
55693 + E_INVALID_VALUE,
55694 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
55695 + break;
55696 + case (e_FM_PORT_TYPE_TX_10G):
55697 + case (e_FM_PORT_TYPE_TX):
55698 + if (!p_FmPortPerformanceCnt->queueCompVal
55699 + || (p_FmPortPerformanceCnt->queueCompVal
55700 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
55701 + RETURN_ERROR(
55702 + MAJOR,
55703 + E_INVALID_VALUE,
55704 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
55705 + break;
55706 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55707 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
55708 + if (p_FmPortPerformanceCnt->queueCompVal)
55709 + RETURN_ERROR(
55710 + MAJOR,
55711 + E_INVALID_VALUE,
55712 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
55713 + break;
55714 + default:
55715 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55716 + }
55717 +
55718 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
55719 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
55720 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
55721 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
55722 +
55723 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
55724 + if (err != 0)
55725 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
55726 +
55727 + return E_OK;
55728 +}
55729 +
55730 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
55731 +{
55732 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55733 + t_FmPortPerformanceCnt currParams, savedParams;
55734 + t_Error err;
55735 + bool underTest, failed = FALSE;
55736 +
55737 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55738 +
55739 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
55740 + p_FmPort->portType, p_FmPort->portId);
55741 +
55742 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
55743 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55744 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
55745 + currParams.queueCompVal = 0;
55746 + else
55747 + currParams.queueCompVal = 1;
55748 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
55749 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
55750 +
55751 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55752 + ClearPerfCnts(p_FmPort);
55753 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55754 + != E_OK)
55755 + RETURN_ERROR(MAJOR, err, NO_MSG);
55756 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55757 + XX_UDelay(1000000);
55758 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55759 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55760 + {
55761 + XX_Print(
55762 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
55763 + p_FmPort->tasks.num);
55764 + failed = TRUE;
55765 + }
55766 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55767 + {
55768 + XX_Print(
55769 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
55770 + p_FmPort->openDmas.num);
55771 + failed = TRUE;
55772 + }
55773 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55774 + {
55775 + XX_Print(
55776 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
55777 + p_FmPort->fifoBufs.num);
55778 + failed = TRUE;
55779 + }
55780 + if (failed)
55781 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55782 +
55783 + memset(&savedParams, 0, sizeof(savedParams));
55784 + while (TRUE)
55785 + {
55786 + underTest = FALSE;
55787 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
55788 + {
55789 + currParams.taskCompVal--;
55790 + underTest = TRUE;
55791 + }
55792 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
55793 + {
55794 + currParams.dmaCompVal--;
55795 + underTest = TRUE;
55796 + }
55797 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
55798 + && !savedParams.fifoCompVal)
55799 + {
55800 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
55801 + underTest = TRUE;
55802 + }
55803 + if (!underTest)
55804 + break;
55805 +
55806 + ClearPerfCnts(p_FmPort);
55807 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
55808 + != E_OK)
55809 + RETURN_ERROR(MAJOR, err, NO_MSG);
55810 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
55811 + XX_UDelay(1000000);
55812 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
55813 +
55814 + if (!savedParams.taskCompVal
55815 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
55816 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
55817 + if (!savedParams.dmaCompVal
55818 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
55819 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
55820 + if (!savedParams.fifoCompVal
55821 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
55822 + savedParams.fifoCompVal = currParams.fifoCompVal
55823 + + (2 * BMI_FIFO_UNITS);
55824 + }
55825 +
55826 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
55827 + savedParams.taskCompVal, savedParams.dmaCompVal,
55828 + savedParams.fifoCompVal);
55829 + return E_OK;
55830 +}
55831 +
55832 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
55833 +{
55834 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55835 + int err;
55836 +
55837 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55838 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55839 +
55840 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
55841 + if (err != 0)
55842 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
55843 + return E_OK;
55844 +}
55845 +
55846 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
55847 +{
55848 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55849 + volatile uint32_t *p_ErrDiscard = NULL;
55850 + int err;
55851 +
55852 + UNUSED(p_ErrDiscard);
55853 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
55854 + if (err != 0)
55855 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
55856 +
55857 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
55858 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55859 + {
55860 + t_FmPcdCtrlParamsPage *p_ParamsPage;
55861 +
55862 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
55863 + (void**)&p_ParamsPage);
55864 + ASSERT_COND(p_ParamsPage);
55865 + switch (p_FmPort->portType)
55866 + {
55867 + case (e_FM_PORT_TYPE_RX_10G):
55868 + case (e_FM_PORT_TYPE_RX):
55869 + p_ErrDiscard =
55870 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
55871 + break;
55872 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55873 + p_ErrDiscard =
55874 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
55875 + break;
55876 + default:
55877 + RETURN_ERROR(
55878 + MAJOR, E_INVALID_OPERATION,
55879 + ("available for Rx and offline parsing ports only"));
55880 + }
55881 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
55882 + GET_UINT32(*p_ErrDiscard) | errs);
55883 + }
55884 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
55885 +
55886 + return E_OK;
55887 +}
55888 +
55889 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
55890 + bool enable)
55891 +{
55892 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55893 + int err;
55894 +
55895 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
55896 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
55897 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55898 +
55899 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55900 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
55901 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55902 + ("available for Rx ports only"));
55903 +
55904 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
55905 + if (err != 0)
55906 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
55907 + return E_OK;
55908 +}
55909 +
55910 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
55911 +{
55912 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55913 +
55914 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
55915 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
55916 + p_BmiStats->cntCycle =
55917 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55918 + /* fmbm_rccn */
55919 + p_BmiStats->cntTaskUtil =
55920 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55921 + /* fmbm_rtuc */
55922 + p_BmiStats->cntQueueUtil =
55923 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55924 + /* fmbm_rrquc */
55925 + p_BmiStats->cntDmaUtil =
55926 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55927 + /* fmbm_rduc */
55928 + p_BmiStats->cntFifoUtil =
55929 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55930 + /* fmbm_rfuc */
55931 + p_BmiStats->cntRxPauseActivation =
55932 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
55933 + /* fmbm_rpac */
55934 + p_BmiStats->cntFrame =
55935 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55936 + /* fmbm_rfrc */
55937 + p_BmiStats->cntDiscardFrame =
55938 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55939 + /* fmbm_rfdc */
55940 + p_BmiStats->cntDeallocBuf =
55941 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55942 + /* fmbm_rbdc */
55943 + p_BmiStats->cntRxBadFrame =
55944 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
55945 + /* fmbm_rfbc */
55946 + p_BmiStats->cntRxLargeFrame =
55947 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
55948 + /* fmbm_rlfc */
55949 + p_BmiStats->cntRxFilterFrame =
55950 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
55951 + /* fmbm_rffc */
55952 + p_BmiStats->cntRxListDmaErr =
55953 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
55954 + /* fmbm_rfldec */
55955 + p_BmiStats->cntRxOutOfBuffersDiscard =
55956 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
55957 + /* fmbm_rodc */
55958 + p_BmiStats->cntWredDiscard = 0;
55959 + p_BmiStats->cntLengthErr = 0;
55960 + p_BmiStats->cntUnsupportedFormat = 0;
55961 + }
55962 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
55963 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
55964 + p_BmiStats->cntCycle =
55965 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
55966 + /* fmbm_tccn */
55967 + p_BmiStats->cntTaskUtil =
55968 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
55969 + /* fmbm_ttuc */
55970 + p_BmiStats->cntQueueUtil =
55971 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
55972 + /* fmbm_ttcquc */
55973 + p_BmiStats->cntDmaUtil =
55974 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
55975 + /* fmbm_tduc */
55976 + p_BmiStats->cntFifoUtil =
55977 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
55978 + /* fmbm_tfuc */
55979 + p_BmiStats->cntRxPauseActivation = 0;
55980 + p_BmiStats->cntFrame =
55981 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
55982 + /* fmbm_tfrc */
55983 + p_BmiStats->cntDiscardFrame =
55984 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
55985 + /* fmbm_tfdc */
55986 + p_BmiStats->cntDeallocBuf =
55987 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
55988 + /* fmbm_tbdc */
55989 + p_BmiStats->cntRxBadFrame = 0;
55990 + p_BmiStats->cntRxLargeFrame = 0;
55991 + p_BmiStats->cntRxFilterFrame = 0;
55992 + p_BmiStats->cntRxListDmaErr = 0;
55993 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
55994 + p_BmiStats->cntWredDiscard = 0;
55995 + p_BmiStats->cntLengthErr =
55996 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
55997 + /* fmbm_tfledc */
55998 + p_BmiStats->cntUnsupportedFormat =
55999 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
56000 + /* fmbm_tfufdc */
56001 + }
56002 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
56003 + p_BmiStats->cntCycle =
56004 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
56005 + /* fmbm_occn */
56006 + p_BmiStats->cntTaskUtil =
56007 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
56008 + /* fmbm_otuc */
56009 + p_BmiStats->cntQueueUtil = 0;
56010 + p_BmiStats->cntDmaUtil =
56011 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
56012 + /* fmbm_oduc */
56013 + p_BmiStats->cntFifoUtil =
56014 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
56015 + /* fmbm_ofuc*/
56016 + p_BmiStats->cntRxPauseActivation = 0;
56017 + p_BmiStats->cntFrame =
56018 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
56019 + /* fmbm_ofrc */
56020 + p_BmiStats->cntDiscardFrame =
56021 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
56022 + /* fmbm_ofdc */
56023 + p_BmiStats->cntDeallocBuf =
56024 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
56025 + /* fmbm_obdc*/
56026 + p_BmiStats->cntRxBadFrame = 0;
56027 + p_BmiStats->cntRxLargeFrame = 0;
56028 + p_BmiStats->cntRxFilterFrame =
56029 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
56030 + /* fmbm_offc */
56031 + p_BmiStats->cntRxListDmaErr =
56032 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
56033 + /* fmbm_ofldec */
56034 + p_BmiStats->cntRxOutOfBuffersDiscard =
56035 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
56036 + /* fmbm_rodc */
56037 + p_BmiStats->cntWredDiscard =
56038 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
56039 + /* fmbm_ofwdc */
56040 + p_BmiStats->cntLengthErr =
56041 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
56042 + /* fmbm_ofledc */
56043 + p_BmiStats->cntUnsupportedFormat =
56044 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
56045 + /* fmbm_ofufdc */
56046 + }
56047 + return E_OK;
56048 +}
56049 +
56050 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
56051 +{
56052 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56053 + bool bmiCounter = FALSE;
56054 + enum fman_port_stats_counters statsType;
56055 + enum fman_port_perf_counters perfType;
56056 + enum fman_port_qmi_counters queueType;
56057 + bool isStats;
56058 + t_Error errCode;
56059 +
56060 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56061 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56062 +
56063 + switch (counter)
56064 + {
56065 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56066 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56067 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56068 + /* check that counter is available for the port type */
56069 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56070 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56071 + {
56072 + REPORT_ERROR(MINOR, E_INVALID_STATE,
56073 + ("Requested counter is not available for Rx ports"));
56074 + return 0;
56075 + }
56076 + bmiCounter = FALSE;
56077 + break;
56078 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56079 + bmiCounter = FALSE;
56080 + break;
56081 + default: /* BMI counters (or error - will be checked in BMI routine )*/
56082 + bmiCounter = TRUE;
56083 + break;
56084 + }
56085 +
56086 + if (bmiCounter)
56087 + {
56088 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
56089 + &perfType, &isStats);
56090 + if (errCode != E_OK)
56091 + {
56092 + REPORT_ERROR(MINOR, errCode, NO_MSG);
56093 + return 0;
56094 + }
56095 + if (isStats)
56096 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
56097 + else
56098 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
56099 + }
56100 + else /* QMI counter */
56101 + {
56102 + /* check that counters are enabled */
56103 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
56104 + & QMI_PORT_CFG_EN_COUNTERS))
56105 +
56106 + {
56107 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
56108 + return 0;
56109 + }
56110 +
56111 + /* Set counter */
56112 + switch (counter)
56113 + {
56114 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56115 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56116 + break;
56117 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56118 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56119 + break;
56120 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56121 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56122 + break;
56123 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56124 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56125 + break;
56126 + default:
56127 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
56128 + return 0;
56129 + }
56130 +
56131 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
56132 + }
56133 +
56134 + return 0;
56135 +}
56136 +
56137 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
56138 + uint32_t value)
56139 +{
56140 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56141 + bool bmiCounter = FALSE;
56142 + enum fman_port_stats_counters statsType;
56143 + enum fman_port_perf_counters perfType;
56144 + enum fman_port_qmi_counters queueType;
56145 + bool isStats;
56146 + t_Error errCode;
56147 +
56148 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56149 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56150 +
56151 + switch (counter)
56152 + {
56153 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56154 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56155 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56156 + /* check that counter is available for the port type */
56157 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56158 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56159 + RETURN_ERROR(
56160 + MINOR, E_INVALID_STATE,
56161 + ("Requested counter is not available for Rx ports"));
56162 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56163 + bmiCounter = FALSE;
56164 + break;
56165 + default: /* BMI counters (or error - will be checked in BMI routine )*/
56166 + bmiCounter = TRUE;
56167 + break;
56168 + }
56169 +
56170 + if (bmiCounter)
56171 + {
56172 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
56173 + &perfType, &isStats);
56174 + if (errCode != E_OK)
56175 + {
56176 + RETURN_ERROR(MINOR, errCode, NO_MSG);
56177 + }
56178 + if (isStats)
56179 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
56180 + else
56181 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
56182 + }
56183 + else /* QMI counter */
56184 + {
56185 + /* check that counters are enabled */
56186 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
56187 + & QMI_PORT_CFG_EN_COUNTERS))
56188 + {
56189 + RETURN_ERROR(MINOR, E_INVALID_STATE,
56190 + ("Requested counter was not enabled"));
56191 + }
56192 +
56193 + /* Set counter */
56194 + switch (counter)
56195 + {
56196 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
56197 + queueType = E_FMAN_PORT_ENQ_TOTAL;
56198 + break;
56199 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
56200 + queueType = E_FMAN_PORT_DEQ_TOTAL;
56201 + break;
56202 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
56203 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
56204 + break;
56205 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
56206 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
56207 + break;
56208 + default:
56209 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56210 + ("Requested counter is not available"));
56211 + }
56212 +
56213 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
56214 + }
56215 +
56216 + return E_OK;
56217 +}
56218 +
56219 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
56220 +{
56221 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56222 +
56223 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
56224 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56225 +
56226 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56227 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56228 + {
56229 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
56230 + return 0;
56231 + }
56232 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
56233 +}
56234 +
56235 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
56236 + uint32_t value)
56237 +{
56238 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
56239 +
56240 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56241 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56242 +
56243 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
56244 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
56245 + RETURN_ERROR( MINOR, E_INVALID_STATE,
56246 + ("Requested counter is not available for non-Rx ports"));
56247 +
56248 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
56249 + return E_OK;
56250 +}
56251 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
56252 +{
56253 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56254 + t_Error err;
56255 + bool isStalled;
56256 +
56257 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
56258 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
56259 + FALSE);
56260 +
56261 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
56262 + if (err != E_OK)
56263 + {
56264 + REPORT_ERROR(MAJOR, err, NO_MSG);
56265 + return TRUE;
56266 + }
56267 + return isStalled;
56268 +}
56269 +
56270 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
56271 +{
56272 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56273 +
56274 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56275 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56276 +
56277 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
56278 +}
56279 +
56280 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
56281 +{
56282 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56283 + int err;
56284 +
56285 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56286 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56287 +
56288 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56289 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56290 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56291 + ("available for Rx ports only"));
56292 +
56293 + if (l4Checksum)
56294 + err = fman_port_modify_rx_fd_bits(
56295 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56296 + TRUE);
56297 + else
56298 + err = fman_port_modify_rx_fd_bits(
56299 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
56300 + FALSE);
56301 + if (err != 0)
56302 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
56303 +
56304 + return E_OK;
56305 +}
56306 +
56307 +/*****************************************************************************/
56308 +/* API Run-time PCD Control unit functions */
56309 +/*****************************************************************************/
56310 +
56311 +#if (DPAA_VERSION >= 11)
56312 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
56313 +{
56314 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56315 + t_Error err = E_OK;
56316 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
56317 + uint32_t tmpReg = 0, tmp = 0;
56318 + uint16_t hwStoragePrflId;
56319 +
56320 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56321 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
56322 + /*for numOfProfiles = 0 don't call this function*/
56323 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
56324 + /*dfltRelativeId should be in the range of numOfProfiles*/
56325 + SANITY_CHECK_RETURN_ERROR(
56326 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
56327 + E_INVALID_VALUE);
56328 + /*p_FmPort should be from Rx type or OP*/
56329 + SANITY_CHECK_RETURN_ERROR(
56330 + ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G) || (p_FmPort->portType == e_FM_PORT_TYPE_RX) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56331 + E_INVALID_VALUE);
56332 + /*port should be disabled*/
56333 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
56334 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
56335 + SANITY_CHECK_RETURN_ERROR(
56336 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
56337 + E_INVALID_VALUE);
56338 + /*should be called before SetPCD - this port should be without PCD*/
56339 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
56340 +
56341 + /*alloc window of VSPs for this port*/
56342 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
56343 + p_FmPort->portId, p_VSPParams->numOfProfiles);
56344 + if (err != E_OK)
56345 + RETURN_ERROR(MAJOR, err, NO_MSG);
56346 +
56347 + /*get absolute VSP ID for dfltRelative*/
56348 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
56349 + p_FmPort->portId,
56350 + p_VSPParams->dfltRelativeId,
56351 + &hwStoragePrflId);
56352 + if (err != E_OK)
56353 + RETURN_ERROR(MAJOR, err, NO_MSG);
56354 +
56355 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
56356 + switch (p_FmPort->portType)
56357 + {
56358 + case (e_FM_PORT_TYPE_RX_10G):
56359 + case (e_FM_PORT_TYPE_RX):
56360 + p_BmiStorageProfileId =
56361 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
56362 + p_BmiVspe =
56363 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
56364 +
56365 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56366 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56367 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56368 +
56369 + tmpReg = GET_UINT32(*p_BmiVspe);
56370 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
56371 +
56372 + p_BmiStorageProfileId =
56373 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
56374 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
56375 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
56376 + break;
56377 +
56378 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56379 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
56380 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
56381 + tmpReg);
56382 +
56383 + p_BmiStorageProfileId =
56384 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
56385 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
56386 + tmp |= BMI_EBD_EN;
56387 + break;
56388 +
56389 + default:
56390 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56391 + ("available for Rx and offline parsing ports only"));
56392 + }
56393 +
56394 + p_FmPort->vspe = TRUE;
56395 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
56396 +
56397 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
56398 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
56399 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
56400 +
56401 + tmpReg = GET_UINT32(*p_BmiVspe);
56402 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
56403 + return E_OK;
56404 +}
56405 +#endif /* (DPAA_VERSION >= 11) */
56406 +
56407 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
56408 +{
56409 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56410 + t_Error err = E_OK;
56411 +
56412 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56413 + ASSERT_COND(p_FmPort->h_FmPcd);
56414 +
56415 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56416 + {
56417 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56418 + return ERROR_CODE(E_BUSY);
56419 + }
56420 +
56421 + if (numOfProfiles)
56422 + {
56423 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
56424 + p_FmPort->hardwarePortId, numOfProfiles);
56425 + if (err)
56426 + RETURN_ERROR(MAJOR, err, NO_MSG);
56427 + }
56428 + /* set the port handle within the PCD policer, even if no profiles defined */
56429 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
56430 +
56431 + RELEASE_LOCK(p_FmPort->lock);
56432 +
56433 + return E_OK;
56434 +}
56435 +
56436 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
56437 +{
56438 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56439 + t_Error err = E_OK;
56440 +
56441 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56442 + {
56443 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56444 + return ERROR_CODE(E_BUSY);
56445 + }
56446 +
56447 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
56448 +
56449 + RELEASE_LOCK(p_FmPort->lock);
56450 +
56451 + if (err)
56452 + RETURN_ERROR(MAJOR, err, NO_MSG);
56453 +
56454 + return E_OK;
56455 +}
56456 +
56457 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
56458 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
56459 +{
56460 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56461 + volatile uint32_t *p_BmiHpnia = NULL;
56462 + uint32_t tmpReg;
56463 + uint8_t relativeSchemeId;
56464 + uint8_t physicalSchemeId;
56465 +
56466 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56467 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56468 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
56469 + E_INVALID_STATE);
56470 +
56471 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
56472 + switch (p_FmPort->portType)
56473 + {
56474 + case (e_FM_PORT_TYPE_RX_10G):
56475 + case (e_FM_PORT_TYPE_RX):
56476 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56477 + break;
56478 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56479 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56480 + break;
56481 + default:
56482 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56483 + ("available for Rx and offline parsing ports only"));
56484 + }
56485 +
56486 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56487 + {
56488 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56489 + return ERROR_CODE(E_BUSY);
56490 + }
56491 +
56492 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
56493 + if (p_FmPcdKgScheme->direct)
56494 + {
56495 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
56496 + /* check that this scheme is bound to this port */
56497 + if (!(p_FmPort->schemesPerPortVector
56498 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
56499 + {
56500 + RELEASE_LOCK(p_FmPort->lock);
56501 + RETURN_ERROR(
56502 + MAJOR, E_INVALID_STATE,
56503 + ("called with a scheme that is not bound to this port"));
56504 + }
56505 +
56506 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
56507 + physicalSchemeId);
56508 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
56509 + {
56510 + RELEASE_LOCK(p_FmPort->lock);
56511 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
56512 + ("called with invalid Scheme "));
56513 + }
56514 +
56515 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
56516 + {
56517 + RELEASE_LOCK(p_FmPort->lock);
56518 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56519 + ("called with uninitialized Scheme "));
56520 + }
56521 +
56522 + WRITE_UINT32(
56523 + *p_BmiHpnia,
56524 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
56525 + }
56526 + else
56527 + /* change to indirect scheme */
56528 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
56529 + RELEASE_LOCK(p_FmPort->lock);
56530 +
56531 + return E_OK;
56532 +}
56533 +
56534 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
56535 + t_Handle h_Profile)
56536 +{
56537 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56538 + volatile uint32_t *p_BmiNia;
56539 + volatile uint32_t *p_BmiHpnia;
56540 + uint32_t tmpReg;
56541 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
56542 +
56543 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56544 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56545 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
56546 + E_INVALID_STATE);
56547 +
56548 + /* check relevance of this routine - only when policer is used
56549 + directly after BMI or Parser */
56550 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
56551 + || (p_FmPort->pcdEngines & FM_PCD_CC))
56552 + RETURN_ERROR(
56553 + MAJOR,
56554 + E_INVALID_STATE,
56555 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
56556 +
56557 + switch (p_FmPort->portType)
56558 + {
56559 + case (e_FM_PORT_TYPE_RX_10G):
56560 + case (e_FM_PORT_TYPE_RX):
56561 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56562 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
56563 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
56564 + break;
56565 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56566 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56567 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
56568 + tmpReg = 0;
56569 + break;
56570 + default:
56571 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56572 + ("available for Rx and offline parsing ports only"));
56573 + }
56574 +
56575 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56576 + {
56577 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56578 + return ERROR_CODE(E_BUSY);
56579 + }
56580 +
56581 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
56582 + {
56583 + RELEASE_LOCK(p_FmPort->lock);
56584 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
56585 + }
56586 +
56587 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
56588 +
56589 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
56590 + {
56591 + /* update BMI HPNIA */
56592 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
56593 + }
56594 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
56595 + {
56596 + /* rfne may contain FDCS bits, so first we read them. */
56597 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
56598 + /* update BMI NIA */
56599 + WRITE_UINT32(*p_BmiNia, tmpReg);
56600 + }RELEASE_LOCK(p_FmPort->lock);
56601 +
56602 + return E_OK;
56603 +}
56604 +
56605 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
56606 +{
56607 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56608 + t_Error err = E_OK;
56609 + volatile uint32_t *p_BmiCcBase = NULL;
56610 + volatile uint32_t *p_BmiNia = NULL;
56611 + uint32_t ccTreePhysOffset;
56612 +
56613 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56614 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
56615 +
56616 + if (p_FmPort->imEn)
56617 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56618 + ("available for non-independent mode ports only"));
56619 +
56620 + /* get PCD registers pointers */
56621 + switch (p_FmPort->portType)
56622 + {
56623 + case (e_FM_PORT_TYPE_RX_10G):
56624 + case (e_FM_PORT_TYPE_RX):
56625 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
56626 + break;
56627 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56628 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
56629 + break;
56630 + default:
56631 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56632 + ("available for Rx and offline parsing ports only"));
56633 + }
56634 +
56635 + /* check that current NIA is BMI to BMI */
56636 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
56637 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
56638 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56639 + ("may be called only for ports in BMI-to-BMI state."));
56640 +
56641 + if (p_FmPort->pcdEngines & FM_PCD_CC)
56642 + {
56643 + if (p_FmPort->h_IpReassemblyManip)
56644 + {
56645 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56646 + p_FmPort->h_IpReassemblyManip, FALSE);
56647 + if (err != E_OK)
56648 + {
56649 + RETURN_ERROR(MAJOR, err, NO_MSG);
56650 + }
56651 + }
56652 + else
56653 + if (p_FmPort->h_CapwapReassemblyManip)
56654 + {
56655 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
56656 + p_FmPort->h_CapwapReassemblyManip,
56657 + FALSE);
56658 + if (err != E_OK)
56659 + {
56660 + RETURN_ERROR(MAJOR, err, NO_MSG);
56661 + }
56662 + }
56663 + switch (p_FmPort->portType)
56664 + {
56665 + case (e_FM_PORT_TYPE_RX_10G):
56666 + case (e_FM_PORT_TYPE_RX):
56667 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
56668 + break;
56669 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56670 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
56671 + break;
56672 + default:
56673 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56674 + }
56675 +
56676 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56677 + {
56678 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56679 + return ERROR_CODE(E_BUSY);
56680 + }
56681 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
56682 + &ccTreePhysOffset, h_FmPort);
56683 + if (err)
56684 + {
56685 + RELEASE_LOCK(p_FmPort->lock);
56686 + RETURN_ERROR(MAJOR, err, NO_MSG);
56687 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
56688 +
56689 + p_FmPort->ccTreeId = h_CcTree;
56690 + RELEASE_LOCK(p_FmPort->lock);
56691 + }
56692 + else
56693 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56694 + ("Coarse Classification not defined for this port."));
56695 +
56696 + return E_OK;
56697 +}
56698 +
56699 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
56700 +{
56701 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56702 + t_Error err = E_OK;
56703 +
56704 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56705 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56706 +
56707 + if (p_FmPort->imEn)
56708 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56709 + ("available for non-independent mode ports only"));
56710 +
56711 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56712 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56713 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56714 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56715 + ("available for Rx and offline parsing ports only"));
56716 +
56717 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56718 + {
56719 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56720 + return ERROR_CODE(E_BUSY);
56721 + }
56722 +
56723 + if (p_FmPort->h_ReassemblyTree)
56724 + p_FmPort->pcdEngines |= FM_PCD_CC;
56725 +
56726 + err = AttachPCD(h_FmPort);
56727 + RELEASE_LOCK(p_FmPort->lock);
56728 +
56729 + return err;
56730 +}
56731 +
56732 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
56733 +{
56734 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56735 + t_Error err = E_OK;
56736 +
56737 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56738 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56739 +
56740 + if (p_FmPort->imEn)
56741 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56742 + ("available for non-independent mode ports only"));
56743 +
56744 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56745 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56746 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56747 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56748 + ("available for Rx and offline parsing ports only"));
56749 +
56750 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56751 + {
56752 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56753 + return ERROR_CODE(E_BUSY);
56754 + }
56755 +
56756 + err = DetachPCD(h_FmPort);
56757 + if (err != E_OK)
56758 + {
56759 + RELEASE_LOCK(p_FmPort->lock);
56760 + RETURN_ERROR(MAJOR, err, NO_MSG);
56761 + }
56762 +
56763 + if (p_FmPort->h_ReassemblyTree)
56764 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
56765 + RELEASE_LOCK(p_FmPort->lock);
56766 +
56767 + return E_OK;
56768 +}
56769 +
56770 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
56771 +{
56772 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56773 + t_Error err = E_OK;
56774 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
56775 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
56776 + t_FmPortPcdCcParams fmPortPcdCcParams;
56777 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
56778 +
56779 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56780 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
56781 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
56782 +
56783 + if (p_FmPort->imEn)
56784 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56785 + ("available for non-independent mode ports only"));
56786 +
56787 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56788 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56789 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56790 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56791 + ("available for Rx and offline parsing ports only"));
56792 +
56793 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
56794 + {
56795 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
56796 + return ERROR_CODE(E_BUSY);
56797 + }
56798 +
56799 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
56800 + ASSERT_COND(p_FmPort->h_FmPcd);
56801 +
56802 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
56803 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
56804 + ("Tree handle must be given if CC is required"));
56805 +
56806 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
56807 + p_PcdParams = &modifiedPcdParams;
56808 + if ((p_PcdParams->h_IpReassemblyManip)
56809 +#if (DPAA_VERSION >= 11)
56810 + || (p_PcdParams->h_CapwapReassemblyManip)
56811 +#endif /* (DPAA_VERSION >= 11) */
56812 + )
56813 + {
56814 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56815 + && (p_PcdParams->pcdSupport
56816 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
56817 + && (p_PcdParams->pcdSupport
56818 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
56819 + && (p_PcdParams->pcdSupport
56820 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
56821 + {
56822 + RELEASE_LOCK(p_FmPort->lock);
56823 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
56824 + ("pcdSupport must have KG for supporting Reassembly"));
56825 + }
56826 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
56827 +#if (DPAA_VERSION >= 11)
56828 + if ((p_PcdParams->h_IpReassemblyManip)
56829 + && (p_PcdParams->h_CapwapReassemblyManip))
56830 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56831 + ("Either IP-R or CAPWAP-R is allowed"));
56832 + if ((p_PcdParams->h_CapwapReassemblyManip)
56833 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56834 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
56835 + ("CAPWAP-R is allowed only on offline-port"));
56836 + if (p_PcdParams->h_CapwapReassemblyManip)
56837 + p_FmPort->h_CapwapReassemblyManip =
56838 + p_PcdParams->h_CapwapReassemblyManip;
56839 +#endif /* (DPAA_VERSION >= 11) */
56840 +
56841 + if (!p_PcdParams->p_CcParams)
56842 + {
56843 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56844 + || (p_PcdParams->pcdSupport
56845 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
56846 + {
56847 + RELEASE_LOCK(p_FmPort->lock);
56848 + RETURN_ERROR(
56849 + MAJOR,
56850 + E_INVALID_STATE,
56851 + ("PCD initialization structure is not consistent with pcdSupport"));
56852 + }
56853 +
56854 + /* No user-tree, need to build internal tree */
56855 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
56856 + sizeof(t_FmPcdCcTreeParams));
56857 + if (!p_FmPcdCcTreeParams)
56858 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
56859 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
56860 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
56861 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
56862 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
56863 +
56864 + if (!p_FmPort->h_ReassemblyTree)
56865 + {
56866 + RELEASE_LOCK(p_FmPort->lock);
56867 + XX_Free(p_FmPcdCcTreeParams);
56868 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
56869 + ("FM_PCD_CcBuildTree for Reassembly failed"));
56870 + }
56871 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
56872 + p_PcdParams->pcdSupport =
56873 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
56874 + else
56875 + p_PcdParams->pcdSupport =
56876 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
56877 +
56878 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
56879 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
56880 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
56881 + XX_Free(p_FmPcdCcTreeParams);
56882 + }
56883 +
56884 + if (p_FmPort->h_IpReassemblyManip)
56885 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
56886 + p_PcdParams->p_CcParams->h_CcTree,
56887 + p_PcdParams->h_NetEnv,
56888 + p_FmPort->h_IpReassemblyManip, TRUE);
56889 +#if (DPAA_VERSION >= 11)
56890 + else
56891 + if (p_FmPort->h_CapwapReassemblyManip)
56892 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
56893 + p_PcdParams->p_CcParams->h_CcTree,
56894 + p_PcdParams->h_NetEnv,
56895 + p_FmPort->h_CapwapReassemblyManip,
56896 + TRUE);
56897 +#endif /* (DPAA_VERSION >= 11) */
56898 +
56899 + if (err != E_OK)
56900 + {
56901 + if (p_FmPort->h_ReassemblyTree)
56902 + {
56903 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56904 + p_FmPort->h_ReassemblyTree = NULL;
56905 + }RELEASE_LOCK(p_FmPort->lock);
56906 + RETURN_ERROR(MAJOR, err, NO_MSG);
56907 + }
56908 + }
56909 +
56910 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
56911 + {
56912 + if (p_FmPort->h_ReassemblyTree)
56913 + {
56914 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56915 + p_FmPort->h_ReassemblyTree = NULL;
56916 + }RELEASE_LOCK(p_FmPort->lock);
56917 + DBG(TRACE, ("Try LockAll - BUSY"));
56918 + return ERROR_CODE(E_BUSY);
56919 + }
56920 +
56921 + err = SetPcd(h_FmPort, p_PcdParams);
56922 + if (err)
56923 + {
56924 + if (p_FmPort->h_ReassemblyTree)
56925 + {
56926 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56927 + p_FmPort->h_ReassemblyTree = NULL;
56928 + }
56929 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56930 + RELEASE_LOCK(p_FmPort->lock);
56931 + RETURN_ERROR(MAJOR, err, NO_MSG);
56932 + }
56933 +
56934 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
56935 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
56936 + {
56937 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
56938 + p_FmPort->hardwarePortId, TRUE);
56939 + if (err)
56940 + {
56941 + DeletePcd(p_FmPort);
56942 + if (p_FmPort->h_ReassemblyTree)
56943 + {
56944 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
56945 + p_FmPort->h_ReassemblyTree = NULL;
56946 + }
56947 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
56948 + RELEASE_LOCK(p_FmPort->lock);
56949 + RETURN_ERROR(MAJOR, err, NO_MSG);
56950 + }
56951 + p_FmPort->includeInPrsStatistics = TRUE;
56952 + }
56953 +
56954 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
56955 +
56956 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
56957 + {
56958 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
56959 +
56960 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56961 + {
56962 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
56963 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
56964 + (p_FmPort->pcdEngines & FM_PCD_KG))
56965 + {
56966 + int i;
56967 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
56968 + /* The following function must be locked */
56969 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
56970 + p_PcdParams->p_KgParams->h_Schemes[i],
56971 + UPDATE_KG_NIA_CC_WA,
56972 + 0);
56973 + }
56974 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
56975 +
56976 +#if (DPAA_VERSION >= 11)
56977 + {
56978 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56979 +
56980 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56981 + (void**)&p_ParamsPage);
56982 + ASSERT_COND(p_ParamsPage);
56983 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
56984 + p_FmPort->savedBmiNia);
56985 + }
56986 +#endif /* (DPAA_VERSION >= 11) */
56987 +
56988 + /* Set post-bmi-fetch nia */
56989 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
56990 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
56991 + | NIA_ENG_FM_CTL);
56992 +
56993 + /* Set pre-bmi-fetch nia */
56994 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
56995 +#if (DPAA_VERSION >= 11)
56996 + fmPortGetSetCcParams.setCcParams.nia =
56997 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
56998 +#else
56999 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
57000 +#endif /* (DPAA_VERSION >= 11) */
57001 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
57002 + != E_OK)
57003 + {
57004 + DeletePcd(p_FmPort);
57005 + if (p_FmPort->h_ReassemblyTree)
57006 + {
57007 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57008 + p_FmPort->h_ReassemblyTree = NULL;
57009 + }
57010 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57011 + RELEASE_LOCK(p_FmPort->lock);
57012 + RETURN_ERROR(MAJOR, err, NO_MSG);
57013 + }
57014 + }
57015 +
57016 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57017 +
57018 + /* Set pop-to-next-step nia */
57019 +#if (DPAA_VERSION == 10)
57020 + if (p_FmPort->fmRevInfo.majorRev < 6)
57021 + {
57022 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
57023 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
57024 + }
57025 + else
57026 + {
57027 +#endif /* (DPAA_VERSION == 10) */
57028 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
57029 +#if (DPAA_VERSION == 10)
57030 + }
57031 +#endif /* (DPAA_VERSION == 10) */
57032 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57033 + != E_OK)
57034 + {
57035 + DeletePcd(p_FmPort);
57036 + if (p_FmPort->h_ReassemblyTree)
57037 + {
57038 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57039 + p_FmPort->h_ReassemblyTree = NULL;
57040 + }RELEASE_LOCK(p_FmPort->lock);
57041 + RETURN_ERROR(MAJOR, err, NO_MSG);
57042 + }
57043 +
57044 + /* Set post-bmi-prepare-to-enq nia */
57045 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
57046 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
57047 + | NIA_ENG_FM_CTL);
57048 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57049 + != E_OK)
57050 + {
57051 + DeletePcd(p_FmPort);
57052 + if (p_FmPort->h_ReassemblyTree)
57053 + {
57054 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57055 + p_FmPort->h_ReassemblyTree = NULL;
57056 + }RELEASE_LOCK(p_FmPort->lock);
57057 + RETURN_ERROR(MAJOR, err, NO_MSG);
57058 + }
57059 +
57060 + if ((p_FmPort->h_IpReassemblyManip)
57061 + || (p_FmPort->h_CapwapReassemblyManip))
57062 + {
57063 +#if (DPAA_VERSION == 10)
57064 + if (p_FmPort->fmRevInfo.majorRev < 6)
57065 + {
57066 + /* Overwrite post-bmi-prepare-to-enq nia */
57067 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
57068 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
57069 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
57070 + }
57071 + else
57072 + {
57073 +#endif /* (DPAA_VERSION == 10) */
57074 + /* Set the ORR bit (for order-restoration) */
57075 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
57076 + fmPortGetSetCcParams.setCcParams.nia =
57077 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
57078 +#if (DPAA_VERSION == 10)
57079 + }
57080 +#endif /* (DPAA_VERSION == 10) */
57081 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57082 + != E_OK)
57083 + {
57084 + DeletePcd(p_FmPort);
57085 + if (p_FmPort->h_ReassemblyTree)
57086 + {
57087 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57088 + p_FmPort->h_ReassemblyTree = NULL;
57089 + }RELEASE_LOCK(p_FmPort->lock);
57090 + RETURN_ERROR(MAJOR, err, NO_MSG);
57091 + }
57092 + }
57093 + }
57094 + else
57095 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57096 +
57097 +#if (DPAA_VERSION >= 11)
57098 + {
57099 + t_FmPcdCtrlParamsPage *p_ParamsPage;
57100 +
57101 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
57102 +
57103 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
57104 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
57105 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
57106 + | NIA_ENG_FM_CTL;
57107 + else
57108 + fmPortGetSetCcParams.setCcParams.nia =
57109 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
57110 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
57111 + != E_OK)
57112 + {
57113 + DeletePcd(p_FmPort);
57114 + if (p_FmPort->h_ReassemblyTree)
57115 + {
57116 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57117 + p_FmPort->h_ReassemblyTree = NULL;
57118 + }RELEASE_LOCK(p_FmPort->lock);
57119 + RETURN_ERROR(MAJOR, err, NO_MSG);
57120 + }
57121 +
57122 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
57123 + (void**)&p_ParamsPage);
57124 + ASSERT_COND(p_ParamsPage);
57125 +
57126 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
57127 + WRITE_UINT32(
57128 + p_ParamsPage->misc,
57129 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
57130 +
57131 + if ((p_FmPort->h_IpReassemblyManip)
57132 + || (p_FmPort->h_CapwapReassemblyManip))
57133 + {
57134 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57135 + WRITE_UINT32(
57136 + p_ParamsPage->discardMask,
57137 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
57138 + else
57139 + WRITE_UINT32(
57140 + p_ParamsPage->discardMask,
57141 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
57142 + }
57143 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
57144 + if (p_FmPort->vspe)
57145 + WRITE_UINT32(
57146 + p_ParamsPage->misc,
57147 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
57148 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
57149 + }
57150 +#endif /* (DPAA_VERSION >= 11) */
57151 +
57152 + err = AttachPCD(h_FmPort);
57153 + if (err)
57154 + {
57155 + DeletePcd(p_FmPort);
57156 + if (p_FmPort->h_ReassemblyTree)
57157 + {
57158 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57159 + p_FmPort->h_ReassemblyTree = NULL;
57160 + }RELEASE_LOCK(p_FmPort->lock);
57161 + RETURN_ERROR(MAJOR, err, NO_MSG);
57162 + }
57163 +
57164 + RELEASE_LOCK(p_FmPort->lock);
57165 +
57166 + return err;
57167 +}
57168 +
57169 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
57170 +{
57171 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57172 + t_Error err = E_OK;
57173 +
57174 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
57175 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57176 +
57177 + if (p_FmPort->imEn)
57178 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57179 + ("available for non-independant mode ports only"));
57180 +
57181 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57182 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57183 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57184 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57185 + ("available for Rx and offline parsing ports only"));
57186 +
57187 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57188 + {
57189 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57190 + return ERROR_CODE(E_BUSY);
57191 + }
57192 +
57193 + err = DetachPCD(h_FmPort);
57194 + if (err)
57195 + {
57196 + RELEASE_LOCK(p_FmPort->lock);
57197 + RETURN_ERROR(MAJOR, err, NO_MSG);
57198 + }
57199 +
57200 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
57201 +
57202 + /* we do it anyway, instead of checking if included */
57203 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
57204 + {
57205 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
57206 + p_FmPort->hardwarePortId, FALSE);
57207 + p_FmPort->includeInPrsStatistics = FALSE;
57208 + }
57209 +
57210 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
57211 + {
57212 + RELEASE_LOCK(p_FmPort->lock);
57213 + DBG(TRACE, ("Try LockAll - BUSY"));
57214 + return ERROR_CODE(E_BUSY);
57215 + }
57216 +
57217 + err = DeletePcd(h_FmPort);
57218 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
57219 + if (err)
57220 + {
57221 + RELEASE_LOCK(p_FmPort->lock);
57222 + RETURN_ERROR(MAJOR, err, NO_MSG);
57223 + }
57224 +
57225 + if (p_FmPort->h_ReassemblyTree)
57226 + {
57227 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
57228 + if (err)
57229 + {
57230 + RELEASE_LOCK(p_FmPort->lock);
57231 + RETURN_ERROR(MAJOR, err, NO_MSG);
57232 + }
57233 + p_FmPort->h_ReassemblyTree = NULL;
57234 + }RELEASE_LOCK(p_FmPort->lock);
57235 +
57236 + return err;
57237 +}
57238 +
57239 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
57240 + t_FmPcdPortSchemesParams *p_PortScheme)
57241 +{
57242 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57243 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57244 + t_Error err = E_OK;
57245 + uint32_t tmpScmVec = 0;
57246 + int i;
57247 +
57248 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57249 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57250 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57251 + E_INVALID_STATE);
57252 +
57253 + schemeBind.netEnvId = p_FmPort->netEnvId;
57254 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57255 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57256 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
57257 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57258 + {
57259 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57260 + p_PortScheme->h_Schemes[i]);
57261 + /* build vector */
57262 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57263 + }
57264 +
57265 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57266 + {
57267 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57268 + return ERROR_CODE(E_BUSY);
57269 + }
57270 +
57271 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57272 + if (err == E_OK)
57273 + p_FmPort->schemesPerPortVector |= tmpScmVec;
57274 +
57275 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
57276 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
57277 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
57278 + (p_FmPort->fmRevInfo.majorRev < 6))
57279 + {
57280 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
57281 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
57282 + }
57283 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
57284 +
57285 + RELEASE_LOCK(p_FmPort->lock);
57286 +
57287 + return err;
57288 +}
57289 +
57290 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
57291 + t_FmPcdPortSchemesParams *p_PortScheme)
57292 +{
57293 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57294 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
57295 + t_Error err = E_OK;
57296 + uint32_t tmpScmVec = 0;
57297 + int i;
57298 +
57299 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57300 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57301 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
57302 + E_INVALID_STATE);
57303 +
57304 + schemeBind.netEnvId = p_FmPort->netEnvId;
57305 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
57306 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
57307 + for (i = 0; i < schemeBind.numOfSchemes; i++)
57308 + {
57309 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
57310 + p_PortScheme->h_Schemes[i]);
57311 + /* build vector */
57312 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
57313 + }
57314 +
57315 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
57316 + {
57317 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
57318 + return ERROR_CODE(E_BUSY);
57319 + }
57320 +
57321 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
57322 + if (err == E_OK)
57323 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
57324 + RELEASE_LOCK(p_FmPort->lock);
57325 +
57326 + return err;
57327 +}
57328 +
57329 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
57330 + t_FmPortCongestionGrps *p_CongestionGrps)
57331 +{
57332 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57333 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
57334 + uint8_t mod, index;
57335 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57336 + int err;
57337 +#if (DPAA_VERSION >= 11)
57338 + int j;
57339 +#endif /* (DPAA_VERSION >= 11) */
57340 +
57341 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57342 +
57343 + /* un-necessary check of the indexes; probably will be needed in the future when there
57344 + will be more CGs available ....
57345 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57346 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
57347 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
57348 + */
57349 +
57350 +#ifdef FM_NO_OP_OBSERVED_CGS
57351 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
57352 + (p_FmPort->fmRevInfo.majorRev < 6))
57353 + {
57354 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57355 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57356 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57357 + }
57358 + else
57359 +#endif /* FM_NO_OP_OBSERVED_CGS */
57360 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57361 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57362 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57363 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57364 + ("Available for Rx & OP ports only"));
57365 +
57366 + /* Prepare groups map array */
57367 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57368 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57369 + {
57370 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57371 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57372 + if (p_FmPort->fmRevInfo.majorRev != 4)
57373 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57374 + else
57375 + grpsMap[0] |= (uint32_t)(1 << mod);
57376 + }
57377 +
57378 + memset(&priorityTmpArray, 0,
57379 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
57380 +
57381 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57382 + {
57383 +#if (DPAA_VERSION >= 11)
57384 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
57385 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
57386 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
57387 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
57388 +#endif /* (DPAA_VERSION >= 11) */
57389 + }
57390 +
57391 +#if (DPAA_VERSION >= 11)
57392 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
57393 + {
57394 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
57395 + priorityTmpArray[i]);
57396 + if (err)
57397 + return err;
57398 + }
57399 +#endif /* (DPAA_VERSION >= 11) */
57400 +
57401 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
57402 + if (err != 0)
57403 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
57404 +
57405 + return E_OK;
57406 +}
57407 +
57408 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
57409 + t_FmPortCongestionGrps *p_CongestionGrps)
57410 +{
57411 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57412 + uint8_t mod, index;
57413 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
57414 + int err;
57415 +
57416 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57417 +
57418 + {
57419 +#ifdef FM_NO_OP_OBSERVED_CGS
57420 + t_FmRevisionInfo revInfo;
57421 +
57422 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
57423 + if (revInfo.majorRev != 4)
57424 + {
57425 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
57426 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57427 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
57428 + }
57429 + else
57430 +#endif /* FM_NO_OP_OBSERVED_CGS */
57431 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57432 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
57433 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
57434 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57435 + ("Available for Rx & OP ports only"));
57436 + }
57437 +
57438 + /* Prepare groups map array */
57439 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
57440 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57441 + {
57442 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
57443 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
57444 + if (p_FmPort->fmRevInfo.majorRev != 4)
57445 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
57446 + else
57447 + grpsMap[0] |= (uint32_t)(1 << mod);
57448 + }
57449 +
57450 +#if (DPAA_VERSION >= 11)
57451 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
57452 + {
57453 + t_Error err = FmSetCongestionGroupPFCpriority(
57454 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
57455 + 0);
57456 + if (err)
57457 + return err;
57458 + }
57459 +#endif /* (DPAA_VERSION >= 11) */
57460 +
57461 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
57462 + if (err != 0)
57463 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57464 + ("fman_port_remove_congestion_grps"));
57465 + return E_OK;
57466 +}
57467 +
57468 +#if (DPAA_VERSION >= 11)
57469 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
57470 + uint32_t *p_Ipv4OptionsCount)
57471 +{
57472 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57473 +
57474 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57475 + SANITY_CHECK_RETURN_ERROR(
57476 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
57477 + E_INVALID_VALUE);
57478 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
57479 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
57480 +
57481 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
57482 +
57483 + return E_OK;
57484 +}
57485 +#endif /* (DPAA_VERSION >= 11) */
57486 +
57487 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
57488 + t_FmPortDsarTablesSizes *params)
57489 +{
57490 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57491 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
57492 + sizeof(struct t_FmPortDsarTablesSizes));
57493 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
57494 + sizeof(struct t_FmPortDsarTablesSizes));
57495 + return E_OK;
57496 +}
57497 +
57498 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
57499 +{
57500 + uint32_t *param_page;
57501 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
57502 + t_ArCommonDesc *ArCommonDescPtr;
57503 + uint32_t size = sizeof(t_ArCommonDesc);
57504 + // ARP
57505 + // should put here if (params->max_num_of_arp_entries)?
57506 + size = ROUND_UP(size,4);
57507 + size += sizeof(t_DsarArpDescriptor);
57508 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
57509 + size += sizeof(t_DsarArpStatistics);
57510 + //ICMPV4
57511 + size = ROUND_UP(size,4);
57512 + size += sizeof(t_DsarIcmpV4Descriptor);
57513 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
57514 + size += sizeof(t_DsarIcmpV4Statistics);
57515 + //ICMPV6
57516 + size = ROUND_UP(size,4);
57517 + size += sizeof(t_DsarIcmpV6Descriptor);
57518 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
57519 + size += sizeof(t_DsarIcmpV6Statistics);
57520 + //ND
57521 + size = ROUND_UP(size,4);
57522 + size += sizeof(t_DsarNdDescriptor);
57523 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
57524 + size += sizeof(t_DsarIcmpV6Statistics);
57525 + //SNMP
57526 + size = ROUND_UP(size,4);
57527 + size += sizeof(t_DsarSnmpDescriptor);
57528 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57529 + * params->maxNumOfSnmpIPV4Entries;
57530 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57531 + * params->maxNumOfSnmpIPV6Entries;
57532 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
57533 + size += params->maxNumOfSnmpOidChar;
57534 + size += sizeof(t_DsarIcmpV6Statistics);
57535 + //filters
57536 + size = ROUND_UP(size,4);
57537 + size += params->maxNumOfIpProtFiltering;
57538 + size = ROUND_UP(size,4);
57539 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
57540 + size = ROUND_UP(size,4);
57541 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
57542 +
57543 + // add here for more protocols
57544 +
57545 + // statistics
57546 + size = ROUND_UP(size,4);
57547 + size += sizeof(t_ArStatistics);
57548 +
57549 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
57550 +
57551 + param_page =
57552 + XX_PhysToVirt(
57553 + p_FmPort->fmMuramPhysBaseAddr
57554 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57555 + WRITE_UINT32(
57556 + *param_page,
57557 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
57558 + return E_OK;
57559 +}
57560 +
57561 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
57562 +{
57563 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57564 + return p_FmPort->deepSleepVars.autoResMaxSizes;
57565 +}
57566 +
57567 +struct arOffsets
57568 +{
57569 + uint32_t arp;
57570 + uint32_t nd;
57571 + uint32_t icmpv4;
57572 + uint32_t icmpv6;
57573 + uint32_t snmp;
57574 + uint32_t stats;
57575 + uint32_t filtIp;
57576 + uint32_t filtUdp;
57577 + uint32_t filtTcp;
57578 +};
57579 +
57580 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
57581 + struct t_FmPortDsarParams *params,
57582 + t_FmPort *p_FmPort)
57583 +{
57584 + uint32_t size = sizeof(t_ArCommonDesc);
57585 + // ARP
57586 + if (params->p_AutoResArpInfo)
57587 + {
57588 + size = ROUND_UP(size,4);
57589 + of->arp = size;
57590 + size += sizeof(t_DsarArpDescriptor);
57591 + size += sizeof(t_DsarArpBindingEntry)
57592 + * params->p_AutoResArpInfo->tableSize;
57593 + size += sizeof(t_DsarArpStatistics);
57594 + }
57595 + // ICMPV4
57596 + if (params->p_AutoResEchoIpv4Info)
57597 + {
57598 + size = ROUND_UP(size,4);
57599 + of->icmpv4 = size;
57600 + size += sizeof(t_DsarIcmpV4Descriptor);
57601 + size += sizeof(t_DsarIcmpV4BindingEntry)
57602 + * params->p_AutoResEchoIpv4Info->tableSize;
57603 + size += sizeof(t_DsarIcmpV4Statistics);
57604 + }
57605 + // ICMPV6
57606 + if (params->p_AutoResEchoIpv6Info)
57607 + {
57608 + size = ROUND_UP(size,4);
57609 + of->icmpv6 = size;
57610 + size += sizeof(t_DsarIcmpV6Descriptor);
57611 + size += sizeof(t_DsarIcmpV6BindingEntry)
57612 + * params->p_AutoResEchoIpv6Info->tableSize;
57613 + size += sizeof(t_DsarIcmpV6Statistics);
57614 + }
57615 + // ND
57616 + if (params->p_AutoResNdpInfo)
57617 + {
57618 + size = ROUND_UP(size,4);
57619 + of->nd = size;
57620 + size += sizeof(t_DsarNdDescriptor);
57621 + size += sizeof(t_DsarIcmpV6BindingEntry)
57622 + * (params->p_AutoResNdpInfo->tableSizeAssigned
57623 + + params->p_AutoResNdpInfo->tableSizeTmp);
57624 + size += sizeof(t_DsarIcmpV6Statistics);
57625 + }
57626 + // SNMP
57627 + if (params->p_AutoResSnmpInfo)
57628 + {
57629 + size = ROUND_UP(size,4);
57630 + of->snmp = size;
57631 + size += sizeof(t_DsarSnmpDescriptor);
57632 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
57633 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
57634 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
57635 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
57636 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
57637 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
57638 + size += sizeof(t_DsarIcmpV6Statistics);
57639 + }
57640 + //filters
57641 + size = ROUND_UP(size,4);
57642 + if (params->p_AutoResFilteringInfo)
57643 + {
57644 + of->filtIp = size;
57645 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
57646 + size = ROUND_UP(size,4);
57647 + of->filtUdp = size;
57648 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
57649 + * sizeof(t_PortTblEntry);
57650 + size = ROUND_UP(size,4);
57651 + of->filtTcp = size;
57652 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
57653 + * sizeof(t_PortTblEntry);
57654 + }
57655 + // add here for more protocols
57656 + // statistics
57657 + size = ROUND_UP(size,4);
57658 + of->stats = size;
57659 + size += sizeof(t_ArStatistics);
57660 + return size;
57661 +}
57662 +
57663 +uint32_t* ARDesc;
57664 +void PrsEnable(t_Handle p_FmPcd);
57665 +void PrsDisable(t_Handle p_FmPcd);
57666 +int PrsIsEnabled(t_Handle p_FmPcd);
57667 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
57668 +
57669 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
57670 + t_FmPortDsarTablesSizes *sizes)
57671 +{
57672 + bool macInit = FALSE;
57673 + uint8_t mac[6];
57674 + int i = 0;
57675 +
57676 + // check table sizes
57677 + if (params->p_AutoResArpInfo
57678 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
57679 + RETURN_ERROR(
57680 + MAJOR, E_INVALID_VALUE,
57681 + ("DSAR: Arp table size exceeds the configured maximum size."));
57682 + if (params->p_AutoResEchoIpv4Info
57683 + && sizes->maxNumOfEchoIpv4Entries
57684 + < params->p_AutoResEchoIpv4Info->tableSize)
57685 + RETURN_ERROR(
57686 + MAJOR,
57687 + E_INVALID_VALUE,
57688 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
57689 + if (params->p_AutoResNdpInfo
57690 + && sizes->maxNumOfNdpEntries
57691 + < params->p_AutoResNdpInfo->tableSizeAssigned
57692 + + params->p_AutoResNdpInfo->tableSizeTmp)
57693 + RETURN_ERROR(
57694 + MAJOR, E_INVALID_VALUE,
57695 + ("DSAR: NDP table size exceeds the configured maximum size."));
57696 + if (params->p_AutoResEchoIpv6Info
57697 + && sizes->maxNumOfEchoIpv6Entries
57698 + < params->p_AutoResEchoIpv6Info->tableSize)
57699 + RETURN_ERROR(
57700 + MAJOR,
57701 + E_INVALID_VALUE,
57702 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
57703 + if (params->p_AutoResSnmpInfo
57704 + && sizes->maxNumOfSnmpOidEntries
57705 + < params->p_AutoResSnmpInfo->oidsTblSize)
57706 + RETURN_ERROR(
57707 + MAJOR,
57708 + E_INVALID_VALUE,
57709 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
57710 + if (params->p_AutoResSnmpInfo
57711 + && sizes->maxNumOfSnmpIPV4Entries
57712 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
57713 + RETURN_ERROR(
57714 + MAJOR,
57715 + E_INVALID_VALUE,
57716 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
57717 + if (params->p_AutoResSnmpInfo
57718 + && sizes->maxNumOfSnmpIPV6Entries
57719 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
57720 + RETURN_ERROR(
57721 + MAJOR,
57722 + E_INVALID_VALUE,
57723 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
57724 + if (params->p_AutoResFilteringInfo)
57725 + {
57726 + if (sizes->maxNumOfIpProtFiltering
57727 + < params->p_AutoResFilteringInfo->ipProtTableSize)
57728 + RETURN_ERROR(
57729 + MAJOR,
57730 + E_INVALID_VALUE,
57731 + ("DSAR: ip filter table size exceeds the configured maximum size."));
57732 + if (sizes->maxNumOfTcpPortFiltering
57733 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
57734 + RETURN_ERROR(
57735 + MAJOR,
57736 + E_INVALID_VALUE,
57737 + ("DSAR: udp filter table size exceeds the configured maximum size."));
57738 + if (sizes->maxNumOfUdpPortFiltering
57739 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
57740 + RETURN_ERROR(
57741 + MAJOR,
57742 + E_INVALID_VALUE,
57743 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
57744 + }
57745 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
57746 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
57747 + {
57748 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
57749 + i = 1;
57750 + macInit = TRUE;
57751 +
57752 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
57753 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
57754 + RETURN_ERROR(
57755 + MAJOR, E_INVALID_VALUE,
57756 + ("DSAR: Only 1 mac address is currently supported."));
57757 + }
57758 + if (params->p_AutoResEchoIpv4Info
57759 + && params->p_AutoResEchoIpv4Info->tableSize)
57760 + {
57761 + i = 0;
57762 + if (!macInit)
57763 + {
57764 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
57765 + 6);
57766 + i = 1;
57767 + macInit = TRUE;
57768 + }
57769 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57770 + if (memcmp(mac,
57771 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
57772 + RETURN_ERROR(
57773 + MAJOR, E_INVALID_VALUE,
57774 + ("DSAR: Only 1 mac address is currently supported."));
57775 + }
57776 + if (params->p_AutoResEchoIpv6Info
57777 + && params->p_AutoResEchoIpv6Info->tableSize)
57778 + {
57779 + i = 0;
57780 + if (!macInit)
57781 + {
57782 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
57783 + 6);
57784 + i = 1;
57785 + macInit = TRUE;
57786 + }
57787 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57788 + if (memcmp(mac,
57789 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
57790 + RETURN_ERROR(
57791 + MAJOR, E_INVALID_VALUE,
57792 + ("DSAR: Only 1 mac address is currently supported."));
57793 + }
57794 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
57795 + {
57796 + i = 0;
57797 + if (!macInit)
57798 + {
57799 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
57800 + 6);
57801 + i = 1;
57802 + macInit = TRUE;
57803 + }
57804 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
57805 + if (memcmp(mac,
57806 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
57807 + 6))
57808 + RETURN_ERROR(
57809 + MAJOR, E_INVALID_VALUE,
57810 + ("DSAR: Only 1 mac address is currently supported."));
57811 + }
57812 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
57813 + {
57814 + i = 0;
57815 + if (!macInit)
57816 + {
57817 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
57818 + i = 1;
57819 + }
57820 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
57821 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
57822 + 6))
57823 + RETURN_ERROR(
57824 + MAJOR, E_INVALID_VALUE,
57825 + ("DSAR: Only 1 mac address is currently supported."));
57826 + }
57827 + return E_OK;
57828 +}
57829 +
57830 +static int GetBERLen(uint8_t* buf)
57831 +{
57832 + if (*buf & 0x80)
57833 + {
57834 + if ((*buf & 0x7F) == 1)
57835 + return buf[1];
57836 + else
57837 + return *(uint16_t*)&buf[1]; // assuming max len is 2
57838 + }
57839 + else
57840 + return buf[0];
57841 +}
57842 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
57843 +
57844 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
57845 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
57846 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
57847 +static int fm_soc_suspend(void)
57848 +{
57849 + uint32_t *fmclk, tmp32;
57850 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57851 + tmp32 = GET_UINT32(*fmclk);
57852 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
57853 + tmp32 = GET_UINT32(*fmclk);
57854 + iounmap(fmclk);
57855 + return 0;
57856 +}
57857 +
57858 +void fm_clk_down(void)
57859 +{
57860 + uint32_t *fmclk, tmp32;
57861 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
57862 + tmp32 = GET_UINT32(*fmclk);
57863 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
57864 + tmp32 = GET_UINT32(*fmclk);
57865 + iounmap(fmclk);
57866 +}
57867 +
57868 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
57869 +{
57870 + int i, j;
57871 + t_Error err;
57872 + uint32_t nia;
57873 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
57874 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
57875 + t_DsarArpDescriptor *ArpDescriptor;
57876 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
57877 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
57878 + t_DsarNdDescriptor* NDDescriptor;
57879 +
57880 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
57881 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
57882 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
57883 + struct arOffsets* of;
57884 + uint8_t tmp = 0;
57885 + t_FmGetSetParams fmGetSetParams;
57886 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
57887 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
57888 + fmGetSetParams.setParams.sleep = 1;
57889 +
57890 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
57891 + if (err != E_OK)
57892 + return err;
57893 +
57894 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
57895 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
57896 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
57897 +
57898 + // common
57899 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
57900 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
57901 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
57902 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
57903 + else
57904 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
57905 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
57906 +
57907 + // ARP
57908 + if (params->p_AutoResArpInfo)
57909 + {
57910 + t_DsarArpBindingEntry* arp_bindings;
57911 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
57912 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
57913 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
57914 + if (params->p_AutoResArpInfo->enableConflictDetection)
57915 + WRITE_UINT16(ArpDescriptor->control, 1);
57916 + else
57917 + WRITE_UINT16(ArpDescriptor->control, 0);
57918 + if (params->p_AutoResArpInfo->tableSize)
57919 + {
57920 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
57921 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57922 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57923 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
57924 +
57925 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
57926 + {
57927 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57928 + if (arp_entry[i].isVlan)
57929 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57930 + }
57931 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
57932 + }
57933 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
57934 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
57935 + }
57936 +
57937 + // ICMPV4
57938 + if (params->p_AutoResEchoIpv4Info)
57939 + {
57940 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
57941 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
57942 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
57943 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
57944 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
57945 + if (params->p_AutoResEchoIpv4Info->tableSize)
57946 + {
57947 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
57948 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
57949 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
57950 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
57951 +
57952 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
57953 + {
57954 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
57955 + if (arp_entry[i].isVlan)
57956 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
57957 + }
57958 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
57959 + }
57960 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
57961 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
57962 + }
57963 +
57964 + // ICMPV6
57965 + if (params->p_AutoResEchoIpv6Info)
57966 + {
57967 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57968 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
57969 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
57970 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
57971 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
57972 + if (params->p_AutoResEchoIpv6Info->tableSize)
57973 + {
57974 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
57975 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
57976 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
57977 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
57978 +
57979 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
57980 + {
57981 + for (j = 0; j < 4; j++)
57982 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
57983 + if (ndp_entry[i].isVlan)
57984 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
57985 + }
57986 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
57987 + }
57988 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
57989 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
57990 + }
57991 +
57992 + // ND
57993 + if (params->p_AutoResNdpInfo)
57994 + {
57995 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
57996 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
57997 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
57998 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
57999 + if (params->p_AutoResNdpInfo->enableConflictDetection)
58000 + WRITE_UINT16(NDDescriptor->control, 1);
58001 + else
58002 + WRITE_UINT16(NDDescriptor->control, 0);
58003 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
58004 + {
58005 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
58006 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
58007 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
58008 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
58009 + + params->p_AutoResNdpInfo->tableSizeTmp);
58010 +
58011 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
58012 + {
58013 + for (j = 0; j < 4; j++)
58014 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
58015 + if (ndp_entry[i].isVlan)
58016 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
58017 + }
58018 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
58019 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
58020 + {
58021 + for (j = 0; j < 4; j++)
58022 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
58023 + if (ndp_entry[i].isVlan)
58024 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
58025 + }
58026 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
58027 + }
58028 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
58029 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
58030 + - fmMuramVirtBaseAddr);
58031 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
58032 + }
58033 +
58034 + // SNMP
58035 + if (params->p_AutoResSnmpInfo)
58036 + {
58037 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
58038 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
58039 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
58040 + t_OidsTblEntry* snmpOid;
58041 + uint8_t *charPointer;
58042 + int len;
58043 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58044 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
58045 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
58046 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
58047 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
58048 + if (snmpSrc->numOfIpv4Addresses)
58049 + {
58050 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
58051 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
58052 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
58053 + {
58054 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
58055 + if (snmpIpv4AddrSrc[i].isVlan)
58056 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
58057 + }
58058 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
58059 + }
58060 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
58061 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
58062 + if (snmpSrc->numOfIpv6Addresses)
58063 + {
58064 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
58065 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
58066 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
58067 + {
58068 + for (j = 0; j < 4; j++)
58069 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
58070 + if (snmpIpv6AddrSrc[i].isVlan)
58071 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
58072 + }
58073 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
58074 + }
58075 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
58076 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
58077 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
58078 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
58079 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
58080 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
58081 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58082 + charPointer += len;
58083 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
58084 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
58085 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58086 + charPointer += len;
58087 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
58088 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
58089 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
58090 + {
58091 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
58092 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
58093 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
58094 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58095 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
58096 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
58097 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
58098 + else
58099 + {
58100 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
58101 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58102 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
58103 + }
58104 + snmpOid++;
58105 + }
58106 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
58107 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
58108 + }
58109 +
58110 + // filtering
58111 + if (params->p_AutoResFilteringInfo)
58112 + {
58113 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
58114 + tmp |= IP_PROT_TBL_PASS_MASK;
58115 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
58116 + tmp |= UDP_PORT_TBL_PASS_MASK;
58117 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
58118 + tmp |= TCP_PORT_TBL_PASS_MASK;
58119 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
58120 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
58121 +
58122 + // ip filtering
58123 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
58124 + {
58125 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
58126 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
58127 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
58128 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
58129 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
58130 + }
58131 +
58132 + // udp filtering
58133 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
58134 + {
58135 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
58136 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
58137 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
58138 + {
58139 + WRITE_UINT32(udp_tbl[i].Ports,
58140 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
58141 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
58142 + WRITE_UINT32(udp_tbl[i].PortsMask,
58143 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
58144 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
58145 + }
58146 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
58147 + }
58148 +
58149 + // tcp filtering
58150 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
58151 + {
58152 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
58153 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
58154 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
58155 + {
58156 + WRITE_UINT32(tcp_tbl[i].Ports,
58157 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
58158 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
58159 + WRITE_UINT32(tcp_tbl[i].PortsMask,
58160 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
58161 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
58162 + }
58163 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
58164 + }
58165 + }
58166 + // common stats
58167 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
58168 +
58169 + // get into Deep Sleep sequence:
58170 +
58171 + // Ensures that FMan do not enter the idle state. This is done by programing
58172 + // FMDPSLPCR[FM_STOP] to one.
58173 + fm_soc_suspend();
58174 +
58175 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
58176 + return E_OK;
58177 +
58178 +}
58179 +
58180 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
58181 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
58182 +{
58183 + t_FmGetSetParams fmGetSetParams;
58184 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
58185 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
58186 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58187 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58188 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58189 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
58190 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58191 +
58192 + /* Issue graceful stop to HC port */
58193 + FM_PORT_Disable(p_FmPortHc);
58194 +
58195 + // config tx port
58196 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
58197 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM | BMI_PORT_CFG_EN);
58198 + // ????
58199 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
58200 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
58201 + // Stage 7:echo
58202 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
58203 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
58204 + if (!PrsIsEnabled(h_FmPcd))
58205 + {
58206 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
58207 + PrsEnable(h_FmPcd);
58208 + }
58209 + else
58210 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
58211 +
58212 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
58213 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
58214 +
58215 + // save rcfg for restoring: accumulate mode is changed by ucode
58216 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
58217 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
58218 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58219 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58220 + fmGetSetParams.setParams.sleep = 1;
58221 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58222 +
58223 +// ***** issue external request sync command
58224 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58225 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
58226 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58227 + // get
58228 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58229 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
58230 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58231 + if (fmGetSetParams.getParams.fmfp_extc != 0)
58232 + {
58233 + // clear
58234 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58235 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
58236 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58237 +}
58238 +
58239 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58240 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
58241 + do
58242 + {
58243 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58244 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
58245 + if (fmGetSetParams.getParams.fm_npi != 0)
58246 + XX_Print("FM: Sync did not finish\n");
58247 +
58248 + // check that all stoped
58249 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58250 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
58251 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58252 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
58253 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58254 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
58255 + XX_Print("FM: Sleeping\n");
58256 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
58257 +
58258 + return E_OK;
58259 +}
58260 +
58261 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
58262 +
58263 +void FM_PORT_Dsar_DumpRegs()
58264 +{
58265 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
58266 + DUMP_MEMORY(hh, 0x220);
58267 +}
58268 +
58269 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
58270 +{
58271 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58272 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
58273 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
58274 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
58275 + t_FmGetSetParams fmGetSetParams;
58276 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
58277 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
58278 + fmGetSetParams.setParams.sleep = 0;
58279 + if (p_FmPort->deepSleepVars.autoResOffsets)
58280 + {
58281 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
58282 + p_FmPort->deepSleepVars.autoResOffsets = 0;
58283 + }
58284 +
58285 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
58286 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
58287 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
58288 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
58289 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
58290 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
58291 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
58292 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
58293 + FM_PORT_Enable(p_FmPortHc);
58294 +}
58295 +
58296 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
58297 +{
58298 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
58299 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
58300 +}
58301 +
58302 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
58303 +{
58304 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
58305 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
58306 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
58307 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
58308 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
58309 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
58310 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58311 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
58312 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58313 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
58314 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58315 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
58316 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
58317 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
58318 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
58319 + stats->arpArCnt = arp_stats->arCnt;
58320 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
58321 + stats->ndpArCnt = nd_stats->arCnt;
58322 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
58323 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
58324 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
58325 + return E_OK;
58326 +}
58327 --- /dev/null
58328 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
58329 @@ -0,0 +1,999 @@
58330 +/*
58331 + * Copyright 2008-2012 Freescale Semiconductor Inc.
58332 + *
58333 + * Redistribution and use in source and binary forms, with or without
58334 + * modification, are permitted provided that the following conditions are met:
58335 + * * Redistributions of source code must retain the above copyright
58336 + * notice, this list of conditions and the following disclaimer.
58337 + * * Redistributions in binary form must reproduce the above copyright
58338 + * notice, this list of conditions and the following disclaimer in the
58339 + * documentation and/or other materials provided with the distribution.
58340 + * * Neither the name of Freescale Semiconductor nor the
58341 + * names of its contributors may be used to endorse or promote products
58342 + * derived from this software without specific prior written permission.
58343 + *
58344 + *
58345 + * ALTERNATIVELY, this software may be distributed under the terms of the
58346 + * GNU General Public License ("GPL") as published by the Free Software
58347 + * Foundation, either version 2 of that License or (at your option) any
58348 + * later version.
58349 + *
58350 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
58351 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58352 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
58353 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
58354 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
58355 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58356 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58357 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
58358 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58359 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58360 + */
58361 +
58362 +
58363 +/******************************************************************************
58364 + @File fm_port.h
58365 +
58366 + @Description FM Port internal structures and definitions.
58367 +*//***************************************************************************/
58368 +#ifndef __FM_PORT_H
58369 +#define __FM_PORT_H
58370 +
58371 +#include "error_ext.h"
58372 +#include "std_ext.h"
58373 +#include "fm_port_ext.h"
58374 +
58375 +#include "fm_common.h"
58376 +#include "fm_sp_common.h"
58377 +#include "fsl_fman_sp.h"
58378 +#include "fm_port_ext.h"
58379 +#include "fsl_fman_port.h"
58380 +
58381 +#define __ERR_MODULE__ MODULE_FM_PORT
58382 +
58383 +
58384 +#define MIN_EXT_BUF_SIZE 64
58385 +#define DATA_ALIGNMENT 64
58386 +#define MAX_LIODN_OFFSET 64
58387 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
58388 +
58389 +/**************************************************************************//**
58390 + @Description Memory Map defines
58391 +*//***************************************************************************/
58392 +#define BMI_PORT_REGS_OFFSET 0
58393 +#define QMI_PORT_REGS_OFFSET 0x400
58394 +#define PRS_PORT_REGS_OFFSET 0x800
58395 +
58396 +/**************************************************************************//**
58397 + @Description defaults
58398 +*//***************************************************************************/
58399 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
58400 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
58401 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
58402 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
58403 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
58404 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
58405 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
58406 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
58407 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
58408 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
58409 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
58410 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
58411 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
58412 +#define DEFAULT_PORT_cutBytesFromEnd 4
58413 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
58414 +
58415 +#define DEFAULT_PORT_frmDiscardOverride FALSE
58416 +
58417 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
58418 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
58419 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
58420 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
58421 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
58422 +
58423 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
58424 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
58425 +#define DEFAULT_PORT_BufMargins_startMargins 32
58426 +#define DEFAULT_PORT_BufMargins_endMargins 0
58427 +#define DEFAULT_PORT_syncReq TRUE
58428 +#define DEFAULT_PORT_syncReqForHc FALSE
58429 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
58430 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
58431 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
58432 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
58433 +#define DEFAULT_PORT_exception IM_EV_BSY
58434 +#define DEFAULT_PORT_maxFrameLength 9600
58435 +
58436 +#define DEFAULT_notSupported 0xff
58437 +
58438 +#if (DPAA_VERSION < 11)
58439 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58440 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
58441 +
58442 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58443 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
58444 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
58445 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58446 +
58447 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58448 +
58449 +/* Host command port MUST NOT be changed to more than 1 !!! */
58450 +#define DEFAULT_PORT_numOfTasks(type) \
58451 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58452 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
58453 + ((((type) == e_FM_PORT_TYPE_RX) || \
58454 + ((type) == e_FM_PORT_TYPE_TX) || \
58455 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
58456 +
58457 +#define DEFAULT_PORT_extraNumOfTasks(type) \
58458 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58459 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
58460 +
58461 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58462 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
58463 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
58464 +
58465 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
58466 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58467 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
58468 +
58469 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58470 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58471 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
58472 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
58473 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
58474 +
58475 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58476 +
58477 +#else /* (DPAA_VERSION < 11) */
58478 +/* Defaults are registers' reset values */
58479 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
58480 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
58481 +
58482 +#define DEFAULT_PORT_txFifoMinFillLevel 0
58483 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
58484 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
58485 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
58486 +
58487 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
58488 +
58489 +#define DEFAULT_PORT_numOfTasks(type) \
58490 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
58491 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
58492 + (((type) == e_FM_PORT_TYPE_RX) || \
58493 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
58494 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
58495 +
58496 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
58497 +
58498 +#define DEFAULT_PORT_numOfOpenDmas(type) \
58499 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
58500 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
58501 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
58502 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
58503 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
58504 +
58505 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
58506 +
58507 +#define DEFAULT_PORT_numOfFifoBufs(type) \
58508 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
58509 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
58510 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
58511 +
58512 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
58513 +
58514 +#endif /* (DPAA_VERSION < 11) */
58515 +
58516 +#define DEFAULT_PORT_txBdRingLength 16
58517 +#define DEFAULT_PORT_rxBdRingLength 128
58518 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
58519 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
58520 +
58521 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58522 +
58523 +/**************************************************************************//**
58524 + @Collection PCD Engines
58525 +*//***************************************************************************/
58526 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
58527 +
58528 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
58529 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
58530 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
58531 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
58532 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
58533 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
58534 +/* @} */
58535 +
58536 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
58537 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
58538 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
58539 +
58540 +#define FM_OH_PORT_ID 0
58541 +
58542 +/***********************************************************************/
58543 +/* SW parser OFFLOAD labels (offsets) */
58544 +/***********************************************************************/
58545 +#if (DPAA_VERSION == 10)
58546 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
58547 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
58548 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
58549 +#else
58550 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
58551 +/* Will be used for:
58552 + * 1. identify fragments
58553 + * 2. udp-lite
58554 + */
58555 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
58556 +/* Will be used for:
58557 + * 1. will identify the fragmentable area
58558 + * 2. udp-lite
58559 + */
58560 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
58561 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
58562 +#endif /* (DPAA_VERSION == 10) */
58563 +
58564 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
58565 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
58566 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
58567 +
58568 +
58569 +/**************************************************************************//**
58570 + @Description Memory Mapped Registers
58571 +*//***************************************************************************/
58572 +
58573 +#if defined(__MWERKS__) && !defined(__GNUC__)
58574 +#pragma pack(push,1)
58575 +#endif /* defined(__MWERKS__) && ... */
58576 +
58577 +typedef struct
58578 +{
58579 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
58580 + volatile uint32_t fmbm_rst; /**< Rx Status */
58581 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
58582 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
58583 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
58584 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
58585 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
58586 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
58587 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
58588 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
58589 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
58590 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
58591 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
58592 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
58593 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
58594 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
58595 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58596 + /**< Rx Parse Results Array Initialization*/
58597 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
58598 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
58599 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
58600 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
58601 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
58602 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
58603 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
58604 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
58605 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58606 + /**< Buffer Manager pool Information-*/
58607 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
58608 + /**< Allocate Counter-*/
58609 + volatile uint32_t reserved4[0x08];
58610 + /**< 0x130/0x140 - 0x15F reserved -*/
58611 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
58612 + /**< Congestion Group Map*/
58613 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
58614 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
58615 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
58616 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
58617 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
58618 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
58619 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
58620 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
58621 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
58622 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
58623 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
58624 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
58625 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
58626 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
58627 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
58628 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
58629 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
58630 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
58631 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
58632 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
58633 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
58634 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
58635 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
58636 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
58637 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
58638 +} t_FmPortRxBmiRegs;
58639 +
58640 +typedef struct
58641 +{
58642 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
58643 + volatile uint32_t fmbm_tst; /**< Tx Status */
58644 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
58645 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
58646 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
58647 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
58648 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
58649 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
58650 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
58651 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
58652 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
58653 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
58654 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
58655 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
58656 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
58657 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
58658 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
58659 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
58660 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
58661 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
58662 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
58663 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
58664 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
58665 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
58666 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
58667 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
58668 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
58669 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
58670 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
58671 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
58672 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
58673 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
58674 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
58675 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
58676 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
58677 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
58678 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
58679 +} t_FmPortTxBmiRegs;
58680 +
58681 +typedef struct
58682 +{
58683 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
58684 + volatile uint32_t fmbm_ost; /**< O/H Status */
58685 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
58686 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
58687 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
58688 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
58689 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
58690 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
58691 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
58692 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
58693 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
58694 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
58695 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
58696 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
58697 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
58698 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
58699 + /**< O/H Parse Results Array Initialization */
58700 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
58701 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
58702 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
58703 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
58704 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
58705 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
58706 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
58707 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
58708 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
58709 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
58710 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
58711 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
58712 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
58713 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
58714 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
58715 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
58716 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
58717 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
58718 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
58719 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
58720 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
58721 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
58722 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
58723 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
58724 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
58725 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
58726 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
58727 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
58728 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
58729 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
58730 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
58731 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
58732 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
58733 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
58734 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
58735 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
58736 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
58737 +} t_FmPortOhBmiRegs;
58738 +
58739 +typedef union
58740 +{
58741 + t_FmPortRxBmiRegs rxPortBmiRegs;
58742 + t_FmPortTxBmiRegs txPortBmiRegs;
58743 + t_FmPortOhBmiRegs ohPortBmiRegs;
58744 +} u_FmPortBmiRegs;
58745 +
58746 +typedef struct
58747 +{
58748 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
58749 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
58750 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
58751 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
58752 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
58753 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
58754 +} t_FmPortNonRxQmiRegs;
58755 +
58756 +typedef struct
58757 +{
58758 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
58759 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
58760 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
58761 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
58762 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
58763 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
58764 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
58765 +} t_FmPortQmiRegs;
58766 +
58767 +typedef struct
58768 +{
58769 + struct
58770 + {
58771 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
58772 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
58773 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
58774 + volatile uint32_t reserved0[0xde];
58775 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
58776 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
58777 +} t_FmPortPrsRegs;
58778 +
58779 +/**************************************************************************//*
58780 + @Description Basic buffer descriptor (BD) structure
58781 +*//***************************************************************************/
58782 +typedef _Packed struct
58783 +{
58784 + volatile uint16_t status;
58785 + volatile uint16_t length;
58786 + volatile uint8_t reserved0[0x6];
58787 + volatile uint8_t reserved1[0x1];
58788 + volatile t_FmPhysAddr buff;
58789 +} _PackedType t_FmImBd;
58790 +
58791 +typedef _Packed struct
58792 +{
58793 + volatile uint16_t gen; /**< tbd */
58794 + volatile uint8_t reserved0[0x1];
58795 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
58796 + volatile uint16_t bdRingSize; /**< tbd */
58797 + volatile uint16_t offsetIn; /**< tbd */
58798 + volatile uint16_t offsetOut; /**< tbd */
58799 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
58800 +} _PackedType t_FmPortImQd;
58801 +
58802 +typedef _Packed struct
58803 +{
58804 + volatile uint32_t mode; /**< Mode register */
58805 + volatile uint32_t rxQdPtr; /**< tbd */
58806 + volatile uint32_t txQdPtr; /**< tbd */
58807 + volatile uint16_t mrblr; /**< tbd */
58808 + volatile uint16_t rxQdBsyCnt; /**< tbd */
58809 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
58810 + t_FmPortImQd rxQd;
58811 + t_FmPortImQd txQd;
58812 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
58813 +} _PackedType t_FmPortImPram;
58814 +
58815 +#if defined(__MWERKS__) && !defined(__GNUC__)
58816 +#pragma pack(pop)
58817 +#endif /* defined(__MWERKS__) && ... */
58818 +
58819 +
58820 +/**************************************************************************//**
58821 + @Description Registers bit fields
58822 +*//***************************************************************************/
58823 +
58824 +/**************************************************************************//**
58825 + @Description BMI defines
58826 +*//***************************************************************************/
58827 +#if (DPAA_VERSION >= 11)
58828 +#define BMI_SP_ID_MASK 0xff000000
58829 +#define BMI_SP_ID_SHIFT 24
58830 +#define BMI_SP_EN 0x01000000
58831 +#endif /* (DPAA_VERSION >= 11) */
58832 +
58833 +#define BMI_PORT_CFG_EN 0x80000000
58834 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
58835 +#define BMI_PORT_CFG_FDOVR 0x02000000
58836 +#define BMI_PORT_CFG_IM 0x01000000
58837 +#define BMI_PORT_CFG_AM 0x00000040
58838 +#define BMI_PORT_STATUS_BSY 0x80000000
58839 +#define BMI_COUNTERS_EN 0x80000000
58840 +
58841 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
58842 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
58843 +#define BMI_RFNE_FDCS_MASK 0xFF000000
58844 +#define BMI_RFNE_HXS_MASK 0x000000FF
58845 +
58846 +#define BMI_CMD_MR_LEAC 0x00200000
58847 +#define BMI_CMD_MR_SLEAC 0x00100000
58848 +#define BMI_CMD_MR_MA 0x00080000
58849 +#define BMI_CMD_MR_DEAS 0x00040000
58850 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
58851 + BMI_CMD_MR_SLEAC | \
58852 + BMI_CMD_MR_MA | \
58853 + BMI_CMD_MR_DEAS)
58854 +#define BMI_CMD_ATTR_ORDER 0x80000000
58855 +#define BMI_CMD_ATTR_SYNC 0x02000000
58856 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
58857 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
58858 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
58859 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
58860 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
58861 +
58862 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
58863 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
58864 + FM_PORT_FRM_ERR_PHYSICAL | \
58865 + FM_PORT_FRM_ERR_SIZE | \
58866 + FM_PORT_FRM_ERR_CLS_DISCARD | \
58867 + FM_PORT_FRM_ERR_EXTRACTION | \
58868 + FM_PORT_FRM_ERR_NO_SCHEME | \
58869 + FM_PORT_FRM_ERR_COLOR_RED | \
58870 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
58871 + FM_PORT_FRM_ERR_ILL_PLCR | \
58872 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58873 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58874 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58875 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58876 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58877 + FM_PORT_FRM_ERR_IPRE | \
58878 + FM_PORT_FRM_ERR_IPR_NCSP | \
58879 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
58880 +
58881 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
58882 + ~(FM_PORT_FRM_ERR_LENGTH | \
58883 + FM_PORT_FRM_ERR_NON_FM | \
58884 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
58885 +
58886 +#define BMI_RATE_LIMIT_EN 0x80000000
58887 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
58888 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
58889 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
58890 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
58891 +
58892 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
58893 +
58894 +#define BMI_PRS_RESULT_HIGH 0x00000000
58895 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
58896 +
58897 +
58898 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
58899 + FM_PORT_FRM_ERR_PHYSICAL | \
58900 + FM_PORT_FRM_ERR_SIZE | \
58901 + FM_PORT_FRM_ERR_EXTRACTION | \
58902 + FM_PORT_FRM_ERR_NO_SCHEME | \
58903 + FM_PORT_FRM_ERR_ILL_PLCR | \
58904 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
58905 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
58906 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
58907 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
58908 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
58909 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
58910 + FM_PORT_FRM_ERR_IPRE)
58911 +
58912 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
58913 + FM_PORT_FRM_ERR_LENGTH | \
58914 + FM_PORT_FRM_ERR_NON_FM | \
58915 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
58916 +
58917 +
58918 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
58919 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
58920 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
58921 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
58922 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
58923 +
58924 +/* shifts */
58925 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
58926 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
58927 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
58928 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
58929 +
58930 +#define BMI_IM_FOF_SHIFT 28
58931 +#define BMI_PR_PORTID_SHIFT 24
58932 +
58933 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
58934 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
58935 +
58936 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
58937 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
58938 +
58939 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
58940 +
58941 +#define BMI_INT_BUF_MARG_SHIFT 28
58942 +
58943 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
58944 +
58945 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
58946 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
58947 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
58948 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
58949 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
58950 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
58951 +
58952 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
58953 +
58954 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
58955 +#define BMI_TX_LOW_COMF_SHIFT 0
58956 +
58957 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
58958 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
58959 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
58960 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
58961 +
58962 +#define BMI_MAX_BURST_SHIFT 16
58963 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
58964 +
58965 +/* sizes */
58966 +#define FRAME_END_DATA_SIZE 16
58967 +#define FRAME_OFFSET_UNITS 16
58968 +#define MIN_TX_INT_OFFSET 16
58969 +#define MAX_FRAME_OFFSET 64
58970 +#define MAX_FIFO_PIPELINE_DEPTH 8
58971 +#define MAX_PERFORMANCE_TASK_COMP 64
58972 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
58973 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
58974 +#define MAX_PERFORMANCE_DMA_COMP 16
58975 +#define MAX_NUM_OF_TASKS 64
58976 +#define MAX_NUM_OF_EXTRA_TASKS 8
58977 +#define MAX_NUM_OF_DMAS 16
58978 +#define MAX_NUM_OF_EXTRA_DMAS 8
58979 +#define MAX_BURST_SIZE 1024
58980 +#define MIN_NUM_OF_OP_DMAS 2
58981 +
58982 +
58983 +/**************************************************************************//**
58984 + @Description QMI defines
58985 +*//***************************************************************************/
58986 +/* masks */
58987 +#define QMI_PORT_CFG_EN 0x80000000
58988 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
58989 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
58990 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
58991 +
58992 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
58993 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
58994 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
58995 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
58996 +
58997 +#define QMI_DEQ_CFG_PRI 0x80000000
58998 +#define QMI_DEQ_CFG_TYPE1 0x10000000
58999 +#define QMI_DEQ_CFG_TYPE2 0x20000000
59000 +#define QMI_DEQ_CFG_TYPE3 0x30000000
59001 +
59002 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
59003 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
59004 +
59005 +/**************************************************************************//**
59006 + @Description PARSER defines
59007 +*//***************************************************************************/
59008 +/* masks */
59009 +#define PRS_HDR_ERROR_DIS 0x00000800
59010 +#define PRS_HDR_SW_PRS_EN 0x00000400
59011 +#define PRS_CP_OFFSET_MASK 0x0000000F
59012 +#define PRS_TPID1_MASK 0xFFFF0000
59013 +#define PRS_TPID2_MASK 0x0000FFFF
59014 +#define PRS_TPID_DFLT 0x91009100
59015 +
59016 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
59017 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
59018 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
59019 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
59020 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
59021 +#define PRS_CAC_STOP 0x00000001
59022 +#define PRS_CAC_ACTIVE 0x00000100
59023 +
59024 +/* shifts */
59025 +#define PRS_PCTPID_SHIFT 16
59026 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
59027 +#define PRS_HDR_ETH_BC_SHIFT 28
59028 +#define PRS_HDR_ETH_MC_SHIFT 24
59029 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
59030 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
59031 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
59032 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
59033 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
59034 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
59035 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
59036 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
59037 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
59038 +
59039 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
59040 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
59041 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
59042 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
59043 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
59044 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
59045 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
59046 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
59047 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
59048 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
59049 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
59050 +
59051 +/* others */
59052 +#define PRS_HDR_ENTRY_SIZE 8
59053 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
59054 +
59055 +#define IPSEC_SW_PATCH_START 0x20
59056 +#define SCTP_SW_PATCH_START 0x4D
59057 +#define DCCP_SW_PATCH_START 0x41
59058 +
59059 +/**************************************************************************//**
59060 + @Description IM defines
59061 +*//***************************************************************************/
59062 +#define BD_R_E 0x80000000
59063 +#define BD_L 0x08000000
59064 +
59065 +#define BD_RX_CRE 0x00080000
59066 +#define BD_RX_FTL 0x00040000
59067 +#define BD_RX_FTS 0x00020000
59068 +#define BD_RX_OV 0x00010000
59069 +
59070 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
59071 +
59072 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
59073 +
59074 +#define BD_STATUS_MASK 0xffff0000
59075 +#define BD_LENGTH_MASK 0x0000ffff
59076 +
59077 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
59078 +
59079 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
59080 +
59081 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
59082 +
59083 +#define IM_ILEGAL_BD_ID 0xffff
59084 +
59085 +/* others */
59086 +#define IM_PRAM_ALIGN 0x100
59087 +
59088 +/* masks */
59089 +#define IM_MODE_GBL 0x20000000
59090 +#define IM_MODE_BO_MASK 0x18000000
59091 +#define IM_MODE_BO_SHIFT 3
59092 +#define IM_MODE_GRC_STP 0x00800000
59093 +
59094 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
59095 +
59096 +#define IM_RXQD_BSYINTM 0x0008
59097 +#define IM_RXQD_RXFINTM 0x0010
59098 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
59099 +
59100 +#define IM_EV_BSY 0x40000000
59101 +#define IM_EV_RX 0x80000000
59102 +
59103 +
59104 +/**************************************************************************//**
59105 + @Description Additional defines
59106 +*//***************************************************************************/
59107 +
59108 +typedef struct {
59109 + t_Handle h_FmMuram;
59110 + t_FmPortImPram *p_FmPortImPram;
59111 + uint8_t fwExtStructsMemId;
59112 + uint32_t fwExtStructsMemAttr;
59113 + uint16_t bdRingSize;
59114 + t_FmImBd *p_BdRing;
59115 + t_Handle *p_BdShadow;
59116 + uint16_t currBdId;
59117 + uint16_t firstBdOfFrameId;
59118 +
59119 + /* Rx port parameters */
59120 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
59121 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
59122 + t_BufferPoolInfo rxPool;
59123 + uint16_t mrblr;
59124 + uint16_t rxFrameAccumLength;
59125 + t_FmPortImRxStoreCallback *f_RxStore;
59126 +
59127 + /* Tx port parameters */
59128 + uint32_t txFirstBdStatus;
59129 + t_FmPortImTxConfCallback *f_TxConf;
59130 +} t_FmMacIm;
59131 +
59132 +
59133 +typedef struct {
59134 + struct fman_port_cfg dfltCfg;
59135 + uint32_t dfltFqid;
59136 + uint32_t confFqid;
59137 + uint32_t errFqid;
59138 + uintptr_t baseAddr;
59139 + uint8_t deqSubPortal;
59140 + bool deqHighPriority;
59141 + e_FmPortDeqType deqType;
59142 + e_FmPortDeqPrefetchOption deqPrefetchOption;
59143 + uint16_t deqByteCnt;
59144 + uint8_t cheksumLastBytesIgnore;
59145 + uint8_t cutBytesFromEnd;
59146 + t_FmBufPoolDepletion bufPoolDepletion;
59147 + uint8_t pipelineDepth;
59148 + uint16_t fifoLowComfLevel;
59149 + bool frmDiscardOverride;
59150 + bool enRateLimit;
59151 + t_FmPortRateLimit rateLimit;
59152 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
59153 + bool enBufPoolDepletion;
59154 + uint16_t liodnOffset;
59155 + uint16_t liodnBase;
59156 + t_FmExtPools extBufPools;
59157 + e_FmDmaSwapOption dmaSwapData;
59158 + e_FmDmaCacheOption dmaIntContextCacheAttr;
59159 + e_FmDmaCacheOption dmaHeaderCacheAttr;
59160 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
59161 + bool dmaReadOptimize;
59162 + bool dmaWriteOptimize;
59163 + uint32_t txFifoMinFillLevel;
59164 + uint32_t txFifoLowComfLevel;
59165 + uint32_t rxFifoPriElevationLevel;
59166 + uint32_t rxFifoThreshold;
59167 + t_FmSpBufMargins bufMargins;
59168 + t_FmSpIntContextDataCopy intContext;
59169 + bool syncReq;
59170 + e_FmPortColor color;
59171 + fmPortFrameErrSelect_t errorsToDiscard;
59172 + fmPortFrameErrSelect_t errorsToEnq;
59173 + bool forwardReuseIntContext;
59174 + t_FmBufferPrefixContent bufferPrefixContent;
59175 + t_FmBackupBmPools *p_BackupBmPools;
59176 + bool dontReleaseBuf;
59177 + bool setNumOfTasks;
59178 + bool setNumOfOpenDmas;
59179 + bool setSizeOfFifo;
59180 +#if (DPAA_VERSION >= 11)
59181 + bool noScatherGather;
59182 +#endif /* (DPAA_VERSION >= 11) */
59183 +
59184 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
59185 + bool bcbWorkaround;
59186 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
59187 +} t_FmPortDriverParam;
59188 +
59189 +
59190 +typedef struct t_FmPortRxPoolsParams
59191 +{
59192 + uint8_t numOfPools;
59193 + uint16_t secondLargestBufSize;
59194 + uint16_t largestBufSize;
59195 +} t_FmPortRxPoolsParams;
59196 +
59197 +typedef struct t_FmPortDsarVars {
59198 + t_Handle *autoResOffsets;
59199 + t_FmPortDsarTablesSizes *autoResMaxSizes;
59200 + uint32_t fmbm_tcfg;
59201 + uint32_t fmbm_tcmne;
59202 + uint32_t fmbm_rfne;
59203 + uint32_t fmbm_rfpne;
59204 + uint32_t fmbm_rcfg;
59205 + bool dsarEnabledParser;
59206 +} t_FmPortDsarVars;
59207 +typedef struct {
59208 + struct fman_port port;
59209 + t_Handle h_Fm;
59210 + t_Handle h_FmPcd;
59211 + t_Handle h_FmMuram;
59212 + t_FmRevisionInfo fmRevInfo;
59213 + uint8_t portId;
59214 + e_FmPortType portType;
59215 + int enabled;
59216 + char name[MODULE_NAME_SIZE];
59217 + uint8_t hardwarePortId;
59218 + uint16_t fmClkFreq;
59219 + t_FmPortQmiRegs *p_FmPortQmiRegs;
59220 + u_FmPortBmiRegs *p_FmPortBmiRegs;
59221 + t_FmPortPrsRegs *p_FmPortPrsRegs;
59222 + fmPcdEngines_t pcdEngines;
59223 + uint32_t savedBmiNia;
59224 + uint8_t netEnvId;
59225 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
59226 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
59227 + uint8_t privateInfo;
59228 + uint32_t schemesPerPortVector;
59229 + bool useClsPlan;
59230 + uint8_t clsPlanGrpId;
59231 + t_Handle ccTreeId;
59232 + t_Handle completeArg;
59233 + void (*f_Complete)(t_Handle arg);
59234 + t_FmSpBufferOffsets bufferOffsets;
59235 + /* Independent-Mode parameters support */
59236 + bool imEn;
59237 + t_FmMacIm im;
59238 + volatile bool lock;
59239 + t_Handle h_Spinlock;
59240 + t_FmPortExceptionCallback *f_Exception;
59241 + t_Handle h_App;
59242 + uint8_t internalBufferOffset;
59243 + uint8_t fmanCtrlEventId;
59244 + uint32_t exceptions;
59245 + bool polling;
59246 + t_FmExtPools extBufPools;
59247 + uint32_t requiredAction;
59248 + uint32_t savedQmiPnen;
59249 + uint32_t savedBmiFene;
59250 + uint32_t savedBmiFpne;
59251 + uint32_t savedBmiCmne;
59252 + uint32_t savedBmiOfp;
59253 + uint32_t savedNonRxQmiRegsPndn;
59254 + uint32_t origNonRxQmiRegsPndn;
59255 + int savedPrsStartOffset;
59256 + bool includeInPrsStatistics;
59257 + uint16_t maxFrameLength;
59258 + t_FmFmanCtrl orFmanCtrl;
59259 + t_FmPortRsrc openDmas;
59260 + t_FmPortRsrc tasks;
59261 + t_FmPortRsrc fifoBufs;
59262 + t_FmPortRxPoolsParams rxPoolsParams;
59263 +// bool explicitUserSizeOfFifo;
59264 + t_Handle h_IpReassemblyManip;
59265 + t_Handle h_CapwapReassemblyManip;
59266 + t_Handle h_ReassemblyTree;
59267 + uint64_t fmMuramPhysBaseAddr;
59268 +#if (DPAA_VERSION >= 11)
59269 + bool vspe;
59270 + uint8_t dfltRelativeId;
59271 + e_FmPortGprFuncType gprFunc;
59272 + t_FmPcdCtrlParamsPage *p_ParamsPage;
59273 +#endif /* (DPAA_VERSION >= 11) */
59274 + t_FmPortDsarVars deepSleepVars;
59275 + t_FmPortDriverParam *p_FmPortDriverParam;
59276 +} t_FmPort;
59277 +
59278 +
59279 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
59280 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
59281 +
59282 +t_Error FmPortImInit(t_FmPort *p_FmPort);
59283 +void FmPortImFree(t_FmPort *p_FmPort);
59284 +
59285 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
59286 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
59287 +t_Error FmPortImRx (t_FmPort *p_FmPort);
59288 +
59289 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
59290 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
59291 +
59292 +
59293 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
59294 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
59295 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
59296 +
59297 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
59298 +{
59299 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
59300 + physAddr |= GET_UINT32(p_Bd->buff.low);
59301 +
59302 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
59303 +}
59304 +
59305 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
59306 +{
59307 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
59308 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
59309 +}
59310 +
59311 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
59312 +{
59313 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
59314 + SET_ADDR(&p_Bd->buff, physAddr);
59315 +}
59316 +
59317 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
59318 +{
59319 + if (id < p_FmPort->im.bdRingSize-1)
59320 + return (uint16_t)(id+1);
59321 + else
59322 + return 0;
59323 +}
59324 +
59325 +void FM_PORT_Dsar_DumpRegs(void);
59326 +
59327 +
59328 +#endif /* __FM_PORT_H */
59329 --- /dev/null
59330 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
59331 @@ -0,0 +1,494 @@
59332 +/*
59333 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59334 + *
59335 + * Redistribution and use in source and binary forms, with or without
59336 + * modification, are permitted provided that the following conditions are met:
59337 + * * Redistributions of source code must retain the above copyright
59338 + * notice, this list of conditions and the following disclaimer.
59339 + * * Redistributions in binary form must reproduce the above copyright
59340 + * notice, this list of conditions and the following disclaimer in the
59341 + * documentation and/or other materials provided with the distribution.
59342 + * * Neither the name of Freescale Semiconductor nor the
59343 + * names of its contributors may be used to endorse or promote products
59344 + * derived from this software without specific prior written permission.
59345 + *
59346 + *
59347 + * ALTERNATIVELY, this software may be distributed under the terms of the
59348 + * GNU General Public License ("GPL") as published by the Free Software
59349 + * Foundation, either version 2 of that License or (at your option) any
59350 + * later version.
59351 + *
59352 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59353 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59354 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59355 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59356 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59357 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59358 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59359 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59360 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59361 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59362 + */
59363 +
59364 +/**************************************************************************//**
59365 + @File fm_port_dsar.h
59366 +
59367 + @Description Deep Sleep Auto Response project - common module header file.
59368 +
59369 + Author - Eyal Harari
59370 +
59371 + @Cautions See the FMan Controller spec and design document for more information.
59372 +*//***************************************************************************/
59373 +
59374 +#ifndef __FM_PORT_DSAR_H_
59375 +#define __FM_PORT_DSAR_H_
59376 +
59377 +#define DSAR_GETSER_MASK 0xFF0000FF
59378 +
59379 +#if defined(__MWERKS__) && !defined(__GNUC__)
59380 +#pragma pack(push,1)
59381 +#endif /* defined(__MWERKS__) && ... */
59382 +
59383 +/**************************************************************************//**
59384 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59385 + Refer to the FMan Controller spec for more details.
59386 +*//***************************************************************************/
59387 +typedef _Packed struct
59388 +{
59389 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59390 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59391 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59392 + uint16_t reserved;
59393 +} _PackedType t_DsarArpBindingEntry;
59394 +
59395 +/**************************************************************************//**
59396 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
59397 + Refer to the FMan Controller spec for more details.
59398 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
59399 + 0x04 ECHO_CNT Echo counter
59400 + 0x08 CD_CNT Conflict Detection counter
59401 + 0x0C AR_CNT Auto-Response counter
59402 + 0x10 RATM_CNT Replies Addressed To Me counter
59403 + 0x14 UKOP_CNT Unknown Operation counter
59404 + 0x18 NMTP_CNT Not my TPA counter
59405 + 0x1C NMVLAN_CNT Not My VLAN counter
59406 +*//***************************************************************************/
59407 +typedef _Packed struct
59408 +{
59409 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
59410 + uint32_t echoCnt; /**< Echo counter. */
59411 + uint32_t cdCnt; /**< Conflict Detection counter. */
59412 + uint32_t arCnt; /**< Auto-Response counter. */
59413 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
59414 + uint32_t ukopCnt; /**< Unknown Operation counter. */
59415 + uint32_t nmtpCnt; /**< Not my TPA counter. */
59416 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59417 +} _PackedType t_DsarArpStatistics;
59418 +
59419 +
59420 +/**************************************************************************//**
59421 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
59422 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
59423 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59424 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
59425 + 0x6 0-15
59426 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
59427 + 0xA 0-15
59428 + 0xC 0-15 Reserved Reserved. Must be cleared.
59429 + 0xE 015
59430 +
59431 +*//***************************************************************************/
59432 +typedef _Packed struct
59433 +{
59434 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
59435 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59436 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59437 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59438 + uint32_t reserved1; /**< Reserved. */
59439 +} _PackedType t_DsarArpDescriptor;
59440 +
59441 +
59442 +/**************************************************************************//**
59443 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59444 + Refer to the FMan Controller spec for more details.
59445 +*//***************************************************************************/
59446 +typedef _Packed struct
59447 +{
59448 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59449 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59450 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59451 + uint16_t reserved;
59452 +} _PackedType t_DsarIcmpV4BindingEntry;
59453 +
59454 +/**************************************************************************//**
59455 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59456 + Refer to the FMan Controller spec for more details.
59457 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59458 + 0x04 NMVLAN_CNT Not My VLAN counter
59459 + 0x08 NMIP_CNT Not My IP counter
59460 + 0x0C AR_CNT Auto-Response counter
59461 + 0x10 CSERR_CNT Checksum Error counter
59462 + 0x14 Reserved Reserved
59463 + 0x18 Reserved Reserved
59464 + 0x1C Reserved Reserved
59465 +
59466 +*//***************************************************************************/
59467 +typedef _Packed struct
59468 +{
59469 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59470 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59471 + uint32_t nmIpCnt; /**< Not My IP counter */
59472 + uint32_t arCnt; /**< Auto-Response counter */
59473 + uint32_t cserrCnt; /**< Checksum Error counter */
59474 + uint32_t reserved0; /**< Reserved */
59475 + uint32_t reserved1; /**< Reserved */
59476 + uint32_t reserved2; /**< Reserved */
59477 +} _PackedType t_DsarIcmpV4Statistics;
59478 +
59479 +
59480 +
59481 +/**************************************************************************//**
59482 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
59483 + 0x0 0-15 Control bits [0-15]
59484 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59485 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59486 + 0x6 0-15
59487 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59488 + 0xA 0-15
59489 + 0xC 0-15 Reserved Reserved. Must be cleared.
59490 + 0xE 015
59491 +
59492 +*//***************************************************************************/
59493 +typedef _Packed struct
59494 +{
59495 + uint16_t control; /** Control bits [0-15]. */
59496 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
59497 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59498 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59499 + uint32_t reserved1; /**< Reserved. */
59500 +} _PackedType t_DsarIcmpV4Descriptor;
59501 +
59502 +/**************************************************************************//**
59503 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
59504 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
59505 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
59506 + Flags[0] (VlanId[12]): Temporary address.
59507 + \95 0 - Assigned IP address.
59508 + \95 1- Temporary (tentative) IP address.
59509 + Refer to the FMan Controller spec for more details.
59510 +*//***************************************************************************/
59511 +typedef _Packed struct
59512 +{
59513 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
59514 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
59515 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
59516 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
59517 + uint16_t reserved;
59518 +} _PackedType t_DsarIcmpV6BindingEntry;
59519 +
59520 +/**************************************************************************//**
59521 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
59522 + Refer to the FMan Controller spec for more details.
59523 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
59524 + 0x04 NMVLAN_CNT Not My VLAN counter
59525 + 0x08 NMIP_CNT Not My IP counter
59526 + 0x0C AR_CNT Auto-Response counter
59527 + 0x10 CSERR_CNT Checksum Error counter
59528 + 0x14 MCAST_CNT Multicast counter
59529 + 0x18 Reserved Reserved
59530 + 0x1C Reserved Reserved
59531 +
59532 +*//***************************************************************************/
59533 +typedef _Packed struct
59534 +{
59535 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59536 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59537 + uint32_t nmIpCnt; /**< Not My IP counter */
59538 + uint32_t arCnt; /**< Auto-Response counter */
59539 + uint32_t reserved1; /**< Reserved */
59540 + uint32_t reserved2; /**< Reserved */
59541 + uint32_t reserved3; /**< Reserved */
59542 + uint32_t reserved4; /**< Reserved */
59543 +} _PackedType t_DsarIcmpV6Statistics;
59544 +
59545 +/**************************************************************************//**
59546 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
59547 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
59548 + 0x04 NMVLAN_CNT Not My VLAN counter
59549 + 0x08 NMIP_CNT Not My IP counter
59550 + 0x0C AR_CNT Auto-Response counter
59551 + 0x10 CSERR_CNT Checksum Error counter
59552 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
59553 + 0x18 NMMCAST_CNT Not My Multicast group counter
59554 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
59555 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
59556 + Source Link-layer Address option is omitted
59557 +*//***************************************************************************/
59558 +typedef _Packed struct
59559 +{
59560 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
59561 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
59562 + uint32_t nmIpCnt; /**< Not My IP counter */
59563 + uint32_t arCnt; /**< Auto-Response counter */
59564 + uint32_t reserved1; /**< Reserved */
59565 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
59566 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
59567 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
59568 +} _PackedType t_NdStatistics;
59569 +
59570 +/**************************************************************************//**
59571 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59572 + 0x0 0-15 Control bits [0-15]
59573 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59574 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59575 + 0x6 0-15
59576 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59577 + 0xA 0-15
59578 + 0xC 0-15 Reserved Reserved. Must be cleared.
59579 + 0xE 015
59580 +
59581 +*//***************************************************************************/
59582 +typedef _Packed struct
59583 +{
59584 + uint16_t control; /** Control bits [0-15]. */
59585 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59586 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59587 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59588 + uint32_t reserved1; /**< Reserved. */
59589 +} _PackedType t_DsarIcmpV6Descriptor;
59590 +
59591 +
59592 +/**************************************************************************//**
59593 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
59594 + The fields names are taken from RFC 4443.
59595 +*//***************************************************************************/
59596 +/* 0 1 2 3 */
59597 +/* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */
59598 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59599 +/* | Type | Code | Checksum | */
59600 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59601 +/* | Identifier | Sequence Number | */
59602 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
59603 +/* | Data ... */
59604 +/* +-+-+-+-+- */
59605 +typedef _Packed struct
59606 +{
59607 + uint8_t type;
59608 + uint8_t code;
59609 + uint16_t checksum;
59610 + uint16_t identifier;
59611 + uint16_t sequenceNumber;
59612 +} _PackedType t_IcmpV6EchoHdr;
59613 +
59614 +/**************************************************************************//**
59615 + @Description Internet Control Message Protocol (ICMPv6)
59616 + Neighbor Solicitation/Advertisement header
59617 + The fields names are taken from RFC 4861.
59618 + The R/S/O fields are valid for Neighbor Advertisement only
59619 +*//***************************************************************************/
59620 +/* 0 1 2 3
59621 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
59622 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59623 + * | Type | Code | Checksum |
59624 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59625 + * |R|S|O| Reserved |
59626 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59627 + * | |
59628 + * + +
59629 + * | |
59630 + * + Target Address +
59631 + * | |
59632 + * + +
59633 + * | |
59634 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59635 + * | Options ...
59636 + * +-+-+-+-+-+-+-+-+-+-+-+-
59637 + *
59638 + * Options Format:
59639 + * 0 1 2 3
59640 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
59641 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59642 + * | Type | Length | Link-Layer Address ... |
59643 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59644 + * | Link-Layer Address |
59645 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59646 +*/
59647 +typedef _Packed struct
59648 +{
59649 + uint8_t type;
59650 + uint8_t code;
59651 + uint16_t checksum;
59652 + uint32_t router:1;
59653 + uint32_t solicited:1;
59654 + uint32_t override:1;
59655 + uint32_t reserved:29;
59656 + uint32_t targetAddr[4];
59657 + uint8_t optionType;
59658 + uint8_t optionLength;
59659 + uint8_t linkLayerAddr[6];
59660 +} _PackedType t_IcmpV6NdHdr;
59661 +
59662 +/**************************************************************************//**
59663 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
59664 + 0x0 0-15 Control bits [0-15]
59665 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
59666 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
59667 + 0x6 0-15
59668 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
59669 + 0xA 0-15
59670 + 0xC 0-15 Reserved Reserved. Must be cleared.
59671 + 0xE 015
59672 +
59673 +*//***************************************************************************/
59674 +typedef _Packed struct
59675 +{
59676 + uint16_t control; /** Control bits [0-15]. */
59677 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
59678 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
59679 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
59680 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
59681 +} _PackedType t_DsarNdDescriptor;
59682 +
59683 +/**************************************************************************//**
59684 +@Description Deep Sleep Auto Response SNMP OIDs table entry
59685 +
59686 +*//***************************************************************************/
59687 +typedef struct {
59688 + uint16_t oidSize; /**< Size in octets of the OID. */
59689 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
59690 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
59691 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
59692 + uint32_t reserved;
59693 +} t_OidsTblEntry;
59694 +
59695 +/**************************************************************************//**
59696 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
59697 + Refer to the FMan Controller spec for more details.
59698 +*//***************************************************************************/
59699 +typedef struct
59700 +{
59701 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
59702 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59703 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59704 + uint16_t reserved;
59705 +} t_DsarSnmpIpv4AddrTblEntry;
59706 +
59707 +/**************************************************************************//**
59708 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
59709 + Refer to the FMan Controller spec for more details.
59710 +*//***************************************************************************/
59711 +#pragma pack(push,1)
59712 +typedef struct
59713 +{
59714 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
59715 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
59716 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
59717 + uint16_t reserved;
59718 +} t_DsarSnmpIpv6AddrTblEntry;
59719 +#pragma pack(pop)
59720 +
59721 +/**************************************************************************//**
59722 +@Description Deep Sleep Auto Response SNMP statistics table
59723 +
59724 +*//***************************************************************************/
59725 +typedef struct {
59726 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
59727 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
59728 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
59729 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
59730 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
59731 +} t_DsarSnmpStatistics;
59732 +
59733 +/**************************************************************************//**
59734 + @Description Deep Sleep Auto Response SNMP Descriptor
59735 +
59736 +*//***************************************************************************/
59737 +typedef struct
59738 +{
59739 + uint16_t control; /**< Control bits [0-15]. */
59740 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
59741 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
59742 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
59743 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
59744 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
59745 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
59746 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
59747 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
59748 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
59749 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
59750 +} t_DsarSnmpDescriptor;
59751 +
59752 +/**************************************************************************//**
59753 +@Description Deep Sleep Auto Response (Common) Statistics
59754 +
59755 +*//***************************************************************************/
59756 +typedef _Packed struct {
59757 + uint32_t dsarDiscarded;
59758 + uint32_t dsarErrDiscarded;
59759 + uint32_t dsarFragDiscarded;
59760 + uint32_t dsarTunnelDiscarded;
59761 + uint32_t dsarArpDiscarded;
59762 + uint32_t dsarIpDiscarded;
59763 + uint32_t dsarTcpDiscarded;
59764 + uint32_t dsarUdpDiscarded;
59765 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
59766 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
59767 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
59768 +} _PackedType t_ArStatistics;
59769 +
59770 +
59771 +/**************************************************************************//**
59772 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
59773 +
59774 +*//***************************************************************************/
59775 +typedef _Packed struct {
59776 + uint32_t Ports;
59777 + uint32_t PortsMask;
59778 +} _PackedType t_PortTblEntry;
59779 +
59780 +
59781 +
59782 +/**************************************************************************//**
59783 +@Description Deep Sleep Auto Response Common Parameters Descriptor
59784 +
59785 +*//***************************************************************************/
59786 +typedef _Packed struct {
59787 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
59788 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
59789 + uint16_t res1; /* 0x00 16-31 Reserved */
59790 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
59791 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
59792 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
59793 + uint8_t res2; /* 0x10 0-7 Reserved */
59794 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
59795 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
59796 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
59797 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
59798 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
59799 + uint8_t res3; /* 0x14 24-31 Reserved */
59800 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
59801 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
59802 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
59803 + uint32_t res4; /* 0x24 Reserved */
59804 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
59805 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
59806 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
59807 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
59808 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
59809 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
59810 +} _PackedType t_ArCommonDesc;
59811 +
59812 +#if defined(__MWERKS__) && !defined(__GNUC__)
59813 +#pragma pack(pop)
59814 +#endif /* defined(__MWERKS__) && ... */
59815 +
59816 +/* t_ArCommonDesc.filterControl bits */
59817 +#define IP_PROT_TBL_PASS_MASK 0x08
59818 +#define UDP_PORT_TBL_PASS_MASK 0x04
59819 +#define TCP_PORT_TBL_PASS_MASK 0x02
59820 +
59821 +/* Offset of TCF flags within TCP packet */
59822 +#define TCP_FLAGS_OFFSET 12
59823 +
59824 +
59825 +#endif /* __FM_PORT_DSAR_H_ */
59826 --- /dev/null
59827 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
59828 @@ -0,0 +1,753 @@
59829 +/*
59830 + * Copyright 2008-2012 Freescale Semiconductor Inc.
59831 + *
59832 + * Redistribution and use in source and binary forms, with or without
59833 + * modification, are permitted provided that the following conditions are met:
59834 + * * Redistributions of source code must retain the above copyright
59835 + * notice, this list of conditions and the following disclaimer.
59836 + * * Redistributions in binary form must reproduce the above copyright
59837 + * notice, this list of conditions and the following disclaimer in the
59838 + * documentation and/or other materials provided with the distribution.
59839 + * * Neither the name of Freescale Semiconductor nor the
59840 + * names of its contributors may be used to endorse or promote products
59841 + * derived from this software without specific prior written permission.
59842 + *
59843 + *
59844 + * ALTERNATIVELY, this software may be distributed under the terms of the
59845 + * GNU General Public License ("GPL") as published by the Free Software
59846 + * Foundation, either version 2 of that License or (at your option) any
59847 + * later version.
59848 + *
59849 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
59850 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
59851 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59852 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
59853 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
59854 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
59855 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59856 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59857 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
59858 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59859 + */
59860 +
59861 +
59862 +/******************************************************************************
59863 + @File fm_port_im.c
59864 +
59865 + @Description FM Port Independent-Mode ...
59866 +*//***************************************************************************/
59867 +#include "std_ext.h"
59868 +#include "string_ext.h"
59869 +#include "error_ext.h"
59870 +#include "memcpy_ext.h"
59871 +#include "fm_muram_ext.h"
59872 +
59873 +#include "fm_port.h"
59874 +
59875 +
59876 +#define TX_CONF_STATUS_UNSENT 0x1
59877 +
59878 +
59879 +typedef enum e_TxConfType
59880 +{
59881 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
59882 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
59883 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
59884 +} e_TxConfType;
59885 +
59886 +
59887 +static void ImException(t_Handle h_FmPort, uint32_t event)
59888 +{
59889 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59890 +
59891 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
59892 + !FmIsMaster(p_FmPort->h_Fm));
59893 +
59894 + if (event & IM_EV_RX)
59895 + FmPortImRx(p_FmPort);
59896 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
59897 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
59898 +}
59899 +
59900 +
59901 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
59902 +{
59903 + t_Error retVal = E_BUSY;
59904 + uint32_t bdStatus;
59905 + uint16_t savedStartBdId, confBdId;
59906 +
59907 + ASSERT_COND(p_FmPort);
59908 +
59909 + /*
59910 + if (confType==e_TX_CONF_TYPE_CHECK)
59911 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
59912 + */
59913 +
59914 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
59915 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59916 +
59917 + /* If R bit is set, we don't enter, or we break.
59918 + we run till we get to R, or complete the loop */
59919 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
59920 + {
59921 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
59922 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
59923 +
59924 + /* case 1: R bit is 0 and Length is set -> confirm! */
59925 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
59926 + {
59927 + if (p_FmPort->im.f_TxConf)
59928 + {
59929 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
59930 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59931 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59932 + TX_CONF_STATUS_UNSENT,
59933 + p_FmPort->im.p_BdShadow[confBdId]);
59934 + else
59935 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
59936 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
59937 + 0,
59938 + p_FmPort->im.p_BdShadow[confBdId]);
59939 + }
59940 + }
59941 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
59942 +
59943 + confBdId = GetNextBdId(p_FmPort, confBdId);
59944 + if (confBdId == savedStartBdId)
59945 + retVal = E_OK;
59946 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
59947 + }
59948 +
59949 + return retVal;
59950 +}
59951 +
59952 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
59953 +{
59954 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59955 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
59956 + return E_OK;
59957 +}
59958 +
59959 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
59960 +{
59961 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
59962 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
59963 + return E_OK;
59964 +}
59965 +
59966 +t_Error FmPortImRx(t_FmPort *p_FmPort)
59967 +{
59968 + t_Handle h_CurrUserPriv, h_NewUserPriv;
59969 + uint32_t bdStatus;
59970 + volatile uint8_t buffPos;
59971 + uint16_t length;
59972 + uint16_t errors;
59973 + uint8_t *p_CurData, *p_Data;
59974 + uint32_t flags;
59975 +
59976 + ASSERT_COND(p_FmPort);
59977 +
59978 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
59979 + if (p_FmPort->lock)
59980 + {
59981 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59982 + return E_OK;
59983 + }
59984 + p_FmPort->lock = TRUE;
59985 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
59986 +
59987 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
59988 +
59989 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
59990 + {
59991 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
59992 + {
59993 + p_FmPort->lock = FALSE;
59994 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
59995 + }
59996 +
59997 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
59998 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
59999 +
60000 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60001 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
60002 + length = (uint16_t)((bdStatus & BD_L) ?
60003 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
60004 + (bdStatus & BD_LENGTH_MASK));
60005 + p_FmPort->im.rxFrameAccumLength += length;
60006 +
60007 + /* determine whether buffer is first, last, first and last (single */
60008 + /* buffer frame) or middle (not first and not last) */
60009 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
60010 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
60011 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
60012 +
60013 + if (bdStatus & BD_L)
60014 + {
60015 + p_FmPort->im.rxFrameAccumLength = 0;
60016 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60017 + }
60018 +
60019 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60020 +
60021 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
60022 +
60023 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
60024 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
60025 +
60026 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60027 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
60028 + /* Pass the buffer if one of the conditions is true:
60029 + - There are no errors
60030 + - This is a part of a larger frame ( the application has already received some buffers ) */
60031 + if ((buffPos != SINGLE_BUF) || !errors)
60032 + {
60033 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
60034 + p_CurData,
60035 + length,
60036 + errors,
60037 + buffPos,
60038 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
60039 + break;
60040 + }
60041 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60042 + p_CurData,
60043 + h_CurrUserPriv))
60044 + {
60045 + p_FmPort->lock = FALSE;
60046 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
60047 + }
60048 +
60049 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60050 + }
60051 + p_FmPort->lock = FALSE;
60052 + return E_OK;
60053 +}
60054 +
60055 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
60056 +{
60057 + ASSERT_COND(p_FmPort);
60058 +
60059 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60060 +
60061 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
60062 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
60063 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
60064 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
60065 +
60066 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
60067 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
60068 +
60069 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60070 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60071 + {
60072 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
60073 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
60074 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
60075 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
60076 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
60077 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
60078 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
60079 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
60080 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
60081 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
60082 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
60083 +
60084 + p_FmPort->im.mrblr = 0x8000;
60085 + while (p_FmPort->im.mrblr)
60086 + {
60087 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
60088 + break;
60089 + p_FmPort->im.mrblr >>= 1;
60090 + }
60091 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
60092 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
60093 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
60094 + p_FmPort->exceptions = DEFAULT_PORT_exception;
60095 + if (FmIsMaster(p_FmPort->h_Fm))
60096 + p_FmPort->polling = FALSE;
60097 + else
60098 + p_FmPort->polling = TRUE;
60099 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60100 + }
60101 + else
60102 + {
60103 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
60104 +
60105 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
60106 + }
60107 +}
60108 +
60109 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
60110 +{
60111 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
60112 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
60113 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
60114 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
60115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
60116 +
60117 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60118 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60119 + {
60120 + if (!POWER_OF_2(p_FmPort->im.mrblr))
60121 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
60122 + if (p_FmPort->im.mrblr < 256)
60123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
60124 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
60125 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
60126 + }
60127 +
60128 + return E_OK;
60129 +}
60130 +
60131 +t_Error FmPortImInit(t_FmPort *p_FmPort)
60132 +{
60133 + t_FmImBd *p_Bd=NULL;
60134 + t_Handle h_BufContext;
60135 + uint64_t tmpPhysBase;
60136 + uint16_t log2Num;
60137 + uint8_t *p_Data/*, *p_Tmp*/;
60138 + int i;
60139 + t_Error err;
60140 + uint16_t tmpReg16;
60141 + uint32_t tmpReg32;
60142 +
60143 + ASSERT_COND(p_FmPort);
60144 +
60145 + p_FmPort->im.p_FmPortImPram =
60146 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
60147 + if (!p_FmPort->im.p_FmPortImPram)
60148 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
60149 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
60150 +
60151 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60152 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60153 + {
60154 + p_FmPort->im.p_BdRing =
60155 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
60156 + p_FmPort->im.fwExtStructsMemId,
60157 + 4);
60158 + if (!p_FmPort->im.p_BdRing)
60159 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
60160 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60161 +
60162 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60163 + if (!p_FmPort->im.p_BdShadow)
60164 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60165 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60166 +
60167 + /* Initialize the Rx-BD ring */
60168 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
60169 + {
60170 + p_Bd = BD_GET(i);
60171 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
60172 +
60173 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
60174 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
60175 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
60176 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
60177 + }
60178 +
60179 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60180 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60181 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60182 + else
60183 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60184 +
60185 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
60186 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60187 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
60188 +
60189 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
60190 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
60191 +
60192 + /* Initialize Rx QD */
60193 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60194 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
60195 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60196 +
60197 + /* Update the IM PRAM address in the BMI */
60198 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
60199 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60200 + p_FmPort->fmMuramPhysBaseAddr));
60201 + if (!p_FmPort->polling || p_FmPort->exceptions)
60202 + {
60203 + /* Allocate, configure and register interrupts */
60204 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60205 + if (err)
60206 + RETURN_ERROR(MAJOR, err, NO_MSG);
60207 +
60208 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60209 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
60210 + tmpReg32 = 0;
60211 +
60212 + if (p_FmPort->exceptions & IM_EV_BSY)
60213 + {
60214 + tmpReg16 |= IM_RXQD_BSYINTM;
60215 + tmpReg32 |= IM_EV_BSY;
60216 + }
60217 + if (!p_FmPort->polling)
60218 + {
60219 + tmpReg16 |= IM_RXQD_RXFINTM;
60220 + tmpReg32 |= IM_EV_RX;
60221 + }
60222 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60223 +
60224 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
60225 +
60226 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60227 + }
60228 + else
60229 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60230 + }
60231 + else
60232 + {
60233 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
60234 + if (!p_FmPort->im.p_BdRing)
60235 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
60236 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60237 +
60238 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60239 + if (!p_FmPort->im.p_BdShadow)
60240 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
60241 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
60242 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60243 +
60244 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
60245 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
60246 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
60247 + else
60248 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
60249 +
60250 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
60251 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60252 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
60253 +
60254 + /* Initialize Tx QD */
60255 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
60256 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
60257 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
60258 +
60259 + /* Update the IM PRAM address in the BMI */
60260 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
60261 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
60262 + p_FmPort->fmMuramPhysBaseAddr));
60263 + }
60264 +
60265 +
60266 + return E_OK;
60267 +}
60268 +
60269 +void FmPortImFree(t_FmPort *p_FmPort)
60270 +{
60271 + uint32_t bdStatus;
60272 + uint8_t *p_CurData;
60273 +
60274 + ASSERT_COND(p_FmPort);
60275 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
60276 +
60277 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
60278 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
60279 + {
60280 + if (!p_FmPort->polling || p_FmPort->exceptions)
60281 + {
60282 + /* Deallocate and unregister interrupts */
60283 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60284 +
60285 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60286 +
60287 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60288 +
60289 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60290 + }
60291 + /* Try first clean what has received */
60292 + FmPortImRx(p_FmPort);
60293 +
60294 + /* Now, get rid of the the empty buffer! */
60295 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60296 +
60297 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
60298 + {
60299 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
60300 +
60301 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
60302 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
60303 +
60304 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
60305 + p_CurData,
60306 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60307 +
60308 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60309 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60310 + }
60311 + }
60312 + else
60313 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
60314 +
60315 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
60316 +
60317 + if (p_FmPort->im.p_BdShadow)
60318 + XX_Free(p_FmPort->im.p_BdShadow);
60319 +
60320 + if (p_FmPort->im.p_BdRing)
60321 + XX_FreeSmart(p_FmPort->im.p_BdRing);
60322 +}
60323 +
60324 +
60325 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
60326 +{
60327 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60328 +
60329 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60330 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60331 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60332 +
60333 + p_FmPort->im.mrblr = newVal;
60334 +
60335 + return E_OK;
60336 +}
60337 +
60338 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60339 +{
60340 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60341 +
60342 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60343 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60344 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60345 +
60346 + p_FmPort->im.bdRingSize = newVal;
60347 +
60348 + return E_OK;
60349 +}
60350 +
60351 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
60352 +{
60353 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60354 +
60355 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60356 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60357 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60358 +
60359 + p_FmPort->im.bdRingSize = newVal;
60360 +
60361 + return E_OK;
60362 +}
60363 +
60364 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
60365 + uint8_t memId,
60366 + uint32_t memAttributes)
60367 +{
60368 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60369 +
60370 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60371 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60372 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60373 +
60374 + p_FmPort->im.fwExtStructsMemId = memId;
60375 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
60376 +
60377 + return E_OK;
60378 +}
60379 +
60380 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
60381 +{
60382 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60383 +
60384 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60385 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60386 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60387 +
60388 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
60389 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
60390 +
60391 + if (!FmIsMaster(p_FmPort->h_Fm))
60392 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
60393 + "in guest-partitions, IM is always in polling!"));
60394 +
60395 + p_FmPort->polling = TRUE;
60396 +
60397 + return E_OK;
60398 +}
60399 +
60400 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
60401 +{
60402 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60403 + t_Error err;
60404 + uint16_t tmpReg16;
60405 + uint32_t tmpReg32;
60406 +
60407 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60408 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60409 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60410 +
60411 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
60412 + {
60413 + if (enable)
60414 + {
60415 + p_FmPort->exceptions |= IM_EV_BSY;
60416 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
60417 + {
60418 + /* Allocate, configure and register interrupts */
60419 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
60420 + if (err)
60421 + RETURN_ERROR(MAJOR, err, NO_MSG);
60422 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
60423 +
60424 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
60425 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
60426 + tmpReg32 = IM_EV_BSY;
60427 + }
60428 + else
60429 + {
60430 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
60431 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
60432 + }
60433 +
60434 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60435 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60436 + }
60437 + else
60438 + {
60439 + p_FmPort->exceptions &= ~IM_EV_BSY;
60440 + if (!p_FmPort->exceptions && p_FmPort->polling)
60441 + {
60442 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60443 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
60444 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
60445 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
60446 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
60447 + }
60448 + else
60449 + {
60450 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
60451 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
60452 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
60453 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
60454 + }
60455 + }
60456 + }
60457 + else
60458 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
60459 +
60460 + return E_OK;
60461 +}
60462 +
60463 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
60464 + uint8_t *p_Data,
60465 + uint16_t length,
60466 + bool lastBuffer,
60467 + t_Handle h_BufContext)
60468 +{
60469 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60470 + uint16_t nextBdId;
60471 + uint32_t bdStatus, nextBdStatus;
60472 + bool firstBuffer;
60473 +
60474 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60475 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60476 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60477 +
60478 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
60479 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60480 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
60481 +
60482 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
60483 + {
60484 + /* Confirm the current BD - BD is available */
60485 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
60486 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
60487 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
60488 + 0,
60489 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
60490 +
60491 + bdStatus = length;
60492 +
60493 + /* if this is the first BD of a frame */
60494 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
60495 + {
60496 + firstBuffer = TRUE;
60497 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
60498 +
60499 + if (!lastBuffer)
60500 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
60501 + }
60502 + else
60503 + firstBuffer = FALSE;
60504 +
60505 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
60506 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
60507 +
60508 + /* deal with last */
60509 + if (lastBuffer)
60510 + {
60511 + /* if single buffer frame */
60512 + if (firstBuffer)
60513 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
60514 + else
60515 + {
60516 + /* Set the last BD of the frame */
60517 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
60518 + /* Set the first BD of the frame */
60519 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
60520 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60521 + }
60522 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
60523 + }
60524 + else if (!firstBuffer) /* mid frame buffer */
60525 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
60526 +
60527 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
60528 + }
60529 + else
60530 + {
60531 + /* Discard current frame. Return error. */
60532 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
60533 + {
60534 + /* Error: No free BD */
60535 + /* Response: Discard current frame. Return error. */
60536 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
60537 +
60538 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
60539 +
60540 + /* Since firstInFrame is not NULL, one buffer at least has already been
60541 + inserted into the BD ring. Using do-while covers the situation of a
60542 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
60543 + prior to testing whether or not it's equal to TxBd). */
60544 + do
60545 + {
60546 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
60547 + /* Advance BD pointer */
60548 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
60549 + } while (cleanBdId != p_FmPort->im.currBdId);
60550 +
60551 + p_FmPort->im.currBdId = cleanBdId;
60552 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
60553 + }
60554 +
60555 + return ERROR_CODE(E_FULL);
60556 + }
60557 +
60558 + return E_OK;
60559 +}
60560 +
60561 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
60562 +{
60563 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60564 +
60565 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
60566 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
60567 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60568 +
60569 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
60570 +}
60571 +
60572 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
60573 +{
60574 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
60575 +
60576 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
60577 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
60578 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
60579 +
60580 + return FmPortImRx(p_FmPort);
60581 +}
60582 --- /dev/null
60583 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
60584 @@ -0,0 +1,1568 @@
60585 +/*
60586 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60587 + *
60588 + * Redistribution and use in source and binary forms, with or without
60589 + * modification, are permitted provided that the following conditions are met:
60590 + * * Redistributions of source code must retain the above copyright
60591 + * notice, this list of conditions and the following disclaimer.
60592 + * * Redistributions in binary form must reproduce the above copyright
60593 + * notice, this list of conditions and the following disclaimer in the
60594 + * documentation and/or other materials provided with the distribution.
60595 + * * Neither the name of Freescale Semiconductor nor the
60596 + * names of its contributors may be used to endorse or promote products
60597 + * derived from this software without specific prior written permission.
60598 + *
60599 + *
60600 + * ALTERNATIVELY, this software may be distributed under the terms of the
60601 + * GNU General Public License ("GPL") as published by the Free Software
60602 + * Foundation, either version 2 of that License or (at your option) any
60603 + * later version.
60604 + *
60605 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60606 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60607 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60608 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60609 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60610 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60611 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60612 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60613 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60614 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60615 + */
60616 +
60617 +
60618 +#include "common/general.h"
60619 +
60620 +#include "fman_common.h"
60621 +#include "fsl_fman_port.h"
60622 +
60623 +
60624 +/* problem Eyal: the following should not be here*/
60625 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
60626 +
60627 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
60628 +{
60629 + if (cfg->errata_A006675)
60630 + return NIA_ENG_FM_CTL |
60631 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
60632 + else
60633 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
60634 +}
60635 +
60636 +static int init_bmi_rx(struct fman_port *port,
60637 + struct fman_port_cfg *cfg,
60638 + struct fman_port_params *params)
60639 +{
60640 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
60641 + uint32_t tmp;
60642 +
60643 + /* Rx Configuration register */
60644 + tmp = 0;
60645 + if (port->im_en)
60646 + tmp |= BMI_PORT_CFG_IM;
60647 + else if (cfg->discard_override)
60648 + tmp |= BMI_PORT_CFG_FDOVR;
60649 + iowrite32be(tmp, &regs->fmbm_rcfg);
60650 +
60651 + /* DMA attributes */
60652 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60653 + if (cfg->dma_ic_stash_on)
60654 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60655 + if (cfg->dma_header_stash_on)
60656 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60657 + if (cfg->dma_sg_stash_on)
60658 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60659 + if (cfg->dma_write_optimize)
60660 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60661 + iowrite32be(tmp, &regs->fmbm_rda);
60662 +
60663 + /* Rx FIFO parameters */
60664 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
60665 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
60666 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
60667 + iowrite32be(tmp, &regs->fmbm_rfp);
60668 +
60669 + if (cfg->excessive_threshold_register)
60670 + /* always allow access to the extra resources */
60671 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
60672 +
60673 + /* Frame end data */
60674 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60675 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
60676 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
60677 + BMI_RX_FRAME_END_CUT_SHIFT;
60678 + if (cfg->errata_A006320)
60679 + tmp &= 0xffe0ffff;
60680 + iowrite32be(tmp, &regs->fmbm_rfed);
60681 +
60682 + /* Internal context parameters */
60683 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60684 + BMI_IC_TO_EXT_SHIFT;
60685 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60686 + BMI_IC_FROM_INT_SHIFT;
60687 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60688 + iowrite32be(tmp, &regs->fmbm_ricp);
60689 +
60690 + /* Internal buffer offset */
60691 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60692 + << BMI_INT_BUF_MARG_SHIFT;
60693 + iowrite32be(tmp, &regs->fmbm_rim);
60694 +
60695 + /* External buffer margins */
60696 + if (!port->im_en)
60697 + {
60698 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
60699 + BMI_EXT_BUF_MARG_START_SHIFT;
60700 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
60701 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
60702 + tmp |= BMI_SG_DISABLE;
60703 + iowrite32be(tmp, &regs->fmbm_rebm);
60704 + }
60705 +
60706 + /* Frame attributes */
60707 + tmp = BMI_CMD_RX_MR_DEF;
60708 + if (!port->im_en)
60709 + {
60710 + tmp |= BMI_CMD_ATTR_ORDER;
60711 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60712 + if (cfg->sync_req)
60713 + tmp |= BMI_CMD_ATTR_SYNC;
60714 + }
60715 + iowrite32be(tmp, &regs->fmbm_rfca);
60716 +
60717 + /* NIA */
60718 + if (port->im_en)
60719 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
60720 + else
60721 + {
60722 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
60723 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
60724 + }
60725 + iowrite32be(tmp, &regs->fmbm_rfne);
60726 +
60727 + /* Enqueue NIA */
60728 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
60729 +
60730 + /* Default/error queues */
60731 + if (!port->im_en)
60732 + {
60733 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
60734 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
60735 + }
60736 +
60737 + /* Discard/error masks */
60738 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
60739 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
60740 +
60741 + /* Statistics counters */
60742 + tmp = 0;
60743 + if (cfg->stats_counters_enable)
60744 + tmp = BMI_COUNTERS_EN;
60745 + iowrite32be(tmp, &regs->fmbm_rstc);
60746 +
60747 + /* Performance counters */
60748 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60749 + tmp = 0;
60750 + if (cfg->perf_counters_enable)
60751 + tmp = BMI_COUNTERS_EN;
60752 + iowrite32be(tmp, &regs->fmbm_rpc);
60753 +
60754 + return 0;
60755 +}
60756 +
60757 +static int init_bmi_tx(struct fman_port *port,
60758 + struct fman_port_cfg *cfg,
60759 + struct fman_port_params *params)
60760 +{
60761 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
60762 + uint32_t tmp;
60763 +
60764 + /* Tx Configuration register */
60765 + tmp = 0;
60766 + if (port->im_en)
60767 + tmp |= BMI_PORT_CFG_IM;
60768 + iowrite32be(tmp, &regs->fmbm_tcfg);
60769 +
60770 + /* DMA attributes */
60771 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60772 + if (cfg->dma_ic_stash_on)
60773 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60774 + if (cfg->dma_header_stash_on)
60775 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60776 + if (cfg->dma_sg_stash_on)
60777 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60778 + iowrite32be(tmp, &regs->fmbm_tda);
60779 +
60780 + /* Tx FIFO parameters */
60781 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
60782 + BMI_TX_FIFO_MIN_FILL_SHIFT;
60783 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60784 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60785 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
60786 + FMAN_PORT_BMI_FIFO_UNITS - 1);
60787 + iowrite32be(tmp, &regs->fmbm_tfp);
60788 +
60789 + /* Frame end data */
60790 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
60791 + BMI_FRAME_END_CS_IGNORE_SHIFT;
60792 + iowrite32be(tmp, &regs->fmbm_tfed);
60793 +
60794 + /* Internal context parameters */
60795 + if (!port->im_en)
60796 + {
60797 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60798 + BMI_IC_TO_EXT_SHIFT;
60799 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60800 + BMI_IC_FROM_INT_SHIFT;
60801 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60802 + iowrite32be(tmp, &regs->fmbm_ticp);
60803 + }
60804 + /* Frame attributes */
60805 + tmp = BMI_CMD_TX_MR_DEF;
60806 + if (port->im_en)
60807 + tmp |= BMI_CMD_MR_DEAS;
60808 + else
60809 + {
60810 + tmp |= BMI_CMD_ATTR_ORDER;
60811 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60812 + }
60813 + iowrite32be(tmp, &regs->fmbm_tfca);
60814 +
60815 + /* Dequeue NIA + enqueue NIA */
60816 + if (port->im_en)
60817 + {
60818 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
60819 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
60820 + }
60821 + else
60822 + {
60823 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
60824 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
60825 + if (cfg->fmbm_tfne_has_features)
60826 + iowrite32be(!params->dflt_fqid ?
60827 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
60828 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
60829 + if (!params->dflt_fqid && params->dont_release_buf)
60830 + {
60831 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
60832 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
60833 + if (cfg->fmbm_tfne_has_features)
60834 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
60835 + }
60836 + }
60837 +
60838 + /* Confirmation/error queues */
60839 + if (!port->im_en)
60840 + {
60841 + if (params->dflt_fqid || !params->dont_release_buf)
60842 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
60843 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
60844 + }
60845 + /* Statistics counters */
60846 + tmp = 0;
60847 + if (cfg->stats_counters_enable)
60848 + tmp = BMI_COUNTERS_EN;
60849 + iowrite32be(tmp, &regs->fmbm_tstc);
60850 +
60851 + /* Performance counters */
60852 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60853 + tmp = 0;
60854 + if (cfg->perf_counters_enable)
60855 + tmp = BMI_COUNTERS_EN;
60856 + iowrite32be(tmp, &regs->fmbm_tpc);
60857 +
60858 + return 0;
60859 +}
60860 +
60861 +static int init_bmi_oh(struct fman_port *port,
60862 + struct fman_port_cfg *cfg,
60863 + struct fman_port_params *params)
60864 +{
60865 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
60866 + uint32_t tmp;
60867 +
60868 + /* OP Configuration register */
60869 + tmp = 0;
60870 + if (cfg->discard_override)
60871 + tmp |= BMI_PORT_CFG_FDOVR;
60872 + iowrite32be(tmp, &regs->fmbm_ocfg);
60873 +
60874 + /* DMA attributes */
60875 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
60876 + if (cfg->dma_ic_stash_on)
60877 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
60878 + if (cfg->dma_header_stash_on)
60879 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
60880 + if (cfg->dma_sg_stash_on)
60881 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
60882 + if (cfg->dma_write_optimize)
60883 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
60884 + iowrite32be(tmp, &regs->fmbm_oda);
60885 +
60886 + /* Tx FIFO parameters */
60887 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
60888 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
60889 + iowrite32be(tmp, &regs->fmbm_ofp);
60890 +
60891 + /* Internal context parameters */
60892 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60893 + BMI_IC_TO_EXT_SHIFT;
60894 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
60895 + BMI_IC_FROM_INT_SHIFT;
60896 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
60897 + iowrite32be(tmp, &regs->fmbm_oicp);
60898 +
60899 + /* Frame attributes */
60900 + tmp = BMI_CMD_OP_MR_DEF;
60901 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
60902 + if (cfg->sync_req)
60903 + tmp |= BMI_CMD_ATTR_SYNC;
60904 + if (port->type == E_FMAN_PORT_TYPE_OP)
60905 + tmp |= BMI_CMD_ATTR_ORDER;
60906 + iowrite32be(tmp, &regs->fmbm_ofca);
60907 +
60908 + /* Internal buffer offset */
60909 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
60910 + << BMI_INT_BUF_MARG_SHIFT;
60911 + iowrite32be(tmp, &regs->fmbm_oim);
60912 +
60913 + /* Dequeue NIA */
60914 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
60915 +
60916 + /* NIA and Enqueue NIA */
60917 + if (port->type == E_FMAN_PORT_TYPE_HC) {
60918 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
60919 + &regs->fmbm_ofne);
60920 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
60921 + } else {
60922 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
60923 + &regs->fmbm_ofne);
60924 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
60925 + &regs->fmbm_ofene);
60926 + }
60927 +
60928 + /* Default/error queues */
60929 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
60930 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
60931 +
60932 + /* Discard/error masks */
60933 + if (port->type == E_FMAN_PORT_TYPE_OP) {
60934 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
60935 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
60936 + }
60937 +
60938 + /* Statistics counters */
60939 + tmp = 0;
60940 + if (cfg->stats_counters_enable)
60941 + tmp = BMI_COUNTERS_EN;
60942 + iowrite32be(tmp, &regs->fmbm_ostc);
60943 +
60944 + /* Performance counters */
60945 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
60946 + tmp = 0;
60947 + if (cfg->perf_counters_enable)
60948 + tmp = BMI_COUNTERS_EN;
60949 + iowrite32be(tmp, &regs->fmbm_opc);
60950 +
60951 + return 0;
60952 +}
60953 +
60954 +static int init_qmi(struct fman_port *port,
60955 + struct fman_port_cfg *cfg,
60956 + struct fman_port_params *params)
60957 +{
60958 + struct fman_port_qmi_regs *regs = port->qmi_regs;
60959 + uint32_t tmp;
60960 +
60961 + tmp = 0;
60962 + if (cfg->queue_counters_enable)
60963 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
60964 + iowrite32be(tmp, &regs->fmqm_pnc);
60965 +
60966 + /* Rx port configuration */
60967 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
60968 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
60969 + /* Enqueue NIA */
60970 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60971 + return 0;
60972 + }
60973 +
60974 + /* Continue with Tx and O/H port configuration */
60975 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
60976 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
60977 + /* Enqueue NIA */
60978 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
60979 + &regs->fmqm_pnen);
60980 + /* Dequeue NIA */
60981 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
60982 + } else {
60983 + /* Enqueue NIA */
60984 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
60985 + /* Dequeue NIA */
60986 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
60987 + }
60988 +
60989 + /* Dequeue Configuration register */
60990 + tmp = 0;
60991 + if (cfg->deq_high_pri)
60992 + tmp |= QMI_DEQ_CFG_PRI;
60993 +
60994 + switch (cfg->deq_type) {
60995 + case E_FMAN_PORT_DEQ_BY_PRI:
60996 + tmp |= QMI_DEQ_CFG_TYPE1;
60997 + break;
60998 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
60999 + tmp |= QMI_DEQ_CFG_TYPE2;
61000 + break;
61001 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
61002 + tmp |= QMI_DEQ_CFG_TYPE3;
61003 + break;
61004 + default:
61005 + return -EINVAL;
61006 + }
61007 +
61008 + if (cfg->qmi_deq_options_support) {
61009 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
61010 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
61011 + return -EINVAL;
61012 +
61013 + switch (cfg->deq_prefetch_opt) {
61014 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
61015 + break;
61016 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
61017 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
61018 + break;
61019 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
61020 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
61021 + break;
61022 + default:
61023 + return -EINVAL;
61024 + }
61025 + }
61026 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
61027 + QMI_DEQ_CFG_SP_SHIFT;
61028 + tmp |= cfg->deq_byte_cnt;
61029 + iowrite32be(tmp, &regs->fmqm_pndc);
61030 +
61031 + return 0;
61032 +}
61033 +
61034 +static void get_rx_stats_reg(struct fman_port *port,
61035 + enum fman_port_stats_counters counter,
61036 + uint32_t **stats_reg)
61037 +{
61038 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61039 +
61040 + switch (counter) {
61041 + case E_FMAN_PORT_STATS_CNT_FRAME:
61042 + *stats_reg = &regs->fmbm_rfrc;
61043 + break;
61044 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61045 + *stats_reg = &regs->fmbm_rfdc;
61046 + break;
61047 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61048 + *stats_reg = &regs->fmbm_rbdc;
61049 + break;
61050 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
61051 + *stats_reg = &regs->fmbm_rfbc;
61052 + break;
61053 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
61054 + *stats_reg = &regs->fmbm_rlfc;
61055 + break;
61056 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
61057 + *stats_reg = &regs->fmbm_rodc;
61058 + break;
61059 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
61060 + *stats_reg = &regs->fmbm_rffc;
61061 + break;
61062 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
61063 + *stats_reg = &regs->fmbm_rfldec;
61064 + break;
61065 + default:
61066 + *stats_reg = NULL;
61067 + }
61068 +}
61069 +
61070 +static void get_tx_stats_reg(struct fman_port *port,
61071 + enum fman_port_stats_counters counter,
61072 + uint32_t **stats_reg)
61073 +{
61074 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
61075 +
61076 + switch (counter) {
61077 + case E_FMAN_PORT_STATS_CNT_FRAME:
61078 + *stats_reg = &regs->fmbm_tfrc;
61079 + break;
61080 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61081 + *stats_reg = &regs->fmbm_tfdc;
61082 + break;
61083 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61084 + *stats_reg = &regs->fmbm_tbdc;
61085 + break;
61086 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
61087 + *stats_reg = &regs->fmbm_tfledc;
61088 + break;
61089 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
61090 + *stats_reg = &regs->fmbm_tfufdc;
61091 + break;
61092 + default:
61093 + *stats_reg = NULL;
61094 + }
61095 +}
61096 +
61097 +static void get_oh_stats_reg(struct fman_port *port,
61098 + enum fman_port_stats_counters counter,
61099 + uint32_t **stats_reg)
61100 +{
61101 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61102 +
61103 + switch (counter) {
61104 + case E_FMAN_PORT_STATS_CNT_FRAME:
61105 + *stats_reg = &regs->fmbm_ofrc;
61106 + break;
61107 + case E_FMAN_PORT_STATS_CNT_DISCARD:
61108 + *stats_reg = &regs->fmbm_ofdc;
61109 + break;
61110 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
61111 + *stats_reg = &regs->fmbm_obdc;
61112 + break;
61113 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
61114 + *stats_reg = &regs->fmbm_offc;
61115 + break;
61116 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
61117 + *stats_reg = &regs->fmbm_ofldec;
61118 + break;
61119 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
61120 + *stats_reg = &regs->fmbm_ofledc;
61121 + break;
61122 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
61123 + *stats_reg = &regs->fmbm_ofufdc;
61124 + break;
61125 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
61126 + *stats_reg = &regs->fmbm_ofwdc;
61127 + break;
61128 + default:
61129 + *stats_reg = NULL;
61130 + }
61131 +}
61132 +
61133 +static void get_rx_perf_reg(struct fman_port *port,
61134 + enum fman_port_perf_counters counter,
61135 + uint32_t **perf_reg)
61136 +{
61137 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
61138 +
61139 + switch (counter) {
61140 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61141 + *perf_reg = &regs->fmbm_rccn;
61142 + break;
61143 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61144 + *perf_reg = &regs->fmbm_rtuc;
61145 + break;
61146 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61147 + *perf_reg = &regs->fmbm_rrquc;
61148 + break;
61149 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61150 + *perf_reg = &regs->fmbm_rduc;
61151 + break;
61152 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61153 + *perf_reg = &regs->fmbm_rfuc;
61154 + break;
61155 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
61156 + *perf_reg = &regs->fmbm_rpac;
61157 + break;
61158 + default:
61159 + *perf_reg = NULL;
61160 + }
61161 +}
61162 +
61163 +static void get_tx_perf_reg(struct fman_port *port,
61164 + enum fman_port_perf_counters counter,
61165 + uint32_t **perf_reg)
61166 +{
61167 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
61168 +
61169 + switch (counter) {
61170 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61171 + *perf_reg = &regs->fmbm_tccn;
61172 + break;
61173 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61174 + *perf_reg = &regs->fmbm_ttuc;
61175 + break;
61176 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
61177 + *perf_reg = &regs->fmbm_ttcquc;
61178 + break;
61179 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61180 + *perf_reg = &regs->fmbm_tduc;
61181 + break;
61182 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61183 + *perf_reg = &regs->fmbm_tfuc;
61184 + break;
61185 + default:
61186 + *perf_reg = NULL;
61187 + }
61188 +}
61189 +
61190 +static void get_oh_perf_reg(struct fman_port *port,
61191 + enum fman_port_perf_counters counter,
61192 + uint32_t **perf_reg)
61193 +{
61194 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
61195 +
61196 + switch (counter) {
61197 + case E_FMAN_PORT_PERF_CNT_CYCLE:
61198 + *perf_reg = &regs->fmbm_occn;
61199 + break;
61200 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
61201 + *perf_reg = &regs->fmbm_otuc;
61202 + break;
61203 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
61204 + *perf_reg = &regs->fmbm_oduc;
61205 + break;
61206 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
61207 + *perf_reg = &regs->fmbm_ofuc;
61208 + break;
61209 + default:
61210 + *perf_reg = NULL;
61211 + }
61212 +}
61213 +
61214 +static void get_qmi_counter_reg(struct fman_port *port,
61215 + enum fman_port_qmi_counters counter,
61216 + uint32_t **queue_reg)
61217 +{
61218 + struct fman_port_qmi_regs *regs = port->qmi_regs;
61219 +
61220 + switch (counter) {
61221 + case E_FMAN_PORT_ENQ_TOTAL:
61222 + *queue_reg = &regs->fmqm_pnetfc;
61223 + break;
61224 + case E_FMAN_PORT_DEQ_TOTAL:
61225 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61226 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61227 + /* Counter not available for Rx ports */
61228 + *queue_reg = NULL;
61229 + else
61230 + *queue_reg = &regs->fmqm_pndtfc;
61231 + break;
61232 + case E_FMAN_PORT_DEQ_FROM_DFLT:
61233 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61234 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61235 + /* Counter not available for Rx ports */
61236 + *queue_reg = NULL;
61237 + else
61238 + *queue_reg = &regs->fmqm_pndfdc;
61239 + break;
61240 + case E_FMAN_PORT_DEQ_CONFIRM:
61241 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
61242 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
61243 + /* Counter not available for Rx ports */
61244 + *queue_reg = NULL;
61245 + else
61246 + *queue_reg = &regs->fmqm_pndcc;
61247 + break;
61248 + default:
61249 + *queue_reg = NULL;
61250 + }
61251 +}
61252 +
61253 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
61254 +{
61255 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
61256 + cfg->dma_ic_stash_on = FALSE;
61257 + cfg->dma_header_stash_on = FALSE;
61258 + cfg->dma_sg_stash_on = FALSE;
61259 + cfg->dma_write_optimize = TRUE;
61260 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
61261 + cfg->discard_override = FALSE;
61262 + cfg->checksum_bytes_ignore = 0;
61263 + cfg->rx_cut_end_bytes = 4;
61264 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61265 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
61266 + cfg->rx_fd_bits = 0;
61267 + cfg->ic_ext_offset = 0;
61268 + cfg->ic_int_offset = 0;
61269 + cfg->ic_size = 0;
61270 + cfg->int_buf_start_margin = 0;
61271 + cfg->ext_buf_start_margin = 0;
61272 + cfg->ext_buf_end_margin = 0;
61273 + cfg->tx_fifo_min_level = 0;
61274 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
61275 + cfg->stats_counters_enable = TRUE;
61276 + cfg->perf_counters_enable = TRUE;
61277 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
61278 +
61279 + if (type == E_FMAN_PORT_TYPE_HC) {
61280 + cfg->sync_req = FALSE;
61281 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
61282 + } else {
61283 + cfg->sync_req = TRUE;
61284 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
61285 + }
61286 +
61287 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
61288 + cfg->tx_fifo_deq_pipeline_depth = 4;
61289 + cfg->deq_high_pri = TRUE;
61290 + cfg->deq_byte_cnt = 0x1400;
61291 + } else {
61292 + if ((type == E_FMAN_PORT_TYPE_HC) ||
61293 + (type == E_FMAN_PORT_TYPE_OP))
61294 + cfg->tx_fifo_deq_pipeline_depth = 2;
61295 + else
61296 + cfg->tx_fifo_deq_pipeline_depth = 1;
61297 +
61298 + cfg->deq_high_pri = FALSE;
61299 + cfg->deq_byte_cnt = 0x400;
61300 + }
61301 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
61302 +}
61303 +
61304 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
61305 +{
61306 + uint32_t *bp_reg, tmp;
61307 + uint8_t i, id;
61308 +
61309 + /* Find the pool */
61310 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61311 + for (i = 0;
61312 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
61313 + i++) {
61314 + tmp = ioread32be(&bp_reg[i]);
61315 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
61316 + BMI_EXT_BUF_POOL_ID_SHIFT);
61317 +
61318 + if (id == bpid)
61319 + break;
61320 + }
61321 +
61322 + return i;
61323 +}
61324 +
61325 +int fman_port_init(struct fman_port *port,
61326 + struct fman_port_cfg *cfg,
61327 + struct fman_port_params *params)
61328 +{
61329 + int err;
61330 +
61331 + /* Init BMI registers */
61332 + switch (port->type) {
61333 + case E_FMAN_PORT_TYPE_RX:
61334 + case E_FMAN_PORT_TYPE_RX_10G:
61335 + err = init_bmi_rx(port, cfg, params);
61336 + break;
61337 + case E_FMAN_PORT_TYPE_TX:
61338 + case E_FMAN_PORT_TYPE_TX_10G:
61339 + err = init_bmi_tx(port, cfg, params);
61340 + break;
61341 + case E_FMAN_PORT_TYPE_OP:
61342 + case E_FMAN_PORT_TYPE_HC:
61343 + err = init_bmi_oh(port, cfg, params);
61344 + break;
61345 + default:
61346 + return -EINVAL;
61347 + }
61348 +
61349 + if (err)
61350 + return err;
61351 +
61352 + /* Init QMI registers */
61353 + if (!port->im_en)
61354 + {
61355 + err = init_qmi(port, cfg, params);
61356 + return err;
61357 + }
61358 + return 0;
61359 +}
61360 +
61361 +int fman_port_enable(struct fman_port *port)
61362 +{
61363 + uint32_t *bmi_cfg_reg, tmp;
61364 + bool rx_port;
61365 +
61366 + switch (port->type) {
61367 + case E_FMAN_PORT_TYPE_RX:
61368 + case E_FMAN_PORT_TYPE_RX_10G:
61369 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61370 + rx_port = TRUE;
61371 + break;
61372 + case E_FMAN_PORT_TYPE_TX:
61373 + case E_FMAN_PORT_TYPE_TX_10G:
61374 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61375 + rx_port = FALSE;
61376 + break;
61377 + case E_FMAN_PORT_TYPE_OP:
61378 + case E_FMAN_PORT_TYPE_HC:
61379 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61380 + rx_port = FALSE;
61381 + break;
61382 + default:
61383 + return -EINVAL;
61384 + }
61385 +
61386 + /* Enable QMI */
61387 + if (!rx_port) {
61388 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
61389 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61390 + }
61391 +
61392 + /* Enable BMI */
61393 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
61394 + iowrite32be(tmp, bmi_cfg_reg);
61395 +
61396 + return 0;
61397 +}
61398 +
61399 +int fman_port_disable(const struct fman_port *port)
61400 +{
61401 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
61402 + bool rx_port, failure = FALSE;
61403 + int count;
61404 +
61405 + switch (port->type) {
61406 + case E_FMAN_PORT_TYPE_RX:
61407 + case E_FMAN_PORT_TYPE_RX_10G:
61408 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
61409 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
61410 + rx_port = TRUE;
61411 + break;
61412 + case E_FMAN_PORT_TYPE_TX:
61413 + case E_FMAN_PORT_TYPE_TX_10G:
61414 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
61415 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
61416 + rx_port = FALSE;
61417 + break;
61418 + case E_FMAN_PORT_TYPE_OP:
61419 + case E_FMAN_PORT_TYPE_HC:
61420 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
61421 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
61422 + rx_port = FALSE;
61423 + break;
61424 + default:
61425 + return -EINVAL;
61426 + }
61427 +
61428 + /* Disable QMI */
61429 + if (!rx_port) {
61430 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
61431 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61432 +
61433 + /* Wait for QMI to finish FD handling */
61434 + count = 100;
61435 + do {
61436 + udelay(10);
61437 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
61438 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
61439 +
61440 + if (count == 0)
61441 + {
61442 + /* Timeout */
61443 + failure = TRUE;
61444 + }
61445 + }
61446 +
61447 + /* Disable BMI */
61448 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
61449 + iowrite32be(tmp, bmi_cfg_reg);
61450 +
61451 + /* Wait for graceful stop end */
61452 + count = 500;
61453 + do {
61454 + udelay(10);
61455 + tmp = ioread32be(bmi_status_reg);
61456 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
61457 +
61458 + if (count == 0)
61459 + {
61460 + /* Timeout */
61461 + failure = TRUE;
61462 + }
61463 +
61464 + if (failure)
61465 + return -EBUSY;
61466 +
61467 + return 0;
61468 +}
61469 +
61470 +int fman_port_set_bpools(const struct fman_port *port,
61471 + const struct fman_port_bpools *bp)
61472 +{
61473 + uint32_t tmp, *bp_reg, *bp_depl_reg;
61474 + uint8_t i, max_bp_num;
61475 + bool grp_depl_used = FALSE, rx_port;
61476 +
61477 + switch (port->type) {
61478 + case E_FMAN_PORT_TYPE_RX:
61479 + case E_FMAN_PORT_TYPE_RX_10G:
61480 + max_bp_num = port->ext_pools_num;
61481 + rx_port = TRUE;
61482 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
61483 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
61484 + break;
61485 + case E_FMAN_PORT_TYPE_OP:
61486 + if (port->fm_rev_maj != 4)
61487 + return -EINVAL;
61488 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
61489 + rx_port = FALSE;
61490 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
61491 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
61492 + break;
61493 + default:
61494 + return -EINVAL;
61495 + }
61496 +
61497 + if (rx_port) {
61498 + /* Check buffers are provided in ascending order */
61499 + for (i = 0;
61500 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
61501 + i++) {
61502 + if (bp->bpool[i].size > bp->bpool[i+1].size)
61503 + return -EINVAL;
61504 + }
61505 + }
61506 +
61507 + /* Set up external buffers pools */
61508 + for (i = 0; i < bp->count; i++) {
61509 + tmp = BMI_EXT_BUF_POOL_VALID;
61510 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
61511 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
61512 +
61513 + if (rx_port) {
61514 + if (bp->counters_enable)
61515 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61516 +
61517 + if (bp->bpool[i].is_backup)
61518 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
61519 +
61520 + tmp |= (uint32_t)bp->bpool[i].size;
61521 + }
61522 +
61523 + iowrite32be(tmp, &bp_reg[i]);
61524 + }
61525 +
61526 + /* Clear unused pools */
61527 + for (i = bp->count; i < max_bp_num; i++)
61528 + iowrite32be(0, &bp_reg[i]);
61529 +
61530 + /* Pools depletion */
61531 + tmp = 0;
61532 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
61533 + if (bp->bpool[i].grp_bp_depleted) {
61534 + grp_depl_used = TRUE;
61535 + tmp |= 0x80000000 >> i;
61536 + }
61537 +
61538 + if (bp->bpool[i].single_bp_depleted)
61539 + tmp |= 0x80 >> i;
61540 +
61541 + if (bp->bpool[i].pfc_priorities_en)
61542 + tmp |= 0x0100 << i;
61543 + }
61544 +
61545 + if (grp_depl_used)
61546 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
61547 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
61548 +
61549 + iowrite32be(tmp, bp_depl_reg);
61550 + return 0;
61551 +}
61552 +
61553 +int fman_port_set_rate_limiter(struct fman_port *port,
61554 + struct fman_port_rate_limiter *rate_limiter)
61555 +{
61556 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
61557 + uint32_t granularity, tmp;
61558 + uint8_t usec_bit, factor;
61559 +
61560 + switch (port->type) {
61561 + case E_FMAN_PORT_TYPE_TX:
61562 + case E_FMAN_PORT_TYPE_TX_10G:
61563 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
61564 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61565 + granularity = BMI_RATE_LIMIT_GRAN_TX;
61566 + break;
61567 + case E_FMAN_PORT_TYPE_OP:
61568 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
61569 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61570 + granularity = BMI_RATE_LIMIT_GRAN_OP;
61571 + break;
61572 + default:
61573 + return -EINVAL;
61574 + }
61575 +
61576 + /* Factor is per 1 usec count */
61577 + factor = 1;
61578 + usec_bit = rate_limiter->count_1micro_bit;
61579 +
61580 + /* If rate limit is too small for an 1usec factor, adjust timestamp
61581 + * scale and multiply the factor */
61582 + while (rate_limiter->rate < (granularity / factor)) {
61583 + if (usec_bit == 31)
61584 + /* Can't configure rate limiter - rate is too small */
61585 + return -EINVAL;
61586 +
61587 + usec_bit++;
61588 + factor <<= 1;
61589 + }
61590 +
61591 + /* Figure out register value. The "while" above quarantees that
61592 + * (rate_limiter->rate * factor / granularity) >= 1 */
61593 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
61594 +
61595 + /* Check rate limit isn't too large */
61596 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
61597 + return -EINVAL;
61598 +
61599 + /* Check burst size is in allowed range */
61600 + if ((rate_limiter->burst_size == 0) ||
61601 + (rate_limiter->burst_size >
61602 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
61603 + return -EINVAL;
61604 +
61605 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
61606 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
61607 +
61608 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61609 + (port->fm_rev_maj == 4)) {
61610 + if (rate_limiter->high_burst_size_gran)
61611 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
61612 + }
61613 +
61614 + iowrite32be(tmp, rate_limit_reg);
61615 +
61616 + /* Set up rate limiter scale register */
61617 + tmp = BMI_RATE_LIMIT_SCALE_EN;
61618 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
61619 +
61620 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
61621 + (port->fm_rev_maj == 4))
61622 + tmp |= rate_limiter->rate_factor;
61623 +
61624 + iowrite32be(tmp, rate_limit_scale_reg);
61625 +
61626 + return 0;
61627 +}
61628 +
61629 +int fman_port_delete_rate_limiter(struct fman_port *port)
61630 +{
61631 + uint32_t *rate_limit_scale_reg;
61632 +
61633 + switch (port->type) {
61634 + case E_FMAN_PORT_TYPE_TX:
61635 + case E_FMAN_PORT_TYPE_TX_10G:
61636 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
61637 + break;
61638 + case E_FMAN_PORT_TYPE_OP:
61639 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
61640 + break;
61641 + default:
61642 + return -EINVAL;
61643 + }
61644 +
61645 + iowrite32be(0, rate_limit_scale_reg);
61646 + return 0;
61647 +}
61648 +
61649 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
61650 +{
61651 + uint32_t *err_mask_reg;
61652 +
61653 + /* Obtain register address */
61654 + switch (port->type) {
61655 + case E_FMAN_PORT_TYPE_RX:
61656 + case E_FMAN_PORT_TYPE_RX_10G:
61657 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
61658 + break;
61659 + case E_FMAN_PORT_TYPE_OP:
61660 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
61661 + break;
61662 + default:
61663 + return -EINVAL;
61664 + }
61665 +
61666 + iowrite32be(err_mask, err_mask_reg);
61667 + return 0;
61668 +}
61669 +
61670 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
61671 +{
61672 + uint32_t *discard_mask_reg;
61673 +
61674 + /* Obtain register address */
61675 + switch (port->type) {
61676 + case E_FMAN_PORT_TYPE_RX:
61677 + case E_FMAN_PORT_TYPE_RX_10G:
61678 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
61679 + break;
61680 + case E_FMAN_PORT_TYPE_OP:
61681 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
61682 + break;
61683 + default:
61684 + return -EINVAL;
61685 + }
61686 +
61687 + iowrite32be(discard_mask, discard_mask_reg);
61688 + return 0;
61689 +}
61690 +
61691 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
61692 + uint8_t rx_fd_bits,
61693 + bool add)
61694 +{
61695 + uint32_t tmp;
61696 +
61697 + switch (port->type) {
61698 + case E_FMAN_PORT_TYPE_RX:
61699 + case E_FMAN_PORT_TYPE_RX_10G:
61700 + break;
61701 + default:
61702 + return -EINVAL;
61703 + }
61704 +
61705 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
61706 +
61707 + if (add)
61708 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
61709 + else
61710 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
61711 +
61712 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
61713 + return 0;
61714 +}
61715 +
61716 +int fman_port_set_perf_cnt_params(struct fman_port *port,
61717 + struct fman_port_perf_cnt_params *params)
61718 +{
61719 + uint32_t *pcp_reg, tmp;
61720 +
61721 + /* Obtain register address and check parameters are in range */
61722 + switch (port->type) {
61723 + case E_FMAN_PORT_TYPE_RX:
61724 + case E_FMAN_PORT_TYPE_RX_10G:
61725 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
61726 + if ((params->queue_val == 0) ||
61727 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
61728 + return -EINVAL;
61729 + break;
61730 + case E_FMAN_PORT_TYPE_TX:
61731 + case E_FMAN_PORT_TYPE_TX_10G:
61732 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
61733 + if ((params->queue_val == 0) ||
61734 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
61735 + return -EINVAL;
61736 + break;
61737 + case E_FMAN_PORT_TYPE_OP:
61738 + case E_FMAN_PORT_TYPE_HC:
61739 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
61740 + if (params->queue_val != 0)
61741 + return -EINVAL;
61742 + break;
61743 + default:
61744 + return -EINVAL;
61745 + }
61746 +
61747 + if ((params->task_val == 0) ||
61748 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
61749 + return -EINVAL;
61750 + if ((params->dma_val == 0) ||
61751 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
61752 + return -EINVAL;
61753 + if ((params->fifo_val == 0) ||
61754 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
61755 + MAX_PERFORMANCE_FIFO_COMP))
61756 + return -EINVAL;
61757 + tmp = (uint32_t)(params->task_val - 1) <<
61758 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
61759 + tmp |= (uint32_t)(params->dma_val - 1) <<
61760 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
61761 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
61762 +
61763 + switch (port->type) {
61764 + case E_FMAN_PORT_TYPE_RX:
61765 + case E_FMAN_PORT_TYPE_RX_10G:
61766 + case E_FMAN_PORT_TYPE_TX:
61767 + case E_FMAN_PORT_TYPE_TX_10G:
61768 + tmp |= (uint32_t)(params->queue_val - 1) <<
61769 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
61770 + break;
61771 + default:
61772 + break;
61773 + }
61774 +
61775 +
61776 + iowrite32be(tmp, pcp_reg);
61777 + return 0;
61778 +}
61779 +
61780 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
61781 +{
61782 + uint32_t *stats_reg, tmp;
61783 +
61784 + switch (port->type) {
61785 + case E_FMAN_PORT_TYPE_RX:
61786 + case E_FMAN_PORT_TYPE_RX_10G:
61787 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
61788 + break;
61789 + case E_FMAN_PORT_TYPE_TX:
61790 + case E_FMAN_PORT_TYPE_TX_10G:
61791 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
61792 + break;
61793 + case E_FMAN_PORT_TYPE_OP:
61794 + case E_FMAN_PORT_TYPE_HC:
61795 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
61796 + break;
61797 + default:
61798 + return -EINVAL;
61799 + }
61800 +
61801 + tmp = ioread32be(stats_reg);
61802 +
61803 + if (enable)
61804 + tmp |= BMI_COUNTERS_EN;
61805 + else
61806 + tmp &= ~BMI_COUNTERS_EN;
61807 +
61808 + iowrite32be(tmp, stats_reg);
61809 + return 0;
61810 +}
61811 +
61812 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
61813 +{
61814 + uint32_t *stats_reg, tmp;
61815 +
61816 + switch (port->type) {
61817 + case E_FMAN_PORT_TYPE_RX:
61818 + case E_FMAN_PORT_TYPE_RX_10G:
61819 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
61820 + break;
61821 + case E_FMAN_PORT_TYPE_TX:
61822 + case E_FMAN_PORT_TYPE_TX_10G:
61823 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
61824 + break;
61825 + case E_FMAN_PORT_TYPE_OP:
61826 + case E_FMAN_PORT_TYPE_HC:
61827 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
61828 + break;
61829 + default:
61830 + return -EINVAL;
61831 + }
61832 +
61833 + tmp = ioread32be(stats_reg);
61834 +
61835 + if (enable)
61836 + tmp |= BMI_COUNTERS_EN;
61837 + else
61838 + tmp &= ~BMI_COUNTERS_EN;
61839 +
61840 + iowrite32be(tmp, stats_reg);
61841 + return 0;
61842 +}
61843 +
61844 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
61845 +{
61846 + uint32_t tmp;
61847 +
61848 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
61849 +
61850 + if (enable)
61851 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
61852 + else
61853 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
61854 +
61855 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
61856 + return 0;
61857 +}
61858 +
61859 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
61860 + uint8_t bpid,
61861 + bool enable)
61862 +{
61863 + uint8_t index;
61864 + uint32_t tmp;
61865 +
61866 + switch (port->type) {
61867 + case E_FMAN_PORT_TYPE_RX:
61868 + case E_FMAN_PORT_TYPE_RX_10G:
61869 + break;
61870 + default:
61871 + return -EINVAL;
61872 + }
61873 +
61874 + /* Find the pool */
61875 + index = fman_port_find_bpool(port, bpid);
61876 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
61877 + /* Not found */
61878 + return -EINVAL;
61879 +
61880 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
61881 +
61882 + if (enable)
61883 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
61884 + else
61885 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
61886 +
61887 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
61888 + return 0;
61889 +}
61890 +
61891 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
61892 + enum fman_port_stats_counters counter)
61893 +{
61894 + uint32_t *stats_reg, ret_val;
61895 +
61896 + switch (port->type) {
61897 + case E_FMAN_PORT_TYPE_RX:
61898 + case E_FMAN_PORT_TYPE_RX_10G:
61899 + get_rx_stats_reg(port, counter, &stats_reg);
61900 + break;
61901 + case E_FMAN_PORT_TYPE_TX:
61902 + case E_FMAN_PORT_TYPE_TX_10G:
61903 + get_tx_stats_reg(port, counter, &stats_reg);
61904 + break;
61905 + case E_FMAN_PORT_TYPE_OP:
61906 + case E_FMAN_PORT_TYPE_HC:
61907 + get_oh_stats_reg(port, counter, &stats_reg);
61908 + break;
61909 + default:
61910 + stats_reg = NULL;
61911 + }
61912 +
61913 + if (stats_reg == NULL)
61914 + return 0;
61915 +
61916 + ret_val = ioread32be(stats_reg);
61917 + return ret_val;
61918 +}
61919 +
61920 +void fman_port_set_stats_counter(struct fman_port *port,
61921 + enum fman_port_stats_counters counter,
61922 + uint32_t value)
61923 +{
61924 + uint32_t *stats_reg;
61925 +
61926 + switch (port->type) {
61927 + case E_FMAN_PORT_TYPE_RX:
61928 + case E_FMAN_PORT_TYPE_RX_10G:
61929 + get_rx_stats_reg(port, counter, &stats_reg);
61930 + break;
61931 + case E_FMAN_PORT_TYPE_TX:
61932 + case E_FMAN_PORT_TYPE_TX_10G:
61933 + get_tx_stats_reg(port, counter, &stats_reg);
61934 + break;
61935 + case E_FMAN_PORT_TYPE_OP:
61936 + case E_FMAN_PORT_TYPE_HC:
61937 + get_oh_stats_reg(port, counter, &stats_reg);
61938 + break;
61939 + default:
61940 + stats_reg = NULL;
61941 + }
61942 +
61943 + if (stats_reg == NULL)
61944 + return;
61945 +
61946 + iowrite32be(value, stats_reg);
61947 +}
61948 +
61949 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
61950 + enum fman_port_perf_counters counter)
61951 +{
61952 + uint32_t *perf_reg, ret_val;
61953 +
61954 + switch (port->type) {
61955 + case E_FMAN_PORT_TYPE_RX:
61956 + case E_FMAN_PORT_TYPE_RX_10G:
61957 + get_rx_perf_reg(port, counter, &perf_reg);
61958 + break;
61959 + case E_FMAN_PORT_TYPE_TX:
61960 + case E_FMAN_PORT_TYPE_TX_10G:
61961 + get_tx_perf_reg(port, counter, &perf_reg);
61962 + break;
61963 + case E_FMAN_PORT_TYPE_OP:
61964 + case E_FMAN_PORT_TYPE_HC:
61965 + get_oh_perf_reg(port, counter, &perf_reg);
61966 + break;
61967 + default:
61968 + perf_reg = NULL;
61969 + }
61970 +
61971 + if (perf_reg == NULL)
61972 + return 0;
61973 +
61974 + ret_val = ioread32be(perf_reg);
61975 + return ret_val;
61976 +}
61977 +
61978 +void fman_port_set_perf_counter(struct fman_port *port,
61979 + enum fman_port_perf_counters counter,
61980 + uint32_t value)
61981 +{
61982 + uint32_t *perf_reg;
61983 +
61984 + switch (port->type) {
61985 + case E_FMAN_PORT_TYPE_RX:
61986 + case E_FMAN_PORT_TYPE_RX_10G:
61987 + get_rx_perf_reg(port, counter, &perf_reg);
61988 + break;
61989 + case E_FMAN_PORT_TYPE_TX:
61990 + case E_FMAN_PORT_TYPE_TX_10G:
61991 + get_tx_perf_reg(port, counter, &perf_reg);
61992 + break;
61993 + case E_FMAN_PORT_TYPE_OP:
61994 + case E_FMAN_PORT_TYPE_HC:
61995 + get_oh_perf_reg(port, counter, &perf_reg);
61996 + break;
61997 + default:
61998 + perf_reg = NULL;
61999 + }
62000 +
62001 + if (perf_reg == NULL)
62002 + return;
62003 +
62004 + iowrite32be(value, perf_reg);
62005 +}
62006 +
62007 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
62008 + enum fman_port_qmi_counters counter)
62009 +{
62010 + uint32_t *queue_reg, ret_val;
62011 +
62012 + get_qmi_counter_reg(port, counter, &queue_reg);
62013 +
62014 + if (queue_reg == NULL)
62015 + return 0;
62016 +
62017 + ret_val = ioread32be(queue_reg);
62018 + return ret_val;
62019 +}
62020 +
62021 +void fman_port_set_qmi_counter(struct fman_port *port,
62022 + enum fman_port_qmi_counters counter,
62023 + uint32_t value)
62024 +{
62025 + uint32_t *queue_reg;
62026 +
62027 + get_qmi_counter_reg(port, counter, &queue_reg);
62028 +
62029 + if (queue_reg == NULL)
62030 + return;
62031 +
62032 + iowrite32be(value, queue_reg);
62033 +}
62034 +
62035 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
62036 +{
62037 + uint8_t index;
62038 + uint32_t ret_val;
62039 +
62040 + switch (port->type) {
62041 + case E_FMAN_PORT_TYPE_RX:
62042 + case E_FMAN_PORT_TYPE_RX_10G:
62043 + break;
62044 + default:
62045 + return 0;
62046 + }
62047 +
62048 + /* Find the pool */
62049 + index = fman_port_find_bpool(port, bpid);
62050 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
62051 + /* Not found */
62052 + return 0;
62053 +
62054 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
62055 + return ret_val;
62056 +}
62057 +
62058 +void fman_port_set_bpool_counter(struct fman_port *port,
62059 + uint8_t bpid,
62060 + uint32_t value)
62061 +{
62062 + uint8_t index;
62063 +
62064 + switch (port->type) {
62065 + case E_FMAN_PORT_TYPE_RX:
62066 + case E_FMAN_PORT_TYPE_RX_10G:
62067 + break;
62068 + default:
62069 + return;
62070 + }
62071 +
62072 + /* Find the pool */
62073 + index = fman_port_find_bpool(port, bpid);
62074 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
62075 + /* Not found */
62076 + return;
62077 +
62078 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
62079 +}
62080 +
62081 +int fman_port_add_congestion_grps(struct fman_port *port,
62082 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
62083 +{
62084 + int i;
62085 + uint32_t tmp, *grp_map_reg;
62086 + uint8_t max_grp_map_num;
62087 +
62088 + switch (port->type) {
62089 + case E_FMAN_PORT_TYPE_RX:
62090 + case E_FMAN_PORT_TYPE_RX_10G:
62091 + if (port->fm_rev_maj == 4)
62092 + max_grp_map_num = 1;
62093 + else
62094 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
62095 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
62096 + break;
62097 + case E_FMAN_PORT_TYPE_OP:
62098 + max_grp_map_num = 1;
62099 + if (port->fm_rev_maj != 4)
62100 + return -EINVAL;
62101 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62102 + break;
62103 + default:
62104 + return -EINVAL;
62105 + }
62106 +
62107 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62108 + if (grps_map[i] == 0)
62109 + continue;
62110 + tmp = ioread32be(&grp_map_reg[i]);
62111 + tmp |= grps_map[i];
62112 + iowrite32be(tmp, &grp_map_reg[i]);
62113 + }
62114 +
62115 + return 0;
62116 +}
62117 +
62118 +int fman_port_remove_congestion_grps(struct fman_port *port,
62119 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
62120 +{
62121 + int i;
62122 + uint32_t tmp, *grp_map_reg;
62123 + uint8_t max_grp_map_num;
62124 +
62125 + switch (port->type) {
62126 + case E_FMAN_PORT_TYPE_RX:
62127 + case E_FMAN_PORT_TYPE_RX_10G:
62128 + if (port->fm_rev_maj == 4)
62129 + max_grp_map_num = 1;
62130 + else
62131 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
62132 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
62133 + break;
62134 + case E_FMAN_PORT_TYPE_OP:
62135 + max_grp_map_num = 1;
62136 + if (port->fm_rev_maj != 4)
62137 + return -EINVAL;
62138 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
62139 + break;
62140 + default:
62141 + return -EINVAL;
62142 + }
62143 +
62144 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
62145 + if (grps_map[i] == 0)
62146 + continue;
62147 + tmp = ioread32be(&grp_map_reg[i]);
62148 + tmp &= ~grps_map[i];
62149 + iowrite32be(tmp, &grp_map_reg[i]);
62150 + }
62151 + return 0;
62152 +}
62153 --- /dev/null
62154 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
62155 @@ -0,0 +1,15 @@
62156 +#
62157 +# Makefile for the Freescale Ethernet controllers
62158 +#
62159 +ccflags-y += -DVERSION=\"\"
62160 +#
62161 +#Include netcomm SW specific definitions
62162 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
62163 +
62164 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
62165 +
62166 +ccflags-y += -I$(NCSW_FM_INC)
62167 +
62168 +obj-y += fsl-ncsw-RTC.o
62169 +
62170 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
62171 --- /dev/null
62172 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
62173 @@ -0,0 +1,692 @@
62174 +/*
62175 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62176 + *
62177 + * Redistribution and use in source and binary forms, with or without
62178 + * modification, are permitted provided that the following conditions are met:
62179 + * * Redistributions of source code must retain the above copyright
62180 + * notice, this list of conditions and the following disclaimer.
62181 + * * Redistributions in binary form must reproduce the above copyright
62182 + * notice, this list of conditions and the following disclaimer in the
62183 + * documentation and/or other materials provided with the distribution.
62184 + * * Neither the name of Freescale Semiconductor nor the
62185 + * names of its contributors may be used to endorse or promote products
62186 + * derived from this software without specific prior written permission.
62187 + *
62188 + *
62189 + * ALTERNATIVELY, this software may be distributed under the terms of the
62190 + * GNU General Public License ("GPL") as published by the Free Software
62191 + * Foundation, either version 2 of that License or (at your option) any
62192 + * later version.
62193 + *
62194 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62195 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62196 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62197 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62198 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62199 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62200 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62201 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62202 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62203 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62204 + */
62205 +
62206 +
62207 +/******************************************************************************
62208 + @File fm_rtc.c
62209 +
62210 + @Description FM RTC driver implementation.
62211 +
62212 + @Cautions None
62213 +*//***************************************************************************/
62214 +#include <linux/math64.h>
62215 +#include "error_ext.h"
62216 +#include "debug_ext.h"
62217 +#include "string_ext.h"
62218 +#include "part_ext.h"
62219 +#include "xx_ext.h"
62220 +#include "ncsw_ext.h"
62221 +
62222 +#include "fm_rtc.h"
62223 +#include "fm_common.h"
62224 +
62225 +
62226 +
62227 +/*****************************************************************************/
62228 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
62229 +{
62230 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62231 + int i;
62232 +
62233 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
62234 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
62235 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
62236 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
62237 +
62238 + if (p_Rtc->outputClockDivisor == 0)
62239 + {
62240 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
62241 + ("Divisor for output clock (should be positive)"));
62242 + }
62243 +
62244 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
62245 + {
62246 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
62247 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
62248 + {
62249 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
62250 + }
62251 + }
62252 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
62253 + {
62254 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
62255 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
62256 + {
62257 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
62258 + }
62259 + }
62260 +
62261 + return E_OK;
62262 +}
62263 +
62264 +/*****************************************************************************/
62265 +static void RtcExceptions(t_Handle h_FmRtc)
62266 +{
62267 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62268 + struct rtc_regs *p_MemMap;
62269 + register uint32_t events;
62270 +
62271 + ASSERT_COND(p_Rtc);
62272 + p_MemMap = p_Rtc->p_MemMap;
62273 +
62274 + events = fman_rtc_check_and_clear_event(p_MemMap);
62275 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
62276 + {
62277 + if (p_Rtc->alarmParams[0].clearOnExpiration)
62278 + {
62279 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
62280 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
62281 + }
62282 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
62283 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
62284 + }
62285 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
62286 + {
62287 + if (p_Rtc->alarmParams[1].clearOnExpiration)
62288 + {
62289 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
62290 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
62291 + }
62292 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
62293 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
62294 + }
62295 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
62296 + {
62297 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
62298 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
62299 + }
62300 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
62301 + {
62302 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
62303 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
62304 + }
62305 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
62306 + {
62307 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
62308 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
62309 + }
62310 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
62311 + {
62312 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
62313 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
62314 + }
62315 +}
62316 +
62317 +
62318 +/*****************************************************************************/
62319 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
62320 +{
62321 + t_FmRtc *p_Rtc;
62322 +
62323 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
62324 +
62325 + /* Allocate memory for the FM RTC driver parameters */
62326 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
62327 + if (!p_Rtc)
62328 + {
62329 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
62330 + return NULL;
62331 + }
62332 +
62333 + memset(p_Rtc, 0, sizeof(t_FmRtc));
62334 +
62335 + /* Allocate memory for the FM RTC driver parameters */
62336 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
62337 + if (!p_Rtc->p_RtcDriverParam)
62338 + {
62339 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
62340 + XX_Free(p_Rtc);
62341 + return NULL;
62342 + }
62343 +
62344 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
62345 +
62346 + /* Store RTC configuration parameters */
62347 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
62348 +
62349 + /* Set default RTC configuration parameters */
62350 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
62351 +
62352 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
62353 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
62354 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
62355 +
62356 +
62357 + /* Store RTC parameters in the RTC control structure */
62358 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
62359 + p_Rtc->h_App = p_FmRtcParam->h_App;
62360 +
62361 + return p_Rtc;
62362 +}
62363 +
62364 +/*****************************************************************************/
62365 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
62366 +{
62367 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62368 + struct rtc_cfg *p_RtcDriverParam;
62369 + struct rtc_regs *p_MemMap;
62370 + uint32_t freqCompensation = 0;
62371 + uint64_t tmpDouble;
62372 + bool init_freq_comp = FALSE;
62373 +
62374 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
62375 + p_MemMap = p_Rtc->p_MemMap;
62376 +
62377 + if (CheckInitParameters(p_Rtc)!=E_OK)
62378 + RETURN_ERROR(MAJOR, E_CONFLICT,
62379 + ("Init Parameters are not Valid"));
62380 +
62381 + /* TODO check that no timestamping MACs are working in this stage. */
62382 +
62383 + /* find source clock frequency in Mhz */
62384 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
62385 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
62386 + else
62387 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
62388 +
62389 + /* if timer in Master mode Initialize TMR_CTRL */
62390 + /* We want the counter (TMR_CNT) to count in nano-seconds */
62391 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
62392 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
62393 + else
62394 + {
62395 + /* Initialize TMR_ADD with the initial frequency compensation value:
62396 + freqCompensation = (2^32 / frequency ratio) */
62397 + /* frequency ratio = sorce clock/rtc clock =
62398 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
62399 + init_freq_comp = TRUE;
62400 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
62401 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
62402 + }
62403 +
62404 + /* check the legality of the relation between source and destination clocks */
62405 + /* should be larger than 1.0001 */
62406 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
62407 + if ((tmpDouble) <= 10001)
62408 + RETURN_ERROR(MAJOR, E_CONFLICT,
62409 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
62410 +
62411 + fman_rtc_init(p_RtcDriverParam,
62412 + p_MemMap,
62413 + FM_RTC_NUM_OF_ALARMS,
62414 + FM_RTC_NUM_OF_PERIODIC_PULSES,
62415 + FM_RTC_NUM_OF_EXT_TRIGGERS,
62416 + init_freq_comp,
62417 + freqCompensation,
62418 + p_Rtc->outputClockDivisor);
62419 +
62420 + /* Register the FM RTC interrupt */
62421 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
62422 +
62423 + /* Free parameters structures */
62424 + XX_Free(p_Rtc->p_RtcDriverParam);
62425 + p_Rtc->p_RtcDriverParam = NULL;
62426 +
62427 + return E_OK;
62428 +}
62429 +
62430 +/*****************************************************************************/
62431 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
62432 +{
62433 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62434 +
62435 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62436 +
62437 + if (p_Rtc->p_RtcDriverParam)
62438 + {
62439 + XX_Free(p_Rtc->p_RtcDriverParam);
62440 + }
62441 + else
62442 + {
62443 + FM_RTC_Disable(h_FmRtc);
62444 + }
62445 +
62446 + /* Unregister FM RTC interrupt */
62447 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
62448 + XX_Free(p_Rtc);
62449 +
62450 + return E_OK;
62451 +}
62452 +
62453 +/*****************************************************************************/
62454 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
62455 + e_FmSrcClk srcClk,
62456 + uint32_t freqInMhz)
62457 +{
62458 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62459 +
62460 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62461 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62462 +
62463 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
62464 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
62465 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
62466 +
62467 + return E_OK;
62468 +}
62469 +
62470 +/*****************************************************************************/
62471 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
62472 +{
62473 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62474 +
62475 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62476 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62477 +
62478 + p_Rtc->clockPeriodNanoSec = period;
62479 +
62480 + return E_OK;
62481 +}
62482 +
62483 +/*****************************************************************************/
62484 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
62485 +{
62486 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62487 +
62488 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62489 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62490 +
62491 + p_Rtc->p_RtcDriverParam->bypass = enabled;
62492 +
62493 + return E_OK;
62494 +}
62495 +
62496 +/*****************************************************************************/
62497 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
62498 +{
62499 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62500 +
62501 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62502 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62503 +
62504 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
62505 +
62506 + return E_OK;
62507 +}
62508 +
62509 +/*****************************************************************************/
62510 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
62511 +{
62512 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62513 +
62514 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62515 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62516 +
62517 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
62518 +
62519 + return E_OK;
62520 +}
62521 +
62522 +/*****************************************************************************/
62523 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
62524 +{
62525 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62526 +
62527 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62528 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62529 +
62530 + p_Rtc->outputClockDivisor = divisor;
62531 +
62532 + return E_OK;
62533 +}
62534 +
62535 +/*****************************************************************************/
62536 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
62537 +{
62538 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62539 +
62540 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62541 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62542 +
62543 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
62544 +
62545 + return E_OK;
62546 +}
62547 +
62548 +/*****************************************************************************/
62549 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
62550 + uint8_t alarmId,
62551 + e_FmRtcAlarmPolarity alarmPolarity)
62552 +{
62553 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62554 +
62555 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62556 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62557 +
62558 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
62559 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62560 +
62561 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
62562 + (enum fman_rtc_alarm_polarity)alarmPolarity;
62563 +
62564 + return E_OK;
62565 +}
62566 +
62567 +/*****************************************************************************/
62568 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
62569 + uint8_t triggerId,
62570 + e_FmRtcTriggerPolarity triggerPolarity)
62571 +{
62572 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62573 +
62574 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62575 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62576 +
62577 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62578 + {
62579 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62580 + }
62581 +
62582 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
62583 + (enum fman_rtc_trigger_polarity)triggerPolarity;
62584 +
62585 + return E_OK;
62586 +}
62587 +
62588 +/*****************************************************************************/
62589 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
62590 +{
62591 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62592 +
62593 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62594 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62595 +
62596 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
62597 + return E_OK;
62598 +}
62599 +
62600 +/*****************************************************************************/
62601 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
62602 +{
62603 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62604 +
62605 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62606 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62607 +
62608 + /* TODO A check must be added here, that no timestamping MAC's
62609 + * are working in this stage. */
62610 + fman_rtc_disable(p_Rtc->p_MemMap);
62611 +
62612 + return E_OK;
62613 +}
62614 +
62615 +/*****************************************************************************/
62616 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
62617 +{
62618 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62619 +
62620 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62621 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62622 +
62623 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
62624 + return E_OK;
62625 +}
62626 +
62627 +/*****************************************************************************/
62628 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
62629 +{
62630 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62631 + uint64_t tmpAlarm;
62632 + bool enable = FALSE;
62633 +
62634 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62635 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62636 +
62637 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
62638 + {
62639 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
62640 + }
62641 +
62642 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
62643 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62644 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
62645 + p_Rtc->clockPeriodNanoSec));
62646 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
62647 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
62648 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62649 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
62650 + p_Rtc->clockPeriodNanoSec));
62651 +
62652 + if (p_FmRtcAlarmParams->f_AlarmCallback)
62653 + {
62654 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
62655 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
62656 + enable = TRUE;
62657 + }
62658 +
62659 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
62660 +
62661 + return E_OK;
62662 +}
62663 +
62664 +/*****************************************************************************/
62665 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
62666 +{
62667 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62668 + bool enable = FALSE;
62669 + uint64_t tmpFiper;
62670 +
62671 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62672 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62673 +
62674 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62675 + {
62676 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62677 + }
62678 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
62679 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
62680 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
62681 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62682 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
62683 + p_Rtc->clockPeriodNanoSec));
62684 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
62685 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
62686 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62687 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
62688 + p_Rtc->clockPeriodNanoSec));
62689 + if (tmpFiper & 0xffffffff00000000LL)
62690 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
62691 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
62692 + p_Rtc->clockPeriodNanoSec));
62693 +
62694 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
62695 + {
62696 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
62697 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
62698 + enable = TRUE;
62699 + }
62700 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
62701 + return E_OK;
62702 +}
62703 +
62704 +/*****************************************************************************/
62705 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
62706 +{
62707 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62708 +
62709 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62710 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62711 +
62712 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
62713 + {
62714 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
62715 + }
62716 +
62717 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
62718 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
62719 +
62720 + return E_OK;
62721 +}
62722 +
62723 +/*****************************************************************************/
62724 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
62725 +{
62726 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62727 + bool enable = FALSE;
62728 +
62729 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62730 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62731 +
62732 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62733 + {
62734 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62735 + }
62736 +
62737 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
62738 + {
62739 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
62740 + enable = TRUE;
62741 + }
62742 +
62743 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
62744 + return E_OK;
62745 +}
62746 +
62747 +/*****************************************************************************/
62748 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
62749 +{
62750 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62751 +
62752 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62753 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62754 +
62755 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62756 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
62757 +
62758 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
62759 +
62760 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
62761 +
62762 + return E_OK;
62763 +}
62764 +
62765 +/*****************************************************************************/
62766 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
62767 + uint8_t triggerId,
62768 + uint64_t *p_TimeStamp)
62769 +{
62770 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62771 +
62772 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62773 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62774 +
62775 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
62776 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
62777 +
62778 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
62779 +
62780 + return E_OK;
62781 +}
62782 +
62783 +/*****************************************************************************/
62784 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
62785 +{
62786 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62787 +
62788 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62789 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62790 +
62791 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
62792 +
62793 + return E_OK;
62794 +}
62795 +
62796 +/*****************************************************************************/
62797 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
62798 +{
62799 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62800 +
62801 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62802 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62803 +
62804 + do_div(ts, p_Rtc->clockPeriodNanoSec);
62805 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
62806 +
62807 + return E_OK;
62808 +}
62809 +
62810 +/*****************************************************************************/
62811 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
62812 +{
62813 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62814 +
62815 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62816 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62817 +
62818 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
62819 +
62820 + return E_OK;
62821 +}
62822 +
62823 +/*****************************************************************************/
62824 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
62825 +{
62826 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62827 +
62828 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62829 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62830 +
62831 + /* set the new freqCompensation */
62832 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
62833 +
62834 + return E_OK;
62835 +}
62836 +
62837 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
62838 +/*****************************************************************************/
62839 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
62840 +{
62841 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62842 +
62843 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62844 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62845 +
62846 + /* enable interrupt */
62847 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
62848 +
62849 + return E_OK;
62850 +}
62851 +
62852 +/*****************************************************************************/
62853 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
62854 +{
62855 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
62856 +
62857 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
62858 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
62859 +
62860 + /* disable interrupt */
62861 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
62862 +
62863 + return E_OK;
62864 +}
62865 +#endif
62866 --- /dev/null
62867 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
62868 @@ -0,0 +1,96 @@
62869 +/*
62870 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62871 + *
62872 + * Redistribution and use in source and binary forms, with or without
62873 + * modification, are permitted provided that the following conditions are met:
62874 + * * Redistributions of source code must retain the above copyright
62875 + * notice, this list of conditions and the following disclaimer.
62876 + * * Redistributions in binary form must reproduce the above copyright
62877 + * notice, this list of conditions and the following disclaimer in the
62878 + * documentation and/or other materials provided with the distribution.
62879 + * * Neither the name of Freescale Semiconductor nor the
62880 + * names of its contributors may be used to endorse or promote products
62881 + * derived from this software without specific prior written permission.
62882 + *
62883 + *
62884 + * ALTERNATIVELY, this software may be distributed under the terms of the
62885 + * GNU General Public License ("GPL") as published by the Free Software
62886 + * Foundation, either version 2 of that License or (at your option) any
62887 + * later version.
62888 + *
62889 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62890 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62891 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62892 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62893 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62894 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62895 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62896 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62897 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62898 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62899 + */
62900 +
62901 +
62902 +/******************************************************************************
62903 + @File fm_rtc.h
62904 +
62905 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
62906 +
62907 + @Cautions None
62908 +*//***************************************************************************/
62909 +
62910 +#ifndef __FM_RTC_H__
62911 +#define __FM_RTC_H__
62912 +
62913 +#include "std_ext.h"
62914 +#include "fm_rtc_ext.h"
62915 +
62916 +
62917 +#define __ERR_MODULE__ MODULE_FM_RTC
62918 +
62919 +/* General definitions */
62920 +
62921 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
62922 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
62923 +#define DEFAULT_BYPASS FALSE
62924 +#define DEFAULT_CLOCK_PERIOD 1000
62925 +
62926 +
62927 +
62928 +typedef struct t_FmRtcAlarm
62929 +{
62930 + t_FmRtcExceptionsCallback *f_AlarmCallback;
62931 + bool clearOnExpiration;
62932 +} t_FmRtcAlarm;
62933 +
62934 +typedef struct t_FmRtcPeriodicPulse
62935 +{
62936 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
62937 +} t_FmRtcPeriodicPulse;
62938 +
62939 +typedef struct t_FmRtcExternalTrigger
62940 +{
62941 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
62942 +} t_FmRtcExternalTrigger;
62943 +
62944 +
62945 +/**************************************************************************//**
62946 + @Description RTC FM driver control structure.
62947 +*//***************************************************************************/
62948 +typedef struct t_FmRtc
62949 +{
62950 + t_Part *p_Part; /**< Pointer to the integration device */
62951 + t_Handle h_Fm;
62952 + t_Handle h_App; /**< Application handle */
62953 + struct rtc_regs *p_MemMap;
62954 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
62955 + uint32_t srcClkFreqMhz;
62956 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
62957 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
62958 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
62959 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
62960 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
62961 +} t_FmRtc;
62962 +
62963 +
62964 +#endif /* __FM_RTC_H__ */
62965 --- /dev/null
62966 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
62967 @@ -0,0 +1,334 @@
62968 +/*
62969 + * Copyright 2008-2013 Freescale Semiconductor Inc.
62970 + *
62971 + * Redistribution and use in source and binary forms, with or without
62972 + * modification, are permitted provided that the following conditions are met:
62973 + * * Redistributions of source code must retain the above copyright
62974 + * notice, this list of conditions and the following disclaimer.
62975 + * * Redistributions in binary form must reproduce the above copyright
62976 + * notice, this list of conditions and the following disclaimer in the
62977 + * documentation and/or other materials provided with the distribution.
62978 + * * Neither the name of Freescale Semiconductor nor the
62979 + * names of its contributors may be used to endorse or promote products
62980 + * derived from this software without specific prior written permission.
62981 + *
62982 + *
62983 + * ALTERNATIVELY, this software may be distributed under the terms of the
62984 + * GNU General Public License ("GPL") as published by the Free Software
62985 + * Foundation, either version 2 of that License or (at your option) any
62986 + * later version.
62987 + *
62988 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62989 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62990 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62991 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62992 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62993 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62994 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62995 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62996 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62997 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62998 + */
62999 +
63000 +#include "fsl_fman_rtc.h"
63001 +
63002 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
63003 +{
63004 + int i;
63005 + cfg->src_clk = DEFAULT_SRC_CLOCK;
63006 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
63007 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
63008 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
63009 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
63010 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
63011 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
63012 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
63013 +}
63014 +
63015 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
63016 +{
63017 + return ioread32be(&regs->tmr_tevent);
63018 +}
63019 +
63020 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
63021 +{
63022 + return ioread32be(&regs->tmr_tevent) & ev_mask;
63023 +}
63024 +
63025 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
63026 +{
63027 + return ioread32be(&regs->tmr_temask);
63028 +}
63029 +
63030 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
63031 +{
63032 + iowrite32be(mask, &regs->tmr_temask);
63033 +}
63034 +
63035 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
63036 +{
63037 + iowrite32be(events, &regs->tmr_tevent);
63038 +}
63039 +
63040 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
63041 +{
63042 + uint32_t event;
63043 +
63044 + event = ioread32be(&regs->tmr_tevent);
63045 + event &= ioread32be(&regs->tmr_temask);
63046 +
63047 + if (event)
63048 + iowrite32be(event, &regs->tmr_tevent);
63049 + return event;
63050 +}
63051 +
63052 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
63053 +{
63054 + return ioread32be(&regs->tmr_add);
63055 +}
63056 +
63057 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
63058 +{
63059 + iowrite32be(val, &regs->tmr_add);
63060 +}
63061 +
63062 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
63063 +{
63064 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
63065 +}
63066 +
63067 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
63068 +{
63069 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
63070 +}
63071 +
63072 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
63073 +{
63074 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
63075 +}
63076 +
63077 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
63078 +{
63079 + iowrite32be(val, &regs->tmr_fiper[index]);
63080 +}
63081 +
63082 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
63083 +{
63084 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
63085 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
63086 +}
63087 +
63088 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
63089 +{
63090 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
63091 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
63092 +}
63093 +
63094 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
63095 +{
63096 + uint64_t time;
63097 + /* TMR_CNT_L must be read first to get an accurate value */
63098 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
63099 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
63100 + << 32);
63101 +
63102 + return time;
63103 +}
63104 +
63105 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
63106 +{
63107 + return ioread32be(&regs->tmr_ctrl);
63108 +}
63109 +
63110 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
63111 +{
63112 + iowrite32be(val, &regs->tmr_ctrl);
63113 +}
63114 +
63115 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
63116 +{
63117 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
63118 + udelay(10);
63119 + fman_rtc_set_timer_ctrl(regs, 0);
63120 +}
63121 +
63122 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
63123 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
63124 + uint32_t freq_compensation, uint32_t output_clock_divisor)
63125 +{
63126 + uint32_t tmr_ctrl;
63127 + int i;
63128 +
63129 + fman_rtc_timers_soft_reset(regs);
63130 +
63131 + /* Set the source clock */
63132 + switch (cfg->src_clk) {
63133 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
63134 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
63135 + break;
63136 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
63137 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
63138 + break;
63139 + default:
63140 + /* Use a clock from the External TMR reference clock.*/
63141 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
63142 + break;
63143 + }
63144 +
63145 + /* whatever period the user picked, the timestamp will advance in '1'
63146 + * every time the period passed. */
63147 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
63148 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
63149 +
63150 + if (cfg->invert_input_clk_phase)
63151 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
63152 + if (cfg->invert_output_clk_phase)
63153 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
63154 +
63155 + for (i = 0; i < num_alarms; i++) {
63156 + if (cfg->alarm_polarity[i] ==
63157 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
63158 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
63159 + }
63160 +
63161 + for (i = 0; i < num_ext_triggers; i++)
63162 + if (cfg->trigger_polarity[i] ==
63163 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
63164 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
63165 +
63166 + if (!cfg->timer_slave_mode && cfg->bypass)
63167 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
63168 +
63169 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
63170 + if (init_freq_comp)
63171 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
63172 +
63173 + /* Clear TMR_ALARM registers */
63174 + for (i = 0; i < num_alarms; i++)
63175 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
63176 +
63177 + /* Clear TMR_TEVENT */
63178 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
63179 +
63180 + /* Initialize TMR_TEMASK */
63181 + fman_rtc_set_interrupt_mask(regs, 0);
63182 +
63183 + /* Clear TMR_FIPER registers */
63184 + for (i = 0; i < num_fipers; i++)
63185 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
63186 +
63187 + /* Initialize TMR_PRSC */
63188 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
63189 +
63190 + /* Clear TMR_OFF */
63191 + fman_rtc_set_timer_offset(regs, 0);
63192 +}
63193 +
63194 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
63195 +{
63196 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
63197 +}
63198 +
63199 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
63200 +{
63201 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
63202 +
63203 + /* TODO check that no timestamping MACs are working in this stage. */
63204 + if (reset_clock) {
63205 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
63206 +
63207 + udelay(10);
63208 + /* Clear TMR_OFF */
63209 + fman_rtc_set_timer_offset(regs, 0);
63210 + }
63211 +
63212 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
63213 +}
63214 +
63215 +void fman_rtc_disable(struct rtc_regs *regs)
63216 +{
63217 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
63218 + & ~(FMAN_RTC_TMR_CTRL_TE)));
63219 +}
63220 +
63221 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
63222 +{
63223 + uint32_t tmp_reg;
63224 + if (id == 0)
63225 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
63226 + else
63227 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
63228 + fman_rtc_disable_interupt(regs, tmp_reg);
63229 +
63230 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
63231 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
63232 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
63233 +
63234 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
63235 +}
63236 +
63237 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
63238 +{
63239 + uint32_t tmpReg, tmp_ctrl;
63240 +
63241 + if (id == 0)
63242 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63243 + else
63244 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63245 + fman_rtc_disable_interupt(regs, tmpReg);
63246 +
63247 + if (id == 0)
63248 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63249 + else
63250 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63251 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
63252 + if (tmp_ctrl & tmpReg)
63253 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
63254 +}
63255 +
63256 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
63257 +{
63258 + uint32_t tmpReg;
63259 + fman_rtc_set_timer_alarm(regs, id, val);
63260 + if (enable) {
63261 + if (id == 0)
63262 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
63263 + else
63264 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
63265 + fman_rtc_enable_interupt(regs, tmpReg);
63266 + }
63267 +}
63268 +
63269 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
63270 + bool enable)
63271 +{
63272 + uint32_t tmpReg;
63273 + fman_rtc_set_timer_fiper(regs, id, val);
63274 + if (enable) {
63275 + if (id == 0)
63276 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
63277 + else
63278 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
63279 + fman_rtc_enable_interupt(regs, tmpReg);
63280 + }
63281 +}
63282 +
63283 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
63284 + bool use_pulse_as_input)
63285 +{
63286 + uint32_t tmpReg;
63287 + if (enable) {
63288 + if (id == 0)
63289 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
63290 + else
63291 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
63292 + fman_rtc_enable_interupt(regs, tmpReg);
63293 + }
63294 + if (use_pulse_as_input) {
63295 + if (id == 0)
63296 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
63297 + else
63298 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
63299 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
63300 + }
63301 +}
63302 --- /dev/null
63303 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
63304 @@ -0,0 +1,15 @@
63305 +#
63306 +# Makefile for the Freescale Ethernet controllers
63307 +#
63308 +ccflags-y += -DVERSION=\"\"
63309 +#
63310 +#Include netcomm SW specific definitions
63311 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63312 +
63313 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63314 +
63315 +ccflags-y += -I$(NCSW_FM_INC)
63316 +
63317 +obj-y += fsl-ncsw-sp.o
63318 +
63319 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
63320 --- /dev/null
63321 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
63322 @@ -0,0 +1,757 @@
63323 +/*
63324 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63325 + *
63326 + * Redistribution and use in source and binary forms, with or without
63327 + * modification, are permitted provided that the following conditions are met:
63328 + * * Redistributions of source code must retain the above copyright
63329 + * notice, this list of conditions and the following disclaimer.
63330 + * * Redistributions in binary form must reproduce the above copyright
63331 + * notice, this list of conditions and the following disclaimer in the
63332 + * documentation and/or other materials provided with the distribution.
63333 + * * Neither the name of Freescale Semiconductor nor the
63334 + * names of its contributors may be used to endorse or promote products
63335 + * derived from this software without specific prior written permission.
63336 + *
63337 + *
63338 + * ALTERNATIVELY, this software may be distributed under the terms of the
63339 + * GNU General Public License ("GPL") as published by the Free Software
63340 + * Foundation, either version 2 of that License or (at your option) any
63341 + * later version.
63342 + *
63343 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63344 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63345 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63346 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63347 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63348 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63349 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63350 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63351 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63352 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63353 + */
63354 +
63355 +
63356 +/******************************************************************************
63357 + @File fm_sp.c
63358 +
63359 + @Description FM PCD Storage profile ...
63360 +*//***************************************************************************/
63361 +
63362 +#include "std_ext.h"
63363 +#include "error_ext.h"
63364 +#include "string_ext.h"
63365 +#include "debug_ext.h"
63366 +#include "net_ext.h"
63367 +
63368 +#include "fm_vsp_ext.h"
63369 +#include "fm_sp.h"
63370 +#include "fm_common.h"
63371 +#include "fsl_fman_sp.h"
63372 +
63373 +
63374 +#if (DPAA_VERSION >= 11)
63375 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
63376 +{
63377 + t_Error err = E_OK;
63378 +
63379 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
63380 + RETURN_ERROR(MAJOR, err, NO_MSG);
63381 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
63382 + RETURN_ERROR(MAJOR, err, NO_MSG);
63383 + return err;
63384 +
63385 +}
63386 +
63387 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
63388 +{
63389 + t_Error err = E_OK;
63390 +
63391 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63392 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63393 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
63394 +
63395 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
63396 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
63397 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
63398 +
63399 + RETURN_ERROR(MAJOR, err, NO_MSG);
63400 +
63401 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
63402 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
63403 +
63404 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
63405 + p_FmVspEntry->portType,
63406 + p_FmVspEntry->portId,
63407 + p_FmVspEntry->relativeProfileId);
63408 +
63409 + return err;
63410 +}
63411 +#endif /* (DPAA_VERSION >= 11) */
63412 +
63413 +
63414 +/*****************************************************************************/
63415 +/* Inter-module API routines */
63416 +/*****************************************************************************/
63417 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
63418 + uint8_t *orderedArray,
63419 + uint16_t *sizesArray)
63420 +{
63421 + uint16_t bufSize = 0;
63422 + int i=0, j=0, k=0;
63423 +
63424 + /* First we copy the external buffers pools information to an ordered local array */
63425 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63426 + {
63427 + /* get pool size */
63428 + bufSize = p_FmExtPools->extBufPool[i].size;
63429 +
63430 + /* keep sizes in an array according to poolId for direct access */
63431 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
63432 +
63433 + /* save poolId in an ordered array according to size */
63434 + for (j=0;j<=i;j++)
63435 + {
63436 + /* this is the next free place in the array */
63437 + if (j==i)
63438 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
63439 + else
63440 + {
63441 + /* find the right place for this poolId */
63442 + if (bufSize < sizesArray[orderedArray[j]])
63443 + {
63444 + /* move the poolIds one place ahead to make room for this poolId */
63445 + for (k=i;k>j;k--)
63446 + orderedArray[k] = orderedArray[k-1];
63447 +
63448 + /* now k==j, this is the place for the new size */
63449 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
63450 + break;
63451 + }
63452 + }
63453 + }
63454 + }
63455 +}
63456 +
63457 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
63458 + t_FmBackupBmPools *p_FmBackupBmPools,
63459 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
63460 +{
63461 +
63462 + int i = 0, j = 0;
63463 + bool found;
63464 + uint8_t count = 0;
63465 +
63466 + if (p_FmExtPools)
63467 + {
63468 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
63469 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63470 +
63471 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
63472 + {
63473 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
63474 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
63475 + if (!p_FmExtPools->extBufPool[i].size)
63476 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
63477 + }
63478 + }
63479 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
63480 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
63481 +
63482 + /* backup BM pools indication is valid only for some chip derivatives
63483 + (limited by the config routine) */
63484 + if (p_FmBackupBmPools)
63485 + {
63486 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
63487 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
63488 + found = FALSE;
63489 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
63490 + {
63491 +
63492 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63493 + {
63494 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
63495 + {
63496 + found = TRUE;
63497 + break;
63498 + }
63499 + }
63500 + if (!found)
63501 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
63502 + else
63503 + found = FALSE;
63504 + }
63505 + }
63506 +
63507 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
63508 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
63509 + {
63510 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
63511 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools can't be larger than %d and can't be larger than numOfPoolsUsed", FM_PORT_MAX_NUM_OF_EXT_POOLS));
63512 +
63513 + if (!p_FmBufPoolDepletion->numOfPools)
63514 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
63515 +
63516 + found = FALSE;
63517 + count = 0;
63518 + /* for each pool that is in poolsToConsider, check if it is defined
63519 + in extBufPool */
63520 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63521 + {
63522 + if (p_FmBufPoolDepletion->poolsToConsider[i])
63523 + {
63524 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63525 + {
63526 + if (i == p_FmExtPools->extBufPool[j].id)
63527 + {
63528 + found = TRUE;
63529 + count++;
63530 + break;
63531 + }
63532 + }
63533 + if (!found)
63534 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63535 + else
63536 + found = FALSE;
63537 + }
63538 + }
63539 + /* check that the number of pools that we have checked is equal to the number announced by the user */
63540 + if (count != p_FmBufPoolDepletion->numOfPools)
63541 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
63542 + }
63543 +
63544 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
63545 + {
63546 + /* calculate vector for number of pools depletion */
63547 + found = FALSE;
63548 + count = 0;
63549 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
63550 + {
63551 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
63552 + {
63553 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
63554 + {
63555 + if (i == p_FmExtPools->extBufPool[j].id)
63556 + {
63557 + found = TRUE;
63558 + count++;
63559 + break;
63560 + }
63561 + }
63562 + if (!found)
63563 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
63564 + else
63565 + found = FALSE;
63566 + }
63567 + }
63568 + if (!count)
63569 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
63570 + }
63571 +
63572 + return E_OK;
63573 +}
63574 +
63575 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
63576 +{
63577 + /* Check that divisible by 16 and not larger than 240 */
63578 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
63579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
63580 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
63581 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
63582 +
63583 + /* check that ic size+ic internal offset, does not exceed ic block size */
63584 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
63585 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
63586 + /* Check that divisible by 16 and not larger than 256 */
63587 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
63588 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
63589 +
63590 + /* Check that divisible by 16 and not larger than 4K */
63591 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
63592 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
63593 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
63594 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
63595 +
63596 + return E_OK;
63597 +}
63598 +
63599 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
63600 +{
63601 + /* Check the margin definition */
63602 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
63603 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63604 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
63605 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
63606 +
63607 + return E_OK;
63608 +}
63609 +
63610 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
63611 + t_FmBufferPrefixContent *p_BufferPrefixContent,
63612 + t_FmSpBufMargins *p_FmSpBufMargins,
63613 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
63614 + uint8_t *internalBufferOffset)
63615 +{
63616 + uint32_t tmp;
63617 +
63618 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
63619 + ASSERT_COND(p_FmSpIntContextDataCopy);
63620 + ASSERT_COND(p_BufferPrefixContent);
63621 + ASSERT_COND(p_FmSpBufMargins);
63622 + ASSERT_COND(p_FmSpBufferOffsets);
63623 +
63624 + /* Align start of internal context data to 16 byte */
63625 + p_FmSpIntContextDataCopy->extBufOffset =
63626 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
63627 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
63628 + p_BufferPrefixContent->privDataSize);
63629 +
63630 + /* Translate margin and intContext params to FM parameters */
63631 + /* Initialize with illegal value. Later we'll set legal values. */
63632 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
63633 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
63634 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
63635 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
63636 +
63637 + /* Internally the driver supports 4 options
63638 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
63639 + relate to it as 1).
63640 + 2. All IC context (from AD) not including debug.*/
63641 +
63642 + /* This 'if' covers option 2. We copy from beginning of context. */
63643 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63644 + {
63645 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
63646 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
63647 + p_FmSpIntContextDataCopy->intContextOffset = 16;
63648 +
63649 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
63650 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
63651 + if (p_BufferPrefixContent->passPrsResult)
63652 + p_FmSpBufferOffsets->prsResultOffset =
63653 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
63654 + if (p_BufferPrefixContent->passTimeStamp)
63655 + p_FmSpBufferOffsets->timeStampOffset =
63656 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
63657 + if (p_BufferPrefixContent->passHashResult)
63658 + p_FmSpBufferOffsets->hashResultOffset =
63659 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
63660 + }
63661 + else
63662 + {
63663 + /* This case covers the options under 1 */
63664 + /* Copy size must be in 16-byte granularity. */
63665 + p_FmSpIntContextDataCopy->size =
63666 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
63667 + ((p_BufferPrefixContent->passTimeStamp ||
63668 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
63669 +
63670 + /* Align start of internal context data to 16 byte */
63671 + p_FmSpIntContextDataCopy->intContextOffset =
63672 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
63673 + ((p_BufferPrefixContent->passTimeStamp ||
63674 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
63675 +
63676 + if (p_BufferPrefixContent->passPrsResult)
63677 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
63678 + if (p_BufferPrefixContent->passTimeStamp)
63679 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
63680 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
63681 + p_FmSpIntContextDataCopy->extBufOffset;
63682 + if (p_BufferPrefixContent->passHashResult)
63683 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
63684 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
63685 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
63686 + p_FmSpIntContextDataCopy->extBufOffset + 8;
63687 + }
63688 +
63689 + if (p_FmSpIntContextDataCopy->size)
63690 + p_FmSpBufMargins->startMargins =
63691 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
63692 + p_FmSpIntContextDataCopy->size);
63693 + else
63694 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
63695 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
63696 +
63697 + /* save extra space for manip in both external and internal buffers */
63698 + if (p_BufferPrefixContent->manipExtraSpace)
63699 + {
63700 + uint8_t extraSpace;
63701 +#ifdef FM_CAPWAP_SUPPORT
63702 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
63703 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63704 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
63705 + 256-CAPWAP_FRAG_EXTRA_SPACE));
63706 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
63707 +#else
63708 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
63709 +#endif /* FM_CAPWAP_SUPPORT */
63710 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
63711 + p_FmSpBufMargins->startMargins += extraSpace;
63712 + *internalBufferOffset = extraSpace;
63713 + }
63714 +
63715 + /* align data start */
63716 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
63717 + if (tmp)
63718 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
63719 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
63720 +
63721 + return E_OK;
63722 +}
63723 +/*********************** End of inter-module routines ************************/
63724 +
63725 +
63726 +#if (DPAA_VERSION >= 11)
63727 +/*****************************************************************************/
63728 +/* API routines */
63729 +/*****************************************************************************/
63730 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
63731 +{
63732 + t_FmVspEntry *p_FmVspEntry = NULL;
63733 + struct fm_storage_profile_params fm_vsp_params;
63734 +
63735 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
63736 + if (!p_FmVspEntry)
63737 + {
63738 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63739 + return NULL;
63740 + }
63741 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
63742 +
63743 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
63744 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
63745 + {
63746 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
63747 + XX_Free(p_FmVspEntry);
63748 + return NULL;
63749 + }
63750 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
63751 + fman_vsp_defconfig(&fm_vsp_params);
63752 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
63753 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
63754 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
63755 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
63756 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
63757 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
63758 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
63759 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
63760 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63761 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
63762 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
63763 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63764 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
63765 +
63766 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
63767 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
63768 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
63769 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
63770 +
63771 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
63772 +
63773 + return p_FmVspEntry;
63774 +}
63775 +
63776 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
63777 +{
63778 +
63779 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63780 + struct fm_storage_profile_params fm_vsp_params;
63781 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
63782 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
63783 + t_Error err;
63784 + uint16_t absoluteProfileId = 0;
63785 + int i = 0;
63786 +
63787 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63788 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
63789 +
63790 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
63791 +
63792 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
63793 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
63794 +
63795 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
63796 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
63797 + &p_FmVspEntry->bufMargins,
63798 + &p_FmVspEntry->bufferOffsets,
63799 + &p_FmVspEntry->internalBufferOffset);
63800 + if (err != E_OK)
63801 + RETURN_ERROR(MAJOR, err, NO_MSG);
63802 +
63803 +
63804 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
63805 + if (err != E_OK)
63806 + RETURN_ERROR(MAJOR, err, NO_MSG);
63807 +
63808 +
63809 + p_FmVspEntry->p_FmSpRegsBase =
63810 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
63811 + if (!p_FmVspEntry->p_FmSpRegsBase)
63812 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
63813 +
63814 + /* order external buffer pools in ascending order of buffer pools sizes */
63815 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
63816 + orderedArray,
63817 + sizesArray);
63818 +
63819 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
63820 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
63821 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
63822 + {
63823 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
63824 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
63825 + }
63826 +
63827 + /* on user responsibility to fill it according requirement */
63828 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
63829 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
63830 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
63831 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
63832 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
63833 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
63834 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
63835 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
63836 +
63837 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63838 + {
63839 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
63840 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
63841 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
63842 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
63843 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
63844 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
63845 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
63846 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
63847 + }
63848 + else
63849 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
63850 +
63851 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
63852 + {
63853 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
63854 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
63855 + }
63856 + else
63857 + fm_vsp_params.backup_pools.num_backup_pools = 0;
63858 +
63859 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
63860 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
63861 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
63862 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
63863 +
63864 + /* no check on err - it was checked earlier */
63865 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
63866 + p_FmVspEntry->portType,
63867 + p_FmVspEntry->portId,
63868 + p_FmVspEntry->relativeProfileId,
63869 + &absoluteProfileId);
63870 +
63871 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
63872 + ASSERT_COND(fm_vsp_params.int_context);
63873 + ASSERT_COND(fm_vsp_params.buf_margins);
63874 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
63875 +
63876 + /* Set all registers related to VSP */
63877 + fman_vsp_init(p_FmVspEntry->p_FmSpRegsBase, absoluteProfileId, &fm_vsp_params,FM_PORT_MAX_NUM_OF_EXT_POOLS, BM_MAX_NUM_OF_POOLS, FM_MAX_NUM_OF_PFC_PRIORITIES);
63878 +
63879 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
63880 +
63881 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
63882 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
63883 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
63884 +
63885 + return E_OK;
63886 +}
63887 +
63888 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
63889 +{
63890 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
63891 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63892 + XX_Free(p_FmVspEntry);
63893 + return E_OK;
63894 +}
63895 +
63896 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
63897 +{
63898 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63899 +
63900 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63901 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63902 +
63903 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
63904 + /* if dataAlign was not initialized by user, we return to driver's default */
63905 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
63906 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
63907 +
63908 + return E_OK;
63909 +}
63910 +
63911 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
63912 +{
63913 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63914 +
63915 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63916 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63917 +
63918 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
63919 +
63920 + return E_OK;
63921 +}
63922 +
63923 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
63924 +{
63925 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63926 +
63927 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63928 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63929 +
63930 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
63931 +
63932 + return E_OK;
63933 +}
63934 +
63935 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
63936 +{
63937 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63938 +
63939 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63940 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63941 +
63942 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
63943 +
63944 + return E_OK;
63945 +}
63946 +
63947 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
63948 +{
63949 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63950 +
63951 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63952 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63953 +
63954 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
63955 +
63956 + return E_OK;
63957 +}
63958 +
63959 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
63960 +{
63961 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63962 +
63963 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63964 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63965 +
63966 +
63967 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
63968 +
63969 + return E_OK;
63970 +}
63971 +
63972 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
63973 +{
63974 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63975 +
63976 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
63977 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63978 +
63979 +
63980 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
63981 +
63982 + return E_OK;
63983 +}
63984 +
63985 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
63986 +{
63987 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
63988 +
63989 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
63990 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
63991 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
63992 +
63993 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
63994 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
63995 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
63996 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
63997 +
63998 + return E_OK;
63999 +}
64000 +
64001 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
64002 +{
64003 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64004 +
64005 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
64006 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
64007 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
64008 +
64009 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
64010 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
64011 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
64012 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
64013 +
64014 + return E_OK;
64015 +}
64016 +
64017 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
64018 +{
64019 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64020 +
64021 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
64022 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
64023 +
64024 + return p_FmVspEntry->bufferOffsets.dataOffset;
64025 +}
64026 +
64027 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
64028 +{
64029 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64030 +
64031 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64032 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64033 +
64034 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
64035 + return NULL;
64036 +
64037 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
64038 +}
64039 +
64040 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
64041 +{
64042 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64043 +
64044 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64045 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64046 +
64047 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
64048 + return NULL;
64049 +
64050 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
64051 +}
64052 +
64053 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
64054 +{
64055 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64056 +
64057 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64058 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64059 +
64060 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
64061 + return NULL;
64062 +
64063 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
64064 +}
64065 +
64066 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
64067 +{
64068 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
64069 +
64070 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
64071 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
64072 +
64073 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
64074 + return NULL;
64075 +
64076 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
64077 +}
64078 +
64079 +#endif /* (DPAA_VERSION >= 11) */
64080 --- /dev/null
64081 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
64082 @@ -0,0 +1,85 @@
64083 +/*
64084 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64085 + *
64086 + * Redistribution and use in source and binary forms, with or without
64087 + * modification, are permitted provided that the following conditions are met:
64088 + * * Redistributions of source code must retain the above copyright
64089 + * notice, this list of conditions and the following disclaimer.
64090 + * * Redistributions in binary form must reproduce the above copyright
64091 + * notice, this list of conditions and the following disclaimer in the
64092 + * documentation and/or other materials provided with the distribution.
64093 + * * Neither the name of Freescale Semiconductor nor the
64094 + * names of its contributors may be used to endorse or promote products
64095 + * derived from this software without specific prior written permission.
64096 + *
64097 + *
64098 + * ALTERNATIVELY, this software may be distributed under the terms of the
64099 + * GNU General Public License ("GPL") as published by the Free Software
64100 + * Foundation, either version 2 of that License or (at your option) any
64101 + * later version.
64102 + *
64103 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64104 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64105 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64106 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64107 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64108 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64109 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64110 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64111 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64112 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64113 + */
64114 +
64115 +
64116 +/******************************************************************************
64117 + @File fm_sp.h
64118 +
64119 + @Description FM SP ...
64120 +*//***************************************************************************/
64121 +#ifndef __FM_SP_H
64122 +#define __FM_SP_H
64123 +
64124 +#include "std_ext.h"
64125 +#include "error_ext.h"
64126 +#include "list_ext.h"
64127 +
64128 +#include "fm_sp_common.h"
64129 +#include "fm_common.h"
64130 +
64131 +
64132 +#define __ERR_MODULE__ MODULE_FM_SP
64133 +
64134 +typedef struct {
64135 + t_FmBufferPrefixContent bufferPrefixContent;
64136 + e_FmDmaSwapOption dmaSwapData;
64137 + e_FmDmaCacheOption dmaIntContextCacheAttr;
64138 + e_FmDmaCacheOption dmaHeaderCacheAttr;
64139 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
64140 + bool dmaWriteOptimize;
64141 + uint16_t liodnOffset;
64142 + bool noScatherGather;
64143 + t_FmBufPoolDepletion *p_BufPoolDepletion;
64144 + t_FmBackupBmPools *p_BackupBmPools;
64145 + t_FmExtPools extBufPools;
64146 +} t_FmVspEntryDriverParams;
64147 +
64148 +typedef struct {
64149 + bool valid;
64150 + volatile bool lock;
64151 + uint8_t pointedOwners;
64152 + uint16_t absoluteSpId;
64153 + uint8_t internalBufferOffset;
64154 + t_FmSpBufMargins bufMargins;
64155 + t_FmSpIntContextDataCopy intContext;
64156 + t_FmSpBufferOffsets bufferOffsets;
64157 + t_Handle h_Fm;
64158 + e_FmPortType portType; /**< Port type */
64159 + uint8_t portId; /**< Port Id - relative to type */
64160 + uint8_t relativeProfileId;
64161 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
64162 + t_FmExtPools extBufPools;
64163 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
64164 +} t_FmVspEntry;
64165 +
64166 +
64167 +#endif /* __FM_SP_H */
64168 --- /dev/null
64169 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
64170 @@ -0,0 +1,197 @@
64171 +/*
64172 + * Copyright 2013 Freescale Semiconductor Inc.
64173 + *
64174 + * Redistribution and use in source and binary forms, with or without
64175 + * modification, are permitted provided that the following conditions are met:
64176 + * * Redistributions of source code must retain the above copyright
64177 + * notice, this list of conditions and the following disclaimer.
64178 + * * Redistributions in binary form must reproduce the above copyright
64179 + * notice, this list of conditions and the following disclaimer in the
64180 + * documentation and/or other materials provided with the distribution.
64181 + * * Neither the name of Freescale Semiconductor nor the
64182 + * names of its contributors may be used to endorse or promote products
64183 + * derived from this software without specific prior written permission.
64184 + *
64185 + *
64186 + * ALTERNATIVELY, this software may be distributed under the terms of the
64187 + * GNU General Public License ("GPL") as published by the Free Software
64188 + * Foundation, either version 2 of that License or (at your option) any
64189 + * later version.
64190 + *
64191 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64192 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64193 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64194 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64195 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64196 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64197 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64198 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64199 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64200 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64201 + */
64202 +
64203 +#include "fsl_fman_sp.h"
64204 +
64205 +
64206 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
64207 + uint16_t index)
64208 +{
64209 + struct fm_pcd_storage_profile_regs *sp_regs;
64210 + sp_regs = &regs[index];
64211 + return ioread32be(&sp_regs->fm_sp_acnt);
64212 +}
64213 +
64214 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
64215 + uint16_t index, uint32_t value)
64216 +{
64217 + struct fm_pcd_storage_profile_regs *sp_regs;
64218 + sp_regs = &regs[index];
64219 + iowrite32be(value, &sp_regs->fm_sp_acnt);
64220 +}
64221 +
64222 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
64223 +{
64224 + cfg->dma_swap_data =
64225 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
64226 + cfg->int_context_cache_attr =
64227 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
64228 + cfg->header_cache_attr =
64229 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
64230 + cfg->scatter_gather_cache_attr =
64231 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
64232 + cfg->dma_write_optimize =
64233 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
64234 + cfg->no_scather_gather =
64235 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
64236 +}
64237 +
64238 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
64239 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
64240 +{
64241 + int i, j;
64242 + uint32_t vector = 0;
64243 + for (i = 0; i < max_pools; i++)
64244 + if (pools[i])
64245 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
64246 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
64247 + vector |= mask >> j;
64248 + break;
64249 + }
64250 + return vector;
64251 +}
64252 +
64253 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
64254 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
64255 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
64256 + int max_num_of_pfc_priorities)
64257 +{
64258 + int i = 0, j = 0;
64259 + struct fm_pcd_storage_profile_regs *sp_regs;
64260 + uint32_t tmp_reg, vector;
64261 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
64262 + struct fman_buf_pool_depletion *buf_pool_depletion =
64263 + &fm_vsp_params->buf_pool_depletion;
64264 + struct fman_backup_bm_pools *backup_pools =
64265 + &fm_vsp_params->backup_pools;
64266 + struct fman_sp_int_context_data_copy *int_context_data_copy =
64267 + fm_vsp_params->int_context;
64268 + struct fman_sp_buf_margins *external_buffer_margins =
64269 + fm_vsp_params->buf_margins;
64270 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
64271 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
64272 +
64273 + sp_regs = &regs[index];
64274 +
64275 + /* fill external buffers manager pool information register*/
64276 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
64277 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
64278 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
64279 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
64280 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
64281 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
64282 + /* functionality available only for some deriviatives
64283 + (limited by config) */
64284 + for (j = 0; j < backup_pools->num_backup_pools; j++)
64285 + if (ext_buf_pools->ext_buf_pool[i].id ==
64286 + backup_pools->pool_ids[j]) {
64287 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
64288 + break;
64289 + }
64290 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
64291 + }
64292 +
64293 + /* clear unused pools */
64294 + for (i = ext_buf_pools->num_pools_used;
64295 + i < port_max_num_of_ext_pools; i++)
64296 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
64297 +
64298 + /* fill pool depletion register*/
64299 + tmp_reg = 0;
64300 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
64301 + /* calculate vector for number of pools depletion */
64302 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64303 + pools_to_consider, ext_buf_pools, 0x80000000);
64304 +
64305 + /* configure num of pools and vector for number of pools mode */
64306 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
64307 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
64308 + tmp_reg |= vector;
64309 + }
64310 +
64311 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
64312 + /* calculate vector for number of pools depletion */
64313 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
64314 + pools_to_consider_for_single_mode,
64315 + ext_buf_pools, 0x00000080);
64316 +
64317 + /* configure num of pools and vector for number of pools mode */
64318 + tmp_reg |= vector;
64319 + }
64320 +
64321 + /* fill QbbPEV */
64322 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
64323 + vector = 0;
64324 + for (i = 0; i < max_num_of_pfc_priorities; i++)
64325 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
64326 + vector |= 0x00000100 << i;
64327 + tmp_reg |= vector;
64328 + }
64329 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
64330 +
64331 + /* fill dma attributes register */
64332 + tmp_reg = 0;
64333 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
64334 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
64335 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
64336 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
64337 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
64338 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
64339 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
64340 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
64341 + if (fm_vsp_params->dma_write_optimize)
64342 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
64343 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
64344 +
64345 + /* IC parameters - fill internal context parameters register */
64346 + tmp_reg = 0;
64347 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
64348 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
64349 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
64350 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
64351 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
64352 + FMAN_SP_IC_SIZE_SHIFT);
64353 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
64354 +
64355 + /* buffer margins - fill external buffer margins register */
64356 + tmp_reg = 0;
64357 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
64358 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
64359 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
64360 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
64361 + if (no_scather_gather)
64362 + tmp_reg |= FMAN_SP_SG_DISABLE;
64363 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
64364 +
64365 + /* buffer margins - fill spliodn register */
64366 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
64367 +}
64368 --- /dev/null
64369 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
64370 @@ -0,0 +1,5216 @@
64371 +/*
64372 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64373 + *
64374 + * Redistribution and use in source and binary forms, with or without
64375 + * modification, are permitted provided that the following conditions are met:
64376 + * * Redistributions of source code must retain the above copyright
64377 + * notice, this list of conditions and the following disclaimer.
64378 + * * Redistributions in binary form must reproduce the above copyright
64379 + * notice, this list of conditions and the following disclaimer in the
64380 + * documentation and/or other materials provided with the distribution.
64381 + * * Neither the name of Freescale Semiconductor nor the
64382 + * names of its contributors may be used to endorse or promote products
64383 + * derived from this software without specific prior written permission.
64384 + *
64385 + *
64386 + * ALTERNATIVELY, this software may be distributed under the terms of the
64387 + * GNU General Public License ("GPL") as published by the Free Software
64388 + * Foundation, either version 2 of that License or (at your option) any
64389 + * later version.
64390 + *
64391 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64392 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64393 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64394 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64395 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64396 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64397 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64398 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64399 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64400 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64401 + */
64402 +
64403 +
64404 +/******************************************************************************
64405 + @File fm.c
64406 +
64407 + @Description FM driver routines implementation.
64408 +*//***************************************************************************/
64409 +#include "std_ext.h"
64410 +#include "error_ext.h"
64411 +#include "xx_ext.h"
64412 +#include "string_ext.h"
64413 +#include "sprint_ext.h"
64414 +#include "debug_ext.h"
64415 +#include "fm_muram_ext.h"
64416 +#include <linux/math64.h>
64417 +
64418 +#include "fm_common.h"
64419 +#include "fm_ipc.h"
64420 +#include "fm.h"
64421 +#ifndef CONFIG_FMAN_ARM
64422 +#include <linux/fsl/svr.h>
64423 +#endif
64424 +#include "fsl_fman.h"
64425 +
64426 +
64427 +/****************************************/
64428 +/* static functions */
64429 +/****************************************/
64430 +
64431 +static volatile bool blockingFlag = FALSE;
64432 +static void IpcMsgCompletionCB(t_Handle h_Fm,
64433 + uint8_t *p_Msg,
64434 + uint8_t *p_Reply,
64435 + uint32_t replyLength,
64436 + t_Error status)
64437 +{
64438 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
64439 + blockingFlag = FALSE;
64440 +}
64441 +
64442 +static void FreeInitResources(t_Fm *p_Fm)
64443 +{
64444 + if (p_Fm->camBaseAddr)
64445 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
64446 + if (p_Fm->fifoBaseAddr)
64447 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
64448 + if (p_Fm->resAddr)
64449 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
64450 +}
64451 +
64452 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
64453 +{
64454 + t_FMIramRegs *p_Iram;
64455 +
64456 + ASSERT_COND(p_Fm);
64457 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64458 +
64459 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
64460 +}
64461 +
64462 +static t_Error CheckFmParameters(t_Fm *p_Fm)
64463 +{
64464 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
64465 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
64466 +#if (DPAA_VERSION < 11)
64467 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
64468 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
64469 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64470 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
64471 +#endif /* (DPAA_VERSION < 11) */
64472 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
64473 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
64474 +// if (!p_Fm->p_FmDriverParam->dma_cam_num_of_entries || (p_Fm->p_FmDriverParam->dma_cam_num_of_entries > DMA_MODE_MAX_CAM_NUM_OF_ENTRIES))
64475 +// RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be in the range 1 - %d", DMA_MODE_MAX_CAM_NUM_OF_ENTRIES));
64476 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
64477 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64478 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
64479 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
64480 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
64481 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
64482 +#if (DPAA_VERSION < 11)
64483 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64484 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64485 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64486 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64487 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
64488 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
64489 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
64490 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64491 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
64492 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
64493 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
64494 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
64495 +#else /* (DPAA_VERSION >= 11) */
64496 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
64497 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
64498 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
64499 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
64500 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
64501 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
64502 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
64503 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
64504 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
64505 +#ifdef FM_AID_MODE_NO_TNUM_SW005
64506 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
64507 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
64508 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
64509 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
64510 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
64511 +#endif /* (DPAA_VERSION < 11) */
64512 +
64513 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
64514 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
64515 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
64516 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64517 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
64518 +
64519 +#if (DPAA_VERSION >= 11)
64520 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
64521 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
64522 +#endif /* (DPAA_VERSION >= 11) */
64523 +
64524 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
64525 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
64526 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
64527 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
64528 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
64529 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
64530 + p_Fm->p_FmStateStruct->totalFifoSize,
64531 + BMI_MAX_FIFO_SIZE));
64532 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
64533 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
64534 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
64535 +
64536 +#ifdef FM_HAS_TOTAL_DMAS
64537 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
64538 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
64539 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
64540 +#endif /* FM_HAS_TOTAL_DMAS */
64541 +
64542 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
64543 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
64544 +
64545 + if (!p_Fm->f_Exception)
64546 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64547 + if (!p_Fm->f_BusError)
64548 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
64549 +
64550 +#ifdef FM_NO_WATCHDOG
64551 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
64552 + (p_Fm->p_FmDriverParam->dma_watchdog))
64553 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
64554 +#endif /* FM_NO_WATCHDOG */
64555 +
64556 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
64557 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
64558 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
64559 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
64560 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
64561 +
64562 +#ifdef FM_NO_TNUM_AGING
64563 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64564 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64565 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
64566 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
64567 +#endif /* FM_NO_TNUM_AGING */
64568 +
64569 + /* check that user did not set revision-dependent exceptions */
64570 +#ifdef FM_NO_DISPATCH_RAM_ECC
64571 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
64572 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
64573 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
64574 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
64575 +#endif /* FM_NO_DISPATCH_RAM_ECC */
64576 +
64577 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
64578 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
64579 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
64580 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
64581 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
64582 +
64583 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
64584 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
64585 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
64586 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
64587 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
64588 +
64589 + return E_OK;
64590 +}
64591 +
64592 +
64593 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
64594 +{
64595 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
64596 +
64597 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
64598 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
64599 +
64600 + /* If the MAC is running on guest-partition and we have IPC session with it,
64601 + we inform him about the event through IPC; otherwise, we ignore the event. */
64602 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
64603 + {
64604 + t_Error err;
64605 + t_FmIpcIsr fmIpcIsr;
64606 + t_FmIpcMsg msg;
64607 +
64608 + memset(&msg, 0, sizeof(msg));
64609 + msg.msgId = FM_GUEST_ISR;
64610 + fmIpcIsr.pendingReg = pendingReg;
64611 + fmIpcIsr.boolErr = FALSE;
64612 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
64613 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
64614 + (uint8_t*)&msg,
64615 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
64616 + NULL,
64617 + NULL,
64618 + NULL,
64619 + NULL);
64620 + if (err != E_OK)
64621 + REPORT_ERROR(MINOR, err, NO_MSG);
64622 + }
64623 + else
64624 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
64625 +}
64626 +
64627 +static void BmiErrEvent(t_Fm *p_Fm)
64628 +{
64629 + uint32_t event;
64630 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
64631 +
64632 +
64633 + event = fman_get_bmi_err_event(bmi_rg);
64634 +
64635 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
64636 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
64637 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
64638 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
64639 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
64640 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
64641 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
64642 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
64643 +}
64644 +
64645 +static void QmiErrEvent(t_Fm *p_Fm)
64646 +{
64647 + uint32_t event;
64648 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64649 +
64650 + event = fman_get_qmi_err_event(qmi_rg);
64651 +
64652 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
64653 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
64654 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
64655 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
64656 +}
64657 +
64658 +static void DmaErrEvent(t_Fm *p_Fm)
64659 +{
64660 + uint32_t status, com_id;
64661 + uint8_t tnum;
64662 + uint8_t hardwarePortId;
64663 + uint8_t relativePortId;
64664 + uint16_t liodn;
64665 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
64666 +
64667 + status = fman_get_dma_err_event(dma_rg);
64668 +
64669 + if (status & DMA_STATUS_BUS_ERR)
64670 + {
64671 + com_id = fman_get_dma_com_id(dma_rg);
64672 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
64673 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64674 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
64675 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
64676 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
64677 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
64678 + p_Fm->f_BusError(p_Fm->h_App,
64679 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
64680 + relativePortId,
64681 + fman_get_dma_addr(dma_rg),
64682 + tnum,
64683 + liodn);
64684 + }
64685 + if (status & DMA_STATUS_FM_SPDAT_ECC)
64686 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
64687 + if (status & DMA_STATUS_READ_ECC)
64688 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
64689 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
64690 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
64691 + if (status & DMA_STATUS_FM_WRITE_ECC)
64692 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
64693 + }
64694 +
64695 +static void FpmErrEvent(t_Fm *p_Fm)
64696 +{
64697 + uint32_t event;
64698 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64699 +
64700 + event = fman_get_fpm_err_event(fpm_rg);
64701 +
64702 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
64703 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
64704 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
64705 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
64706 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
64707 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
64708 +}
64709 +
64710 +static void MuramErrIntr(t_Fm *p_Fm)
64711 +{
64712 + uint32_t event;
64713 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64714 +
64715 + event = fman_get_muram_err_event(fpm_rg);
64716 +
64717 + if (event & FPM_RAM_MURAM_ECC)
64718 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
64719 +}
64720 +
64721 +static void IramErrIntr(t_Fm *p_Fm)
64722 +{
64723 + uint32_t event;
64724 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64725 +
64726 + event = fman_get_iram_err_event(fpm_rg);
64727 +
64728 + if (event & FPM_RAM_IRAM_ECC)
64729 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
64730 +}
64731 +
64732 +static void QmiEvent(t_Fm *p_Fm)
64733 +{
64734 + uint32_t event;
64735 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
64736 +
64737 + event = fman_get_qmi_event(qmi_rg);
64738 +
64739 + if (event & QMI_INTR_EN_SINGLE_ECC)
64740 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
64741 +}
64742 +
64743 +static void UnimplementedIsr(t_Handle h_Arg)
64744 +{
64745 + UNUSED(h_Arg);
64746 +
64747 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
64748 +}
64749 +
64750 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
64751 +{
64752 + UNUSED(h_Arg); UNUSED(event);
64753 +
64754 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
64755 +}
64756 +
64757 +static void EnableTimeStamp(t_Fm *p_Fm)
64758 +{
64759 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
64760 +
64761 + ASSERT_COND(p_Fm->p_FmStateStruct);
64762 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
64763 +
64764 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
64765 +
64766 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
64767 +}
64768 +
64769 +static t_Error ClearIRam(t_Fm *p_Fm)
64770 +{
64771 + t_FMIramRegs *p_Iram;
64772 + int i;
64773 + int iram_size;
64774 +
64775 + ASSERT_COND(p_Fm);
64776 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64777 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
64778 +
64779 + /* Enable the auto-increment */
64780 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64781 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64782 +
64783 + for (i=0; i < (iram_size/4); i++)
64784 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64785 +
64786 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
64787 + CORE_MemoryBarrier();
64788 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
64789 +
64790 + return E_OK;
64791 +}
64792 +
64793 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
64794 +{
64795 + t_FMIramRegs *p_Iram;
64796 + int i;
64797 + uint32_t tmp;
64798 + uint8_t compTo16;
64799 +
64800 + ASSERT_COND(p_Fm);
64801 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64802 +
64803 + /* Enable the auto-increment */
64804 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64805 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64806 +
64807 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64808 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
64809 +
64810 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
64811 + if (compTo16)
64812 + for (i=0; i < ((16-compTo16) / 4); i++)
64813 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
64814 +
64815 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
64816 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
64817 +
64818 + /* verify that writing has completed */
64819 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
64820 +
64821 + if (p_Fm->fwVerify)
64822 + {
64823 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
64824 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
64825 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
64826 + {
64827 + tmp = GET_UINT32(p_Iram->idata);
64828 + if (tmp != p_Fm->firmware.p_Code[i])
64829 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
64830 + ("UCode write error : write 0x%x, read 0x%x",
64831 + p_Fm->firmware.p_Code[i],tmp));
64832 + }
64833 + WRITE_UINT32(p_Iram->iadd, 0x0);
64834 + }
64835 +
64836 + /* Enable patch from IRAM */
64837 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64838 + XX_UDelay(1000);
64839 +
64840 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
64841 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
64842 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
64843 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
64844 +
64845 + return E_OK;
64846 +}
64847 +
64848 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
64849 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
64850 +{
64851 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
64852 + uint32_t tmpReg;
64853 + uint32_t savedSpliodn[63];
64854 +
64855 + /* write to IRAM first location the debug instruction */
64856 + WRITE_UINT32(p_Iram->iadd, 0);
64857 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64858 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
64859 +
64860 + WRITE_UINT32(p_Iram->iadd, 0);
64861 + while (GET_UINT32(p_Iram->iadd) != 0) ;
64862 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
64863 +
64864 + /* Enable patch from IRAM */
64865 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
64866 + CORE_MemoryBarrier();
64867 + XX_UDelay(100);
64868 + IO2MemCpy32((uint8_t *)savedSpliodn,
64869 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64870 + 63*sizeof(uint32_t));
64871 +
64872 + /* reset FMAN */
64873 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64874 + CORE_MemoryBarrier();
64875 + XX_UDelay(100);
64876 +
64877 + /* verify breakpoint debug status register */
64878 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
64879 + if (!tmpReg)
64880 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
64881 +
64882 + /*************************************/
64883 + /* Load FMan-Controller code to IRAM */
64884 + /*************************************/
64885 + ClearIRam(p_Fm);
64886 + if (p_Fm->firmware.p_Code &&
64887 + (LoadFmanCtrlCode(p_Fm) != E_OK))
64888 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
64889 + XX_UDelay(100);
64890 +
64891 + /* reset FMAN again to start the microcode */
64892 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
64893 + CORE_MemoryBarrier();
64894 + XX_UDelay(100);
64895 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
64896 + (uint8_t *)savedSpliodn,
64897 + 63*sizeof(uint32_t));
64898 +
64899 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
64900 + {
64901 + fman_resume(p_Fm->p_FmFpmRegs);
64902 + CORE_MemoryBarrier();
64903 + XX_UDelay(100);
64904 + }
64905 +
64906 + return E_OK;
64907 +}
64908 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
64909 +
64910 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
64911 +{
64912 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
64913 +do { \
64914 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
64915 +} while (0)
64916 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
64917 +do { \
64918 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\
64919 +} while (0)
64920 +
64921 + /* error interrupts */
64922 + if (pending & ERR_INTR_EN_1G_MAC0)
64923 + FM_G_CALL_1G_MAC_ERR_ISR(0);
64924 + if (pending & ERR_INTR_EN_1G_MAC1)
64925 + FM_G_CALL_1G_MAC_ERR_ISR(1);
64926 + if (pending & ERR_INTR_EN_1G_MAC2)
64927 + FM_G_CALL_1G_MAC_ERR_ISR(2);
64928 + if (pending & ERR_INTR_EN_1G_MAC3)
64929 + FM_G_CALL_1G_MAC_ERR_ISR(3);
64930 + if (pending & ERR_INTR_EN_1G_MAC4)
64931 + FM_G_CALL_1G_MAC_ERR_ISR(4);
64932 + if (pending & ERR_INTR_EN_1G_MAC5)
64933 + FM_G_CALL_1G_MAC_ERR_ISR(5);
64934 + if (pending & ERR_INTR_EN_1G_MAC6)
64935 + FM_G_CALL_1G_MAC_ERR_ISR(6);
64936 + if (pending & ERR_INTR_EN_1G_MAC7)
64937 + FM_G_CALL_1G_MAC_ERR_ISR(7);
64938 + if (pending & ERR_INTR_EN_10G_MAC0)
64939 + FM_G_CALL_10G_MAC_ERR_ISR(0);
64940 + if (pending & ERR_INTR_EN_10G_MAC1)
64941 + FM_G_CALL_10G_MAC_ERR_ISR(1);
64942 +}
64943 +
64944 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
64945 +{
64946 +#define FM_G_CALL_1G_MAC_ISR(_id) \
64947 +do { \
64948 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\
64949 +} while (0)
64950 +#define FM_G_CALL_10G_MAC_ISR(_id) \
64951 +do { \
64952 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\
64953 +} while (0)
64954 +
64955 + if (pending & INTR_EN_1G_MAC0)
64956 + FM_G_CALL_1G_MAC_ISR(0);
64957 + if (pending & INTR_EN_1G_MAC1)
64958 + FM_G_CALL_1G_MAC_ISR(1);
64959 + if (pending & INTR_EN_1G_MAC2)
64960 + FM_G_CALL_1G_MAC_ISR(2);
64961 + if (pending & INTR_EN_1G_MAC3)
64962 + FM_G_CALL_1G_MAC_ISR(3);
64963 + if (pending & INTR_EN_1G_MAC4)
64964 + FM_G_CALL_1G_MAC_ISR(4);
64965 + if (pending & INTR_EN_1G_MAC5)
64966 + FM_G_CALL_1G_MAC_ISR(5);
64967 + if (pending & INTR_EN_1G_MAC6)
64968 + FM_G_CALL_1G_MAC_ISR(6);
64969 + if (pending & INTR_EN_1G_MAC7)
64970 + FM_G_CALL_1G_MAC_ISR(7);
64971 + if (pending & INTR_EN_10G_MAC0)
64972 + FM_G_CALL_10G_MAC_ISR(0);
64973 + if (pending & INTR_EN_10G_MAC1)
64974 + FM_G_CALL_10G_MAC_ISR(1);
64975 + if (pending & INTR_EN_TMR)
64976 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
64977 +}
64978 +
64979 +#if (DPAA_VERSION >= 11)
64980 +static t_Error SetVSPWindow(t_Handle h_Fm,
64981 + uint8_t hardwarePortId,
64982 + uint8_t baseStorageProfile,
64983 + uint8_t log2NumOfProfiles)
64984 +{
64985 + t_Fm *p_Fm = (t_Fm *)h_Fm;
64986 +
64987 + ASSERT_COND(h_Fm);
64988 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
64989 +
64990 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
64991 + !p_Fm->p_FmBmiRegs &&
64992 + p_Fm->h_IpcSessions[0])
64993 + {
64994 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
64995 + t_FmIpcMsg msg;
64996 + t_Error err = E_OK;
64997 +
64998 + memset(&msg, 0, sizeof(msg));
64999 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
65000 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
65001 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
65002 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
65003 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
65004 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
65005 +
65006 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65007 + (uint8_t*)&msg,
65008 + sizeof(msg.msgId),
65009 + NULL,
65010 + NULL,
65011 + NULL,
65012 + NULL);
65013 + if (err != E_OK)
65014 + RETURN_ERROR(MINOR, err, NO_MSG);
65015 + return E_OK;
65016 + }
65017 + else if (!p_Fm->p_FmBmiRegs)
65018 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65019 + ("Either IPC or 'baseAddress' is required!"));
65020 +
65021 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
65022 + hardwarePortId,
65023 + baseStorageProfile,
65024 + log2NumOfProfiles);
65025 +
65026 + return E_OK;
65027 +}
65028 +
65029 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
65030 +{
65031 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65032 + uint8_t profilesFound = 0;
65033 + int i = 0;
65034 + uint32_t intFlags;
65035 +
65036 + if (!numOfProfiles)
65037 + return E_OK;
65038 +
65039 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
65040 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
65041 + return (uint8_t)ILLEGAL_BASE;
65042 +
65043 + if (p_Fm->h_IpcSessions[0])
65044 + {
65045 + t_FmIpcResourceAllocParams ipcAllocParams;
65046 + t_FmIpcMsg msg;
65047 + t_FmIpcReply reply;
65048 + t_Error err;
65049 + uint32_t replyLength;
65050 +
65051 + memset(&msg, 0, sizeof(msg));
65052 + memset(&reply, 0, sizeof(reply));
65053 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
65054 + ipcAllocParams.guestId = p_Fm->guestId;
65055 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
65056 + ipcAllocParams.base = p_Fm->partVSPBase;
65057 + msg.msgId = FM_VSP_ALLOC;
65058 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
65059 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65060 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65061 + (uint8_t*)&msg,
65062 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
65063 + (uint8_t*)&reply,
65064 + &replyLength,
65065 + NULL,
65066 + NULL);
65067 + if ((err != E_OK) ||
65068 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
65069 + RETURN_ERROR(MAJOR, err, NO_MSG);
65070 + else
65071 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
65072 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
65073 + RETURN_ERROR(MAJOR, err, NO_MSG);
65074 + }
65075 + if (p_Fm->guestId != NCSW_MASTER_ID)
65076 + {
65077 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65078 + return (uint8_t)ILLEGAL_BASE;
65079 + }
65080 +
65081 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65082 + for (i = base; i < base + numOfProfiles; i++)
65083 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
65084 + profilesFound++;
65085 + else
65086 + break;
65087 +
65088 + if (profilesFound == numOfProfiles)
65089 + for (i = base; i<base + numOfProfiles; i++)
65090 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
65091 + else
65092 + {
65093 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65094 + return (uint8_t)ILLEGAL_BASE;
65095 + }
65096 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65097 +
65098 + return base;
65099 +}
65100 +
65101 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
65102 +{
65103 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65104 + int i = 0;
65105 +
65106 + ASSERT_COND(p_Fm);
65107 +
65108 + if (p_Fm->h_IpcSessions[0])
65109 + {
65110 + t_FmIpcResourceAllocParams ipcAllocParams;
65111 + t_FmIpcMsg msg;
65112 + t_FmIpcReply reply;
65113 + uint32_t replyLength;
65114 + t_Error err;
65115 +
65116 + memset(&msg, 0, sizeof(msg));
65117 + memset(&reply, 0, sizeof(reply));
65118 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
65119 + ipcAllocParams.guestId = p_Fm->guestId;
65120 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
65121 + ipcAllocParams.base = p_Fm->partVSPBase;
65122 + msg.msgId = FM_VSP_FREE;
65123 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
65124 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65125 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65126 + (uint8_t*)&msg,
65127 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
65128 + (uint8_t*)&reply,
65129 + &replyLength,
65130 + NULL,
65131 + NULL);
65132 + if (err != E_OK)
65133 + REPORT_ERROR(MAJOR, err, NO_MSG);
65134 + return;
65135 + }
65136 + if (p_Fm->guestId != NCSW_MASTER_ID)
65137 + {
65138 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
65139 + return;
65140 + }
65141 +
65142 + ASSERT_COND(p_Fm->p_FmSp);
65143 +
65144 + for (i=base; i<numOfProfiles; i++)
65145 + {
65146 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
65147 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
65148 + else
65149 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
65150 + }
65151 +}
65152 +#endif /* (DPAA_VERSION >= 11) */
65153 +
65154 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
65155 + uint8_t *p_Msg,
65156 + uint32_t msgLength,
65157 + uint8_t *p_Reply,
65158 + uint32_t *p_ReplyLength)
65159 +{
65160 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65161 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65162 +
65163 + UNUSED(p_Reply);
65164 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65165 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
65166 +
65167 +#ifdef DISABLE_SANITY_CHECKS
65168 + UNUSED(msgLength);
65169 +#endif /* DISABLE_SANITY_CHECKS */
65170 +
65171 + ASSERT_COND(p_Msg);
65172 +
65173 + *p_ReplyLength = 0;
65174 +
65175 + switch (p_IpcMsg->msgId)
65176 + {
65177 + case (FM_GUEST_ISR):
65178 + {
65179 + t_FmIpcIsr ipcIsr;
65180 +
65181 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
65182 + if (ipcIsr.boolErr)
65183 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
65184 + else
65185 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
65186 + break;
65187 + }
65188 + default:
65189 + *p_ReplyLength = 0;
65190 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65191 + }
65192 + return E_OK;
65193 +}
65194 +
65195 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
65196 + uint8_t *p_Msg,
65197 + uint32_t msgLength,
65198 + uint8_t *p_Reply,
65199 + uint32_t *p_ReplyLength)
65200 +{
65201 + t_Error err;
65202 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65203 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
65204 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
65205 +
65206 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65207 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
65208 +
65209 +#ifdef DISABLE_SANITY_CHECKS
65210 + UNUSED(msgLength);
65211 +#endif /* DISABLE_SANITY_CHECKS */
65212 +
65213 + ASSERT_COND(p_IpcMsg);
65214 +
65215 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
65216 + *p_ReplyLength = 0;
65217 +
65218 + switch (p_IpcMsg->msgId)
65219 + {
65220 + case (FM_GET_SET_PORT_PARAMS):
65221 + {
65222 + t_FmIpcPortInInitParams ipcInitParams;
65223 + t_FmInterModulePortInitParams initParams;
65224 + t_FmIpcPortOutInitParams ipcOutInitParams;
65225 +
65226 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
65227 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
65228 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
65229 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
65230 + initParams.liodnOffset = ipcInitParams.liodnOffset;
65231 + initParams.numOfTasks = ipcInitParams.numOfTasks;
65232 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
65233 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
65234 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
65235 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
65236 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
65237 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
65238 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
65239 + initParams.liodnBase = ipcInitParams.liodnBase;
65240 +
65241 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
65242 +
65243 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
65244 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
65245 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
65246 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
65247 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
65248 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
65249 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
65250 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
65251 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
65252 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
65253 + break;
65254 + }
65255 + case (FM_SET_SIZE_OF_FIFO):
65256 + {
65257 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65258 +
65259 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65260 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
65261 + ipcPortRsrcParams.hardwarePortId,
65262 + &ipcPortRsrcParams.val,
65263 + &ipcPortRsrcParams.extra,
65264 + (bool)ipcPortRsrcParams.boolInitialConfig);
65265 + *p_ReplyLength = sizeof(uint32_t);
65266 + break;
65267 + }
65268 + case (FM_SET_NUM_OF_TASKS):
65269 + {
65270 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65271 +
65272 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65273 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
65274 + (uint8_t*)&ipcPortRsrcParams.val,
65275 + (uint8_t*)&ipcPortRsrcParams.extra,
65276 + (bool)ipcPortRsrcParams.boolInitialConfig);
65277 + *p_ReplyLength = sizeof(uint32_t);
65278 + break;
65279 + }
65280 + case (FM_SET_NUM_OF_OPEN_DMAS):
65281 + {
65282 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
65283 +
65284 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
65285 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
65286 + (uint8_t*)&ipcPortRsrcParams.val,
65287 + (uint8_t*)&ipcPortRsrcParams.extra,
65288 + (bool)ipcPortRsrcParams.boolInitialConfig);
65289 + *p_ReplyLength = sizeof(uint32_t);
65290 + break;
65291 + }
65292 + case (FM_RESUME_STALLED_PORT):
65293 + *p_ReplyLength = sizeof(uint32_t);
65294 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
65295 + break;
65296 + case (FM_MASTER_IS_ALIVE):
65297 + {
65298 + uint8_t guestId = p_IpcMsg->msgBody[0];
65299 + /* build the FM master partition IPC address */
65300 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
65301 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
65302 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
65303 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
65304 + if (p_Fm->h_IpcSessions[guestId] == NULL)
65305 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
65306 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
65307 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65308 + break;
65309 + }
65310 + case (FM_IS_PORT_STALLED):
65311 + {
65312 + bool tmp;
65313 +
65314 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
65315 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
65316 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65317 + break;
65318 + }
65319 + case (FM_RESET_MAC):
65320 + {
65321 + t_FmIpcMacParams ipcMacParams;
65322 +
65323 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
65324 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
65325 + (e_FmMacType)(ipcMacParams.enumType),
65326 + ipcMacParams.id);
65327 + *p_ReplyLength = sizeof(uint32_t);
65328 + break;
65329 + }
65330 + case (FM_SET_MAC_MAX_FRAME):
65331 + {
65332 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
65333 +
65334 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
65335 + err = FmSetMacMaxFrame(p_Fm,
65336 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
65337 + ipcMacMaxFrameParams.macParams.id,
65338 + ipcMacMaxFrameParams.maxFrameLength);
65339 + if (err != E_OK)
65340 + REPORT_ERROR(MINOR, err, NO_MSG);
65341 + break;
65342 + }
65343 +#if (DPAA_VERSION >= 11)
65344 + case (FM_VSP_ALLOC) :
65345 + {
65346 + t_FmIpcResourceAllocParams ipcAllocParams;
65347 + uint8_t vspBase;
65348 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65349 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65350 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
65351 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65352 + break;
65353 + }
65354 + case (FM_VSP_FREE) :
65355 + {
65356 + t_FmIpcResourceAllocParams ipcAllocParams;
65357 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
65358 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
65359 + break;
65360 + }
65361 + case (FM_VSP_SET_PORT_WINDOW) :
65362 + {
65363 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
65364 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
65365 + err = SetVSPWindow(h_Fm,
65366 + ipcVspSetPortWindow.hardwarePortId,
65367 + ipcVspSetPortWindow.baseStorageProfile,
65368 + ipcVspSetPortWindow.log2NumOfProfiles);
65369 + return err;
65370 + }
65371 + case (FM_SET_CONG_GRP_PFC_PRIO) :
65372 + {
65373 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65374 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65375 + err = FmSetCongestionGroupPFCpriority(h_Fm,
65376 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
65377 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
65378 + return err;
65379 + }
65380 +#endif /* (DPAA_VERSION >= 11) */
65381 +
65382 + case (FM_FREE_PORT):
65383 + {
65384 + t_FmInterModulePortFreeParams portParams;
65385 + t_FmIpcPortFreeParams ipcPortParams;
65386 +
65387 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
65388 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
65389 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
65390 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
65391 + FmFreePortParams(h_Fm, &portParams);
65392 + break;
65393 + }
65394 + case (FM_REGISTER_INTR):
65395 + {
65396 + t_FmIpcRegisterIntr ipcRegIntr;
65397 +
65398 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
65399 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
65400 + break;
65401 + }
65402 + case (FM_GET_PARAMS):
65403 + {
65404 + t_FmIpcParams ipcParams;
65405 +
65406 + /* Get clock frequency */
65407 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
65408 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
65409 +
65410 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
65411 +
65412 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
65413 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
65414 + break;
65415 + }
65416 + case (FM_GET_FMAN_CTRL_CODE_REV):
65417 + {
65418 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
65419 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
65420 +
65421 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
65422 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
65423 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
65424 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
65425 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
65426 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
65427 + break;
65428 + }
65429 +
65430 + case (FM_DMA_STAT):
65431 + {
65432 + t_FmDmaStatus dmaStatus;
65433 + t_FmIpcDmaStatus ipcDmaStatus;
65434 +
65435 + FM_GetDmaStatus(h_Fm, &dmaStatus);
65436 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
65437 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
65438 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
65439 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
65440 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
65441 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
65442 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
65443 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
65444 + break;
65445 + }
65446 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
65447 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
65448 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
65449 + break;
65450 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
65451 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
65452 + break;
65453 + case (FM_GET_TIMESTAMP_SCALE):
65454 + {
65455 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
65456 +
65457 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
65458 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65459 + break;
65460 + }
65461 + case (FM_GET_COUNTER):
65462 + {
65463 + e_FmCounters inCounter;
65464 + uint32_t outCounter;
65465 +
65466 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
65467 + outCounter = FM_GetCounter(h_Fm, inCounter);
65468 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
65469 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65470 + break;
65471 + }
65472 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
65473 + {
65474 + t_FmIpcFmanEvents ipcFmanEvents;
65475 +
65476 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
65477 + FmSetFmanCtrlIntr(h_Fm,
65478 + ipcFmanEvents.eventRegId,
65479 + ipcFmanEvents.enableEvents);
65480 + break;
65481 + }
65482 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
65483 + {
65484 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
65485 +
65486 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
65487 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
65488 + break;
65489 + }
65490 + case (FM_GET_PHYS_MURAM_BASE):
65491 + {
65492 + t_FmPhysAddr physAddr;
65493 + t_FmIpcPhysAddr ipcPhysAddr;
65494 +
65495 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
65496 + ipcPhysAddr.high = physAddr.high;
65497 + ipcPhysAddr.low = physAddr.low;
65498 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
65499 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
65500 + break;
65501 + }
65502 + case (FM_ENABLE_RAM_ECC):
65503 + {
65504 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
65505 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
65506 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
65507 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65508 + UNUSED(err);
65509 +#else
65510 + REPORT_ERROR(MINOR, err, NO_MSG);
65511 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65512 + break;
65513 + }
65514 + case (FM_DISABLE_RAM_ECC):
65515 + {
65516 +
65517 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
65518 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
65519 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
65520 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
65521 + UNUSED(err);
65522 +#else
65523 + REPORT_ERROR(MINOR, err, NO_MSG);
65524 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
65525 + break;
65526 + }
65527 + case (FM_SET_NUM_OF_FMAN_CTRL):
65528 + {
65529 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
65530 +
65531 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
65532 + err = FmSetNumOfRiscsPerPort(h_Fm,
65533 + ipcPortNumOfFmanCtrls.hardwarePortId,
65534 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
65535 + ipcPortNumOfFmanCtrls.orFmanCtrl);
65536 + if (err != E_OK)
65537 + REPORT_ERROR(MINOR, err, NO_MSG);
65538 + break;
65539 + }
65540 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65541 + case (FM_10G_TX_ECC_WA):
65542 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
65543 + *p_ReplyLength = sizeof(uint32_t);
65544 + break;
65545 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65546 + default:
65547 + *p_ReplyLength = 0;
65548 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
65549 + }
65550 + return E_OK;
65551 +}
65552 +
65553 +
65554 +/****************************************/
65555 +/* Inter-Module functions */
65556 +/****************************************/
65557 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
65558 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
65559 +{
65560 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65561 + t_Error err = E_OK;
65562 + t_FmIpcMsg msg;
65563 + t_FmIpcReply reply;
65564 + uint32_t replyLength;
65565 + uint8_t rxHardwarePortId, txHardwarePortId;
65566 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
65567 +
65568 + if (p_Fm->guestId != NCSW_MASTER_ID)
65569 + {
65570 + memset(&msg, 0, sizeof(msg));
65571 + memset(&reply, 0, sizeof(reply));
65572 + msg.msgId = FM_10G_TX_ECC_WA;
65573 + msg.msgBody[0] = macId;
65574 + replyLength = sizeof(uint32_t);
65575 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65576 + (uint8_t*)&msg,
65577 + sizeof(msg.msgId)+sizeof(macId),
65578 + (uint8_t*)&reply,
65579 + &replyLength,
65580 + NULL,
65581 + NULL)) != E_OK)
65582 + RETURN_ERROR(MINOR, err, NO_MSG);
65583 + if (replyLength != sizeof(uint32_t))
65584 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65585 + return (t_Error)(reply.error);
65586 + }
65587 +
65588 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
65589 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
65590 +
65591 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
65592 + macId,
65593 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65594 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65595 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
65596 + macId,
65597 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65598 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65599 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
65600 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
65601 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
65602 + ("MAC should be initialized prior to Rx and Tx ports!"));
65603 +
65604 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
65605 +}
65606 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
65607 +
65608 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
65609 +{
65610 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65611 +
65612 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65613 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
65614 +
65615 + return p_Fm->tnumAgingPeriod;
65616 +}
65617 +
65618 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
65619 + uint8_t portNum,
65620 + bool preFetchConfigured)
65621 +{
65622 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65623 +
65624 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65625 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65626 +
65627 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
65628 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
65629 +
65630 + return E_OK;
65631 +}
65632 +
65633 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
65634 + uint8_t portNum,
65635 + bool *p_PortConfigured,
65636 + bool *p_PreFetchConfigured)
65637 +{
65638 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65639 +
65640 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65641 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
65642 +
65643 + /* If the prefetch wasn't configured yet (not enable or disabled)
65644 + we return the value TRUE as it was already configured */
65645 + if (!p_Fm->portsPreFetchConfigured[portNum])
65646 + {
65647 + *p_PortConfigured = FALSE;
65648 + *p_PreFetchConfigured = FALSE;
65649 + }
65650 + else
65651 + {
65652 + *p_PortConfigured = TRUE;
65653 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
65654 + }
65655 +
65656 + return E_OK;
65657 +}
65658 +
65659 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
65660 + uint32_t congestionGroupId,
65661 + uint8_t priorityBitMap)
65662 +{
65663 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65664 + uint32_t regNum;
65665 +
65666 + ASSERT_COND(h_Fm);
65667 +
65668 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
65669 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65670 + ("Congestion group ID bigger than %d",
65671 + FM_PORT_NUM_OF_CONGESTION_GRPS));
65672 +
65673 + if (p_Fm->guestId == NCSW_MASTER_ID)
65674 + {
65675 + ASSERT_COND(p_Fm->baseAddr);
65676 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
65677 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
65678 + congestionGroupId,
65679 + priorityBitMap,
65680 + regNum);
65681 + }
65682 + else if (p_Fm->h_IpcSessions[0])
65683 + {
65684 + t_Error err;
65685 + t_FmIpcMsg msg;
65686 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
65687 +
65688 + memset(&msg, 0, sizeof(msg));
65689 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65690 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
65691 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
65692 +
65693 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
65694 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
65695 +
65696 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65697 + (uint8_t*)&msg,
65698 + sizeof(msg.msgId),
65699 + NULL,
65700 + NULL,
65701 + NULL,
65702 + NULL);
65703 + if (err != E_OK)
65704 + RETURN_ERROR(MINOR, err, NO_MSG);
65705 + }
65706 + else
65707 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
65708 +
65709 + return E_OK;
65710 +}
65711 +
65712 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
65713 +{
65714 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65715 +
65716 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65717 +
65718 + if (!p_Fm->baseAddr)
65719 + {
65720 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65721 + ("No base-addr; probably Guest with IPC!"));
65722 + return 0;
65723 + }
65724 +
65725 + return (p_Fm->baseAddr + FM_MM_PRS);
65726 +}
65727 +
65728 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
65729 +{
65730 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65731 +
65732 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65733 +
65734 + if (!p_Fm->baseAddr)
65735 + {
65736 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65737 + ("No base-addr; probably Guest with IPC!"));
65738 + return 0;
65739 + }
65740 +
65741 + return (p_Fm->baseAddr + FM_MM_KG);
65742 +}
65743 +
65744 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
65745 +{
65746 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65747 +
65748 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65749 +
65750 + if (!p_Fm->baseAddr)
65751 + {
65752 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
65753 + ("No base-addr; probably Guest with IPC!"));
65754 + return 0;
65755 + }
65756 +
65757 + return (p_Fm->baseAddr + FM_MM_PLCR);
65758 +}
65759 +
65760 +#if (DPAA_VERSION >= 11)
65761 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
65762 +{
65763 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65764 +
65765 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
65766 +
65767 + return p_Fm->vspBaseAddr;
65768 +}
65769 +#endif /* (DPAA_VERSION >= 11) */
65770 +
65771 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
65772 +{
65773 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65774 +
65775 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
65776 +
65777 + return (p_Fm->h_FmMuram);
65778 +}
65779 +
65780 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
65781 +{
65782 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65783 +
65784 + if (p_Fm->fmMuramPhysBaseAddr)
65785 + {
65786 + /* General FM driver initialization */
65787 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
65788 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
65789 + return;
65790 + }
65791 +
65792 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
65793 +
65794 + if (p_Fm->h_IpcSessions[0])
65795 + {
65796 + t_Error err;
65797 + t_FmIpcMsg msg;
65798 + t_FmIpcReply reply;
65799 + uint32_t replyLength;
65800 + t_FmIpcPhysAddr ipcPhysAddr;
65801 +
65802 + memset(&msg, 0, sizeof(msg));
65803 + memset(&reply, 0, sizeof(reply));
65804 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
65805 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
65806 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65807 + (uint8_t*)&msg,
65808 + sizeof(msg.msgId),
65809 + (uint8_t*)&reply,
65810 + &replyLength,
65811 + NULL,
65812 + NULL);
65813 + if (err != E_OK)
65814 + {
65815 + REPORT_ERROR(MINOR, err, NO_MSG);
65816 + return;
65817 + }
65818 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
65819 + {
65820 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
65821 + return;
65822 + }
65823 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
65824 + p_FmPhysAddr->high = ipcPhysAddr.high;
65825 + p_FmPhysAddr->low = ipcPhysAddr.low;
65826 + }
65827 + else
65828 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
65829 + ("running in guest-mode without neither IPC nor mapped register!"));
65830 +}
65831 +
65832 +#if (DPAA_VERSION >= 11)
65833 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
65834 + e_FmPortType portType,
65835 + uint8_t portId,
65836 + uint8_t numOfVSPs)
65837 +{
65838 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65839 + t_Error err = E_OK;
65840 + uint32_t profilesFound, intFlags;
65841 + uint8_t first, i;
65842 + uint8_t log2Num;
65843 + uint8_t swPortIndex=0, hardwarePortId;
65844 +
65845 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65846 +
65847 + if (!numOfVSPs)
65848 + return E_OK;
65849 +
65850 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
65851 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
65852 +
65853 + if (!POWER_OF_2(numOfVSPs))
65854 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
65855 +
65856 + LOG2((uint64_t)numOfVSPs, log2Num);
65857 +
65858 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
65859 + first = 0;
65860 + else
65861 + first = 1<<log2Num;
65862 +
65863 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65864 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65865 +
65866 + if (first < p_Fm->partVSPBase)
65867 + while (first < p_Fm->partVSPBase)
65868 + first = first + numOfVSPs;
65869 +
65870 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
65871 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
65872 +
65873 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65874 + profilesFound = 0;
65875 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
65876 + {
65877 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
65878 + {
65879 + profilesFound++;
65880 + i++;
65881 + if (profilesFound == numOfVSPs)
65882 + break;
65883 + }
65884 + else
65885 + {
65886 + profilesFound = 0;
65887 + /* advance i to the next aligned address */
65888 + first = i = (uint8_t)(first + numOfVSPs);
65889 + }
65890 + }
65891 + if (profilesFound == numOfVSPs)
65892 + for (i = first; i<first + numOfVSPs; i++)
65893 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
65894 + else
65895 + {
65896 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65897 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
65898 + }
65899 +
65900 + hardwarePortId = SwPortIdToHwPortId(portType,
65901 + portId,
65902 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65903 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65904 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65905 +
65906 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
65907 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
65908 +
65909 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
65910 + for (i = first; i < first + numOfVSPs; i++)
65911 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65912 +
65913 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65914 +
65915 + return err;
65916 +}
65917 +
65918 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
65919 + e_FmPortType portType,
65920 + uint8_t portId)
65921 +{
65922 + t_Fm *p_Fm = (t_Fm *)h_Fm;
65923 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
65924 + uint32_t intFlags;
65925 +
65926 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65927 +
65928 + hardwarePortId = SwPortIdToHwPortId(portType,
65929 + portId,
65930 + p_Fm->p_FmStateStruct->revInfo.majorRev,
65931 + p_Fm->p_FmStateStruct->revInfo.minorRev);
65932 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
65933 +
65934 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
65935 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
65936 +
65937 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
65938 + for (i = first; i < first + numOfVSPs; i++)
65939 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
65940 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
65941 +
65942 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
65943 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
65944 +
65945 + return E_OK;
65946 +}
65947 +#endif /* (DPAA_VERSION >= 11) */
65948 +
65949 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
65950 +{
65951 + t_Fm *p_Fm = (t_Fm*)h_Fm;
65952 + uint8_t i;
65953 +
65954 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
65955 +
65956 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
65957 + p_Fm->h_IpcSessions[0])
65958 + {
65959 + t_Error err;
65960 + t_FmIpcMsg msg;
65961 + t_FmIpcReply reply;
65962 + uint32_t replyLength;
65963 +
65964 + memset(&msg, 0, sizeof(msg));
65965 + memset(&reply, 0, sizeof(reply));
65966 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
65967 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
65968 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
65969 + (uint8_t*)&msg,
65970 + sizeof(msg.msgId),
65971 + (uint8_t*)&reply,
65972 + &replyLength,
65973 + NULL,
65974 + NULL)) != E_OK)
65975 + RETURN_ERROR(MAJOR, err, NO_MSG);
65976 +
65977 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
65978 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
65979 +
65980 + *p_EventId = *(uint8_t*)(reply.replyBody);
65981 +
65982 + return (t_Error)(reply.error);
65983 + }
65984 + else if (p_Fm->guestId != NCSW_MASTER_ID)
65985 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
65986 + ("running in guest-mode without IPC!"));
65987 +
65988 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
65989 + if (!p_Fm->usedEventRegs[i])
65990 + {
65991 + p_Fm->usedEventRegs[i] = TRUE;
65992 + *p_EventId = i;
65993 + break;
65994 + }
65995 +
65996 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
65997 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
65998 +
65999 + return E_OK;
66000 +}
66001 +
66002 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
66003 +{
66004 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66005 +
66006 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
66007 +
66008 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66009 + p_Fm->h_IpcSessions[0])
66010 + {
66011 + t_Error err;
66012 + t_FmIpcMsg msg;
66013 +
66014 + memset(&msg, 0, sizeof(msg));
66015 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
66016 + msg.msgBody[0] = eventId;
66017 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66018 + (uint8_t*)&msg,
66019 + sizeof(msg.msgId)+sizeof(eventId),
66020 + NULL,
66021 + NULL,
66022 + NULL,
66023 + NULL);
66024 + if (err != E_OK)
66025 + REPORT_ERROR(MINOR, err, NO_MSG);
66026 + return;
66027 + }
66028 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66029 + {
66030 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66031 + ("running in guest-mode without IPC!"));
66032 + return;
66033 + }
66034 +
66035 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
66036 +}
66037 +
66038 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
66039 +{
66040 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66041 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66042 +
66043 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66044 + !p_Fm->p_FmFpmRegs &&
66045 + p_Fm->h_IpcSessions[0])
66046 + {
66047 + t_FmIpcFmanEvents fmanCtrl;
66048 + t_Error err;
66049 + t_FmIpcMsg msg;
66050 +
66051 + fmanCtrl.eventRegId = eventRegId;
66052 + fmanCtrl.enableEvents = enableEvents;
66053 + memset(&msg, 0, sizeof(msg));
66054 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
66055 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
66056 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66057 + (uint8_t*)&msg,
66058 + sizeof(msg.msgId)+sizeof(fmanCtrl),
66059 + NULL,
66060 + NULL,
66061 + NULL,
66062 + NULL);
66063 + if (err != E_OK)
66064 + REPORT_ERROR(MINOR, err, NO_MSG);
66065 + return;
66066 + }
66067 + else if (!p_Fm->p_FmFpmRegs)
66068 + {
66069 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66070 + ("Either IPC or 'baseAddress' is required!"));
66071 + return;
66072 + }
66073 +
66074 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66075 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
66076 +}
66077 +
66078 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66079 +{
66080 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66081 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66082 +
66083 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66084 + !p_Fm->p_FmFpmRegs &&
66085 + p_Fm->h_IpcSessions[0])
66086 + {
66087 + t_Error err;
66088 + t_FmIpcMsg msg;
66089 + t_FmIpcReply reply;
66090 + uint32_t replyLength, ctrlIntr;
66091 +
66092 + memset(&msg, 0, sizeof(msg));
66093 + memset(&reply, 0, sizeof(reply));
66094 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
66095 + msg.msgBody[0] = eventRegId;
66096 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66097 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66098 + (uint8_t*)&msg,
66099 + sizeof(msg.msgId)+sizeof(eventRegId),
66100 + (uint8_t*)&reply,
66101 + &replyLength,
66102 + NULL,
66103 + NULL);
66104 + if (err != E_OK)
66105 + {
66106 + REPORT_ERROR(MINOR, err, NO_MSG);
66107 + return 0;
66108 + }
66109 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66110 + {
66111 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66112 + return 0;
66113 + }
66114 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
66115 + return ctrlIntr;
66116 + }
66117 + else if (!p_Fm->p_FmFpmRegs)
66118 + {
66119 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66120 + ("Either IPC or 'baseAddress' is required!"));
66121 + return 0;
66122 + }
66123 +
66124 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
66125 +}
66126 +
66127 +void FmRegisterIntr(t_Handle h_Fm,
66128 + e_FmEventModules module,
66129 + uint8_t modId,
66130 + e_FmIntrType intrType,
66131 + void (*f_Isr) (t_Handle h_Arg),
66132 + t_Handle h_Arg)
66133 +{
66134 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66135 + int event = 0;
66136 +
66137 + ASSERT_COND(h_Fm);
66138 +
66139 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
66140 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66141 +
66142 + /* register in local FM structure */
66143 + p_Fm->intrMng[event].f_Isr = f_Isr;
66144 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
66145 +
66146 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66147 + p_Fm->h_IpcSessions[0])
66148 + {
66149 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
66150 + t_Error err;
66151 + t_FmIpcMsg msg;
66152 +
66153 + /* register in Master FM structure */
66154 + fmIpcRegisterIntr.event = (uint32_t)event;
66155 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
66156 + memset(&msg, 0, sizeof(msg));
66157 + msg.msgId = FM_REGISTER_INTR;
66158 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
66159 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66160 + (uint8_t*)&msg,
66161 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
66162 + NULL,
66163 + NULL,
66164 + NULL,
66165 + NULL);
66166 + if (err != E_OK)
66167 + REPORT_ERROR(MINOR, err, NO_MSG);
66168 + }
66169 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66170 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
66171 + ("running in guest-mode without IPC!"));
66172 +}
66173 +
66174 +void FmUnregisterIntr(t_Handle h_Fm,
66175 + e_FmEventModules module,
66176 + uint8_t modId,
66177 + e_FmIntrType intrType)
66178 +{
66179 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66180 + int event = 0;
66181 +
66182 + ASSERT_COND(h_Fm);
66183 +
66184 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
66185 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
66186 +
66187 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
66188 + p_Fm->intrMng[event].h_SrcHandle = NULL;
66189 +}
66190 +
66191 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
66192 +{
66193 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66194 +
66195 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66196 +
66197 + if (p_Fm->guestId != NCSW_MASTER_ID)
66198 + {
66199 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66200 + return;
66201 + }
66202 +
66203 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
66204 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
66205 +}
66206 +
66207 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
66208 +{
66209 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66210 +
66211 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
66212 +
66213 + if (p_Fm->guestId != NCSW_MASTER_ID)
66214 + {
66215 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
66216 + return;
66217 + }
66218 +
66219 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
66220 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
66221 +}
66222 +
66223 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
66224 +{
66225 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66226 +
66227 + if (p_Fm->h_Pcd)
66228 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
66229 +
66230 + p_Fm->h_Pcd = h_FmPcd;
66231 +}
66232 +
66233 +void FmUnregisterPcd(t_Handle h_Fm)
66234 +{
66235 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66236 +
66237 + if (!p_Fm->h_Pcd)
66238 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
66239 +
66240 + p_Fm->h_Pcd = NULL;
66241 +}
66242 +
66243 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
66244 +{
66245 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66246 +
66247 + return p_Fm->h_Pcd;
66248 +}
66249 +
66250 +uint8_t FmGetId(t_Handle h_Fm)
66251 +{
66252 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66253 +
66254 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
66255 +
66256 + return p_Fm->p_FmStateStruct->fmId;
66257 +}
66258 +
66259 +t_Error FmReset(t_Handle h_Fm)
66260 +{
66261 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66262 +
66263 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66264 +
66265 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66266 + CORE_MemoryBarrier();
66267 + XX_UDelay(100);
66268 +
66269 + return E_OK;
66270 +}
66271 +
66272 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
66273 + uint8_t hardwarePortId,
66274 + uint8_t numOfFmanCtrls,
66275 + t_FmFmanCtrl orFmanCtrl)
66276 +{
66277 +
66278 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66279 + struct fman_fpm_regs *fpm_rg;
66280 +
66281 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66282 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
66283 +
66284 + fpm_rg = p_Fm->p_FmFpmRegs;
66285 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66286 + !p_Fm->p_FmFpmRegs &&
66287 + p_Fm->h_IpcSessions[0])
66288 + {
66289 + t_Error err;
66290 + t_FmIpcPortNumOfFmanCtrls params;
66291 + t_FmIpcMsg msg;
66292 +
66293 + memset(&msg, 0, sizeof(msg));
66294 + params.hardwarePortId = hardwarePortId;
66295 + params.numOfFmanCtrls = numOfFmanCtrls;
66296 + params.orFmanCtrl = orFmanCtrl;
66297 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
66298 + memcpy(msg.msgBody, &params, sizeof(params));
66299 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66300 + (uint8_t*)&msg,
66301 + sizeof(msg.msgId) +sizeof(params),
66302 + NULL,
66303 + NULL,
66304 + NULL,
66305 + NULL);
66306 + if (err != E_OK)
66307 + RETURN_ERROR(MINOR, err, NO_MSG);
66308 + return E_OK;
66309 + }
66310 + else if (!p_Fm->p_FmFpmRegs)
66311 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66312 + ("Either IPC or 'baseAddress' is required!"));
66313 +
66314 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
66315 +
66316 + return E_OK;
66317 +}
66318 +
66319 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
66320 +{
66321 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66322 + t_Error err;
66323 + uint32_t intFlags;
66324 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
66325 + struct fman_rg fman_rg;
66326 +
66327 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
66328 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
66329 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
66330 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
66331 +
66332 + if (p_Fm->guestId != NCSW_MASTER_ID)
66333 + {
66334 + t_FmIpcPortInInitParams portInParams;
66335 + t_FmIpcPortOutInitParams portOutParams;
66336 + t_FmIpcMsg msg;
66337 + t_FmIpcReply reply;
66338 + uint32_t replyLength;
66339 +
66340 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
66341 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
66342 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
66343 + portInParams.liodnOffset = p_PortParams->liodnOffset;
66344 + portInParams.numOfTasks = p_PortParams->numOfTasks;
66345 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
66346 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
66347 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
66348 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
66349 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
66350 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66351 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
66352 + portInParams.liodnBase = p_PortParams->liodnBase;
66353 +
66354 + memset(&msg, 0, sizeof(msg));
66355 + memset(&reply, 0, sizeof(reply));
66356 + msg.msgId = FM_GET_SET_PORT_PARAMS;
66357 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
66358 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
66359 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66360 + (uint8_t*)&msg,
66361 + sizeof(msg.msgId) +sizeof(portInParams),
66362 + (uint8_t*)&reply,
66363 + &replyLength,
66364 + NULL,
66365 + NULL)) != E_OK)
66366 + RETURN_ERROR(MINOR, err, NO_MSG);
66367 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
66368 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66369 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
66370 +
66371 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
66372 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
66373 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
66374 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
66375 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
66376 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
66377 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
66378 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
66379 +
66380 + return (t_Error)(reply.error);
66381 + }
66382 +
66383 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66384 +
66385 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66386 + if (p_PortParams->independentMode)
66387 + {
66388 + /* set port parameters */
66389 + p_Fm->independentMode = p_PortParams->independentMode;
66390 + /* disable dispatch limit */
66391 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
66392 + }
66393 +
66394 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66395 + {
66396 + if (p_Fm->hcPortInitialized)
66397 + {
66398 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66399 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
66400 + }
66401 + else
66402 + p_Fm->hcPortInitialized = TRUE;
66403 + }
66404 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
66405 +
66406 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
66407 + if (err)
66408 + {
66409 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66410 + RETURN_ERROR(MAJOR, err, NO_MSG);
66411 + }
66412 +
66413 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66414 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66415 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66416 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66417 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66418 + /* for transmit & O/H ports */
66419 + {
66420 + uint8_t enqTh;
66421 + uint8_t deqTh;
66422 +
66423 + /* update qmi ENQ/DEQ threshold */
66424 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
66425 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
66426 + /* if enqTh is too big, we reduce it to the max value that is still OK */
66427 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
66428 + {
66429 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66430 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
66431 + }
66432 +
66433 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
66434 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
66435 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
66436 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
66437 + {
66438 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66439 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
66440 + }
66441 + }
66442 +
66443 +#ifdef FM_LOW_END_RESTRICTION
66444 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66445 + {
66446 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
66447 + {
66448 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66449 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
66450 + }
66451 + else
66452 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
66453 + }
66454 +#endif /* FM_LOW_END_RESTRICTION */
66455 +
66456 + err = FmSetSizeOfFifo(p_Fm,
66457 + hardwarePortId,
66458 + &p_PortParams->sizeOfFifo,
66459 + &p_PortParams->extraSizeOfFifo,
66460 + TRUE);
66461 + if (err)
66462 + {
66463 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66464 + RETURN_ERROR(MAJOR, err, NO_MSG);
66465 + }
66466 +
66467 + err = FmSetNumOfOpenDmas(p_Fm,
66468 + hardwarePortId,
66469 + &p_PortParams->numOfOpenDmas,
66470 + &p_PortParams->numOfExtraOpenDmas,
66471 + TRUE);
66472 + if (err)
66473 + {
66474 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66475 + RETURN_ERROR(MAJOR, err, NO_MSG);
66476 + }
66477 +
66478 + fman_set_liodn_per_port(&fman_rg,
66479 + hardwarePortId,
66480 + p_PortParams->liodnBase,
66481 + p_PortParams->liodnOffset);
66482 +
66483 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66484 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
66485 + hardwarePortId,
66486 + p_PortParams->independentMode,
66487 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
66488 +
66489 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66490 +
66491 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66492 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66493 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66494 + {
66495 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66496 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
66497 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
66498 + else
66499 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66500 + }
66501 + else
66502 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66503 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66504 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66505 + {
66506 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66507 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
66508 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
66509 + else
66510 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
66511 + }
66512 +
66513 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
66514 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66515 +
66516 + return E_OK;
66517 +}
66518 +
66519 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
66520 +{
66521 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66522 + uint32_t intFlags;
66523 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
66524 + uint8_t numOfTasks, numOfDmas, macId;
66525 + uint16_t sizeOfFifo;
66526 + t_Error err;
66527 + t_FmIpcPortFreeParams portParams;
66528 + t_FmIpcMsg msg;
66529 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66530 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66531 +
66532 + if (p_Fm->guestId != NCSW_MASTER_ID)
66533 + {
66534 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
66535 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
66536 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
66537 + memset(&msg, 0, sizeof(msg));
66538 + msg.msgId = FM_FREE_PORT;
66539 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
66540 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66541 + (uint8_t*)&msg,
66542 + sizeof(msg.msgId)+sizeof(portParams),
66543 + NULL,
66544 + NULL,
66545 + NULL,
66546 + NULL);
66547 + if (err != E_OK)
66548 + REPORT_ERROR(MINOR, err, NO_MSG);
66549 + return;
66550 + }
66551 +
66552 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66553 +
66554 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66555 +
66556 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
66557 + {
66558 + ASSERT_COND(p_Fm->hcPortInitialized);
66559 + p_Fm->hcPortInitialized = FALSE;
66560 + }
66561 +
66562 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
66563 +
66564 + /* free numOfTasks */
66565 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
66566 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
66567 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
66568 +
66569 + /* free numOfOpenDmas */
66570 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
66571 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
66572 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
66573 +
66574 +#ifdef FM_HAS_TOTAL_DMAS
66575 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
66576 + {
66577 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
66578 + fman_set_num_of_open_dmas(bmi_rg,
66579 + hardwarePortId,
66580 + 1,
66581 + 0,
66582 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
66583 + }
66584 +#endif /* FM_HAS_TOTAL_DMAS */
66585 +
66586 + /* free sizeOfFifo */
66587 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
66588 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
66589 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
66590 +
66591 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
66592 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
66593 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
66594 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
66595 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
66596 + /* for transmit & O/H ports */
66597 + {
66598 + uint8_t enqTh;
66599 + uint8_t deqTh;
66600 +
66601 + /* update qmi ENQ/DEQ threshold */
66602 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
66603 +
66604 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66605 + so we can enlarge enqTh */
66606 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
66607 +
66608 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
66609 + so we can reduce deqTh */
66610 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
66611 +
66612 + fman_set_qmi_enq_th(qmi_rg, enqTh);
66613 + fman_set_qmi_deq_th(qmi_rg, deqTh);
66614 + }
66615 +
66616 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
66617 +
66618 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
66619 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
66620 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
66621 + {
66622 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
66623 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
66624 + }
66625 + else
66626 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66627 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
66628 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
66629 + {
66630 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
66631 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
66632 + }
66633 +
66634 +#ifdef FM_LOW_END_RESTRICTION
66635 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
66636 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
66637 +#endif /* FM_LOW_END_RESTRICTION */
66638 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66639 +}
66640 +
66641 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
66642 +{
66643 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66644 + t_Error err;
66645 + t_FmIpcMsg msg;
66646 + t_FmIpcReply reply;
66647 + uint32_t replyLength;
66648 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66649 +
66650 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66651 + !p_Fm->baseAddr &&
66652 + p_Fm->h_IpcSessions[0])
66653 + {
66654 + memset(&msg, 0, sizeof(msg));
66655 + memset(&reply, 0, sizeof(reply));
66656 + msg.msgId = FM_IS_PORT_STALLED;
66657 + msg.msgBody[0] = hardwarePortId;
66658 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66659 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66660 + (uint8_t*)&msg,
66661 + sizeof(msg.msgId)+sizeof(hardwarePortId),
66662 + (uint8_t*)&reply,
66663 + &replyLength,
66664 + NULL,
66665 + NULL);
66666 + if (err != E_OK)
66667 + RETURN_ERROR(MINOR, err, NO_MSG);
66668 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
66669 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66670 +
66671 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
66672 +
66673 + return (t_Error)(reply.error);
66674 + }
66675 + else if (!p_Fm->baseAddr)
66676 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66677 + ("Either IPC or 'baseAddress' is required!"));
66678 +
66679 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
66680 +
66681 + return E_OK;
66682 +}
66683 +
66684 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
66685 +{
66686 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66687 + t_Error err;
66688 + bool isStalled;
66689 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66690 +
66691 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66692 + !p_Fm->baseAddr &&
66693 + p_Fm->h_IpcSessions[0])
66694 + {
66695 + t_FmIpcMsg msg;
66696 + t_FmIpcReply reply;
66697 + uint32_t replyLength;
66698 +
66699 + memset(&msg, 0, sizeof(msg));
66700 + memset(&reply, 0, sizeof(reply));
66701 + msg.msgId = FM_RESUME_STALLED_PORT;
66702 + msg.msgBody[0] = hardwarePortId;
66703 + replyLength = sizeof(uint32_t);
66704 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66705 + (uint8_t*)&msg,
66706 + sizeof(msg.msgId) + sizeof(hardwarePortId),
66707 + (uint8_t*)&reply,
66708 + &replyLength,
66709 + NULL,
66710 + NULL);
66711 + if (err != E_OK)
66712 + RETURN_ERROR(MINOR, err, NO_MSG);
66713 + if (replyLength != sizeof(uint32_t))
66714 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66715 + return (t_Error)(reply.error);
66716 + }
66717 + else if (!p_Fm->baseAddr)
66718 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66719 + ("Either IPC or 'baseAddress' is required!"));
66720 +
66721 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66722 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
66723 +
66724 + /* Get port status */
66725 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
66726 + if (err)
66727 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
66728 + if (!isStalled)
66729 + return E_OK;
66730 +
66731 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
66732 +
66733 + return E_OK;
66734 +}
66735 +
66736 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
66737 +{
66738 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66739 + t_Error err;
66740 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66741 +
66742 +#if (DPAA_VERSION >= 11)
66743 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66744 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66745 + ("FMan MAC reset!"));
66746 +#endif /*(DPAA_VERSION >= 11)*/
66747 +
66748 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66749 + !p_Fm->baseAddr &&
66750 + p_Fm->h_IpcSessions[0])
66751 + {
66752 + t_FmIpcMacParams macParams;
66753 + t_FmIpcMsg msg;
66754 + t_FmIpcReply reply;
66755 + uint32_t replyLength;
66756 +
66757 + memset(&msg, 0, sizeof(msg));
66758 + memset(&reply, 0, sizeof(reply));
66759 + macParams.id = macId;
66760 + macParams.enumType = (uint32_t)type;
66761 + msg.msgId = FM_RESET_MAC;
66762 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
66763 + replyLength = sizeof(uint32_t);
66764 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66765 + (uint8_t*)&msg,
66766 + sizeof(msg.msgId)+sizeof(macParams),
66767 + (uint8_t*)&reply,
66768 + &replyLength,
66769 + NULL,
66770 + NULL);
66771 + if (err != E_OK)
66772 + RETURN_ERROR(MINOR, err, NO_MSG);
66773 + if (replyLength != sizeof(uint32_t))
66774 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66775 + return (t_Error)(reply.error);
66776 + }
66777 + else if (!p_Fm->baseAddr)
66778 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66779 + ("Either IPC or 'baseAddress' is required!"));
66780 +
66781 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
66782 +
66783 + if (err == -EBUSY)
66784 + return ERROR_CODE(E_TIMEOUT);
66785 + else if (err)
66786 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
66787 +
66788 + return E_OK;
66789 +}
66790 +
66791 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
66792 +{
66793 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66794 +
66795 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66796 + p_Fm->h_IpcSessions[0])
66797 + {
66798 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
66799 + t_Error err;
66800 + t_FmIpcMsg msg;
66801 +
66802 + memset(&msg, 0, sizeof(msg));
66803 + macMaxFrameLengthParams.macParams.id = macId;
66804 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
66805 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
66806 + msg.msgId = FM_SET_MAC_MAX_FRAME;
66807 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
66808 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66809 + (uint8_t*)&msg,
66810 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
66811 + NULL,
66812 + NULL,
66813 + NULL,
66814 + NULL);
66815 + if (err != E_OK)
66816 + RETURN_ERROR(MINOR, err, NO_MSG);
66817 + return E_OK;
66818 + }
66819 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66820 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66821 + ("running in guest-mode without IPC!"));
66822 +
66823 + /* if port is already initialized, check that MaxFrameLength is smaller
66824 + * or equal to the port's max */
66825 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
66826 + if (type == e_FM_MAC_10G)
66827 + {
66828 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
66829 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
66830 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
66831 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
66832 + else
66833 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66834 +
66835 + }
66836 + else
66837 +#else
66838 + UNUSED(type);
66839 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
66840 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
66841 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
66842 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
66843 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
66844 + else
66845 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
66846 +
66847 + return E_OK;
66848 +}
66849 +
66850 +uint16_t FmGetClockFreq(t_Handle h_Fm)
66851 +{
66852 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66853 +
66854 + /* for multicore environment: this depends on the
66855 + * fact that fmClkFreq was properly initialized at "init". */
66856 + return p_Fm->p_FmStateStruct->fmClkFreq;
66857 +}
66858 +
66859 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
66860 +{
66861 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66862 +
66863 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
66864 +}
66865 +
66866 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
66867 +{
66868 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66869 +
66870 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66871 + !p_Fm->baseAddr &&
66872 + p_Fm->h_IpcSessions[0])
66873 + {
66874 + t_Error err;
66875 + t_FmIpcMsg msg;
66876 + t_FmIpcReply reply;
66877 + uint32_t replyLength, timeStamp;
66878 +
66879 + memset(&msg, 0, sizeof(msg));
66880 + memset(&reply, 0, sizeof(reply));
66881 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
66882 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
66883 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66884 + (uint8_t*)&msg,
66885 + sizeof(msg.msgId),
66886 + (uint8_t*)&reply,
66887 + &replyLength,
66888 + NULL,
66889 + NULL)) != E_OK)
66890 + {
66891 + REPORT_ERROR(MAJOR, err, NO_MSG);
66892 + return 0;
66893 + }
66894 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
66895 + {
66896 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
66897 + return 0;
66898 + }
66899 +
66900 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
66901 + return timeStamp;
66902 + }
66903 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66904 + p_Fm->baseAddr)
66905 + {
66906 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
66907 + {
66908 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
66909 + return 0;
66910 + }
66911 + }
66912 + else if (p_Fm->guestId != NCSW_MASTER_ID)
66913 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
66914 +
66915 + return p_Fm->p_FmStateStruct->count1MicroBit;
66916 +}
66917 +
66918 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
66919 +{
66920 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66921 +
66922 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66923 +
66924 + p_Fm->p_FmStateStruct->ramsEccOwners++;
66925 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66926 +
66927 + return FM_EnableRamsEcc(p_Fm);
66928 +}
66929 +
66930 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
66931 +{
66932 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66933 +
66934 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66935 +
66936 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
66937 + p_Fm->p_FmStateStruct->ramsEccOwners--;
66938 +
66939 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
66940 + {
66941 + p_Fm->p_FmStateStruct->internalCall = TRUE;
66942 + return FM_DisableRamsEcc(p_Fm);
66943 + }
66944 +
66945 + return E_OK;
66946 +}
66947 +
66948 +uint8_t FmGetGuestId(t_Handle h_Fm)
66949 +{
66950 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66951 +
66952 + return p_Fm->guestId;
66953 +}
66954 +
66955 +bool FmIsMaster(t_Handle h_Fm)
66956 +{
66957 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66958 +
66959 + return (p_Fm->guestId == NCSW_MASTER_ID);
66960 +}
66961 +
66962 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
66963 + uint8_t hardwarePortId,
66964 + uint32_t *p_SizeOfFifo,
66965 + uint32_t *p_ExtraSizeOfFifo,
66966 + bool initialConfig)
66967 +{
66968 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66969 + t_FmIpcPortRsrcParams rsrcParams;
66970 + t_Error err;
66971 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66972 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
66973 + uint16_t currentVal = 0, currentExtraVal = 0;
66974 +
66975 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66976 + !p_Fm->baseAddr &&
66977 + p_Fm->h_IpcSessions[0])
66978 + {
66979 + t_FmIpcMsg msg;
66980 + t_FmIpcReply reply;
66981 + uint32_t replyLength;
66982 +
66983 + rsrcParams.hardwarePortId = hardwarePortId;
66984 + rsrcParams.val = sizeOfFifo;
66985 + rsrcParams.extra = extraSizeOfFifo;
66986 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
66987 +
66988 + memset(&msg, 0, sizeof(msg));
66989 + memset(&reply, 0, sizeof(reply));
66990 + msg.msgId = FM_SET_SIZE_OF_FIFO;
66991 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
66992 + replyLength = sizeof(uint32_t);
66993 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66994 + (uint8_t*)&msg,
66995 + sizeof(msg.msgId) + sizeof(rsrcParams),
66996 + (uint8_t*)&reply,
66997 + &replyLength,
66998 + NULL,
66999 + NULL)) != E_OK)
67000 + RETURN_ERROR(MINOR, err, NO_MSG);
67001 + if (replyLength != sizeof(uint32_t))
67002 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67003 + return (t_Error)(reply.error);
67004 + }
67005 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67006 + p_Fm->baseAddr)
67007 + {
67008 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
67009 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
67010 + }
67011 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67012 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67013 + ("running in guest-mode without neither IPC nor mapped register!"));
67014 +
67015 + if (!initialConfig)
67016 + {
67017 + /* !initialConfig - runtime change of existing value.
67018 + * - read the current FIFO and extra FIFO size */
67019 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
67020 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
67021 + }
67022 +
67023 + if (extraSizeOfFifo > currentExtraVal)
67024 + {
67025 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
67026 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
67027 + * must be initialized to 1 buffer per port
67028 + */
67029 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
67030 +
67031 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
67032 + }
67033 +
67034 + /* check that there are enough uncommitted fifo size */
67035 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
67036 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
67037 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
67038 + ("Port request fifo size + accumulated size > total FIFO size:"));
67039 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
67040 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
67041 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
67042 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
67043 + p_Fm->p_FmStateStruct->totalFifoSize));
67044 + }
67045 + else
67046 + {
67047 + /* update accumulated */
67048 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
67049 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
67050 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
67051 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
67052 + }
67053 +
67054 + return E_OK;
67055 +}
67056 +
67057 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
67058 + uint8_t hardwarePortId,
67059 + uint8_t *p_NumOfTasks,
67060 + uint8_t *p_NumOfExtraTasks,
67061 + bool initialConfig)
67062 +{
67063 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67064 + t_Error err;
67065 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67066 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
67067 +
67068 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67069 +
67070 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67071 + !p_Fm->baseAddr &&
67072 + p_Fm->h_IpcSessions[0])
67073 + {
67074 + t_FmIpcPortRsrcParams rsrcParams;
67075 + t_FmIpcMsg msg;
67076 + t_FmIpcReply reply;
67077 + uint32_t replyLength;
67078 +
67079 + rsrcParams.hardwarePortId = hardwarePortId;
67080 + rsrcParams.val = numOfTasks;
67081 + rsrcParams.extra = numOfExtraTasks;
67082 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67083 +
67084 + memset(&msg, 0, sizeof(msg));
67085 + memset(&reply, 0, sizeof(reply));
67086 + msg.msgId = FM_SET_NUM_OF_TASKS;
67087 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67088 + replyLength = sizeof(uint32_t);
67089 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67090 + (uint8_t*)&msg,
67091 + sizeof(msg.msgId) + sizeof(rsrcParams),
67092 + (uint8_t*)&reply,
67093 + &replyLength,
67094 + NULL,
67095 + NULL)) != E_OK)
67096 + RETURN_ERROR(MINOR, err, NO_MSG);
67097 + if (replyLength != sizeof(uint32_t))
67098 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67099 + return (t_Error)(reply.error);
67100 + }
67101 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67102 + p_Fm->baseAddr)
67103 + {
67104 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
67105 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67106 + }
67107 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67108 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67109 + ("running in guest-mode without neither IPC nor mapped register!"));
67110 +
67111 + if (!initialConfig)
67112 + {
67113 + /* !initialConfig - runtime change of existing value.
67114 + * - read the current number of tasks */
67115 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
67116 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
67117 + }
67118 +
67119 + if (numOfExtraTasks > currentExtraVal)
67120 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
67121 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
67122 +
67123 + /* check that there are enough uncommitted tasks */
67124 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
67125 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
67126 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67127 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
67128 + p_Fm->p_FmStateStruct->fmId));
67129 + else
67130 + {
67131 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
67132 + /* update accumulated */
67133 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
67134 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
67135 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
67136 + }
67137 +
67138 + return E_OK;
67139 +}
67140 +
67141 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
67142 + uint8_t hardwarePortId,
67143 + uint8_t *p_NumOfOpenDmas,
67144 + uint8_t *p_NumOfExtraOpenDmas,
67145 + bool initialConfig)
67146 +
67147 +{
67148 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67149 + t_Error err;
67150 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
67151 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
67152 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
67153 +
67154 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67155 +
67156 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67157 + !p_Fm->baseAddr &&
67158 + p_Fm->h_IpcSessions[0])
67159 + {
67160 + t_FmIpcPortRsrcParams rsrcParams;
67161 + t_FmIpcMsg msg;
67162 + t_FmIpcReply reply;
67163 + uint32_t replyLength;
67164 +
67165 + rsrcParams.hardwarePortId = hardwarePortId;
67166 + rsrcParams.val = numOfOpenDmas;
67167 + rsrcParams.extra = numOfExtraOpenDmas;
67168 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
67169 +
67170 + memset(&msg, 0, sizeof(msg));
67171 + memset(&reply, 0, sizeof(reply));
67172 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
67173 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
67174 + replyLength = sizeof(uint32_t);
67175 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67176 + (uint8_t*)&msg,
67177 + sizeof(msg.msgId) + sizeof(rsrcParams),
67178 + (uint8_t*)&reply,
67179 + &replyLength,
67180 + NULL,
67181 + NULL)) != E_OK)
67182 + RETURN_ERROR(MINOR, err, NO_MSG);
67183 + if (replyLength != sizeof(uint32_t))
67184 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67185 + return (t_Error)(reply.error);
67186 + }
67187 +#ifdef FM_HAS_TOTAL_DMAS
67188 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67189 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
67190 +#else
67191 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67192 + p_Fm->baseAddr &&
67193 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
67194 + {
67195 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
67196 +
67197 + if (!numOfOpenDmas)
67198 + {
67199 + /* first config without explic it value: Do Nothing - reset value shouldn't be
67200 + changed, read register for port save */
67201 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67202 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67203 + }
67204 + else
67205 + /* whether it is the first time with explicit value, or runtime "set" - write register */
67206 + fman_set_num_of_open_dmas(bmi_rg,
67207 + hardwarePortId,
67208 + numOfOpenDmas,
67209 + numOfExtraOpenDmas,
67210 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67211 + }
67212 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67213 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
67214 + ("running in guest-mode without neither IPC nor mapped register!"));
67215 +#endif /* FM_HAS_TOTAL_DMAS */
67216 +
67217 + if (!initialConfig)
67218 + {
67219 + /* !initialConfig - runtime change of existing value.
67220 + * - read the current number of open Dma's */
67221 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67222 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67223 + }
67224 +
67225 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
67226 + /* it's illegal to be in a state where this is not the first set and no value is specified */
67227 + ASSERT_COND(initialConfig || numOfOpenDmas);
67228 + if (!numOfOpenDmas)
67229 + {
67230 + /* !numOfOpenDmas - first configuration according to values in regs.
67231 + * - read the current number of open Dma's */
67232 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
67233 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
67234 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
67235 + * reset values will be used and we just save these values for resource management */
67236 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67237 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
67238 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
67239 + *p_NumOfOpenDmas = currentVal;
67240 + *p_NumOfExtraOpenDmas = currentExtraVal;
67241 + return E_OK;
67242 + }
67243 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
67244 +
67245 + if (numOfExtraOpenDmas > currentExtraVal)
67246 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
67247 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
67248 +
67249 +#ifdef FM_HAS_TOTAL_DMAS
67250 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
67251 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
67252 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
67253 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67254 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
67255 + p_Fm->p_FmStateStruct->fmId));
67256 +#else
67257 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
67258 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
67259 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
67260 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
67261 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
67262 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
67263 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
67264 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
67265 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
67266 +#endif /* FM_HAS_TOTAL_DMAS */
67267 + else
67268 + {
67269 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
67270 + /* update acummulated */
67271 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
67272 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
67273 +
67274 +#ifdef FM_HAS_TOTAL_DMAS
67275 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
67276 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
67277 +#endif /* FM_HAS_TOTAL_DMAS */
67278 + fman_set_num_of_open_dmas(bmi_rg,
67279 + hardwarePortId,
67280 + numOfOpenDmas,
67281 + numOfExtraOpenDmas,
67282 + totalNumDmas);
67283 + }
67284 +
67285 + return E_OK;
67286 +}
67287 +
67288 +#if (DPAA_VERSION >= 11)
67289 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
67290 + e_FmPortType portType,
67291 + uint8_t portId,
67292 + uint16_t relativeProfile)
67293 +{
67294 + t_Fm *p_Fm;
67295 + t_FmSp *p_FmPcdSp;
67296 + uint8_t swPortIndex=0, hardwarePortId;
67297 +
67298 + ASSERT_COND(h_Fm);
67299 + p_Fm = (t_Fm*)h_Fm;
67300 +
67301 + hardwarePortId = SwPortIdToHwPortId(portType,
67302 + portId,
67303 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67304 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67305 + ASSERT_COND(hardwarePortId);
67306 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67307 +
67308 + p_FmPcdSp = p_Fm->p_FmSp;
67309 + ASSERT_COND(p_FmPcdSp);
67310 +
67311 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67312 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
67313 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
67314 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
67315 +
67316 + return E_OK;
67317 +}
67318 +
67319 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
67320 + e_FmPortType portType,
67321 + uint8_t portId,
67322 + uint16_t relativeProfile,
67323 + uint16_t *p_AbsoluteId)
67324 +{
67325 + t_Fm *p_Fm;
67326 + t_FmSp *p_FmPcdSp;
67327 + uint8_t swPortIndex=0, hardwarePortId;
67328 + t_Error err;
67329 +
67330 + ASSERT_COND(h_Fm);
67331 + p_Fm = (t_Fm*)h_Fm;
67332 +
67333 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
67334 + if (err != E_OK)
67335 + return err;
67336 +
67337 + hardwarePortId = SwPortIdToHwPortId(portType,
67338 + portId,
67339 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67340 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67341 + ASSERT_COND(hardwarePortId);
67342 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67343 +
67344 + p_FmPcdSp = p_Fm->p_FmSp;
67345 + ASSERT_COND(p_FmPcdSp);
67346 +
67347 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
67348 +
67349 + return E_OK;
67350 +}
67351 +#endif /* (DPAA_VERSION >= 11) */
67352 +
67353 +static t_Error InitFmDma(t_Fm *p_Fm)
67354 +{
67355 + t_Error err;
67356 +
67357 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
67358 + if (err != E_OK)
67359 + return err;
67360 +
67361 + /* Allocate MURAM for CAM */
67362 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67363 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
67364 + DMA_CAM_ALIGN));
67365 + if (!p_Fm->camBaseAddr)
67366 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67367 +
67368 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67369 + 0,
67370 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
67371 +
67372 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
67373 + {
67374 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
67375 +
67376 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
67377 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
67378 + 64));
67379 + if (!p_Fm->camBaseAddr)
67380 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
67381 +
67382 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
67383 + 0,
67384 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
67385 +
67386 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
67387 + {
67388 + case (8):
67389 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
67390 + break;
67391 + case (16):
67392 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
67393 + break;
67394 + case (24):
67395 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
67396 + break;
67397 + case (32):
67398 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
67399 + break;
67400 + default:
67401 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
67402 + }
67403 + }
67404 +
67405 + p_Fm->p_FmDriverParam->cam_base_addr =
67406 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
67407 +
67408 + return E_OK;
67409 +}
67410 +
67411 +static t_Error InitFmFpm(t_Fm *p_Fm)
67412 +{
67413 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
67414 +}
67415 +
67416 +static t_Error InitFmBmi(t_Fm *p_Fm)
67417 +{
67418 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
67419 +}
67420 +
67421 +static t_Error InitFmQmi(t_Fm *p_Fm)
67422 +{
67423 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
67424 +}
67425 +
67426 +static t_Error InitGuestMode(t_Fm *p_Fm)
67427 +{
67428 + t_Error err = E_OK;
67429 + int i;
67430 + t_FmIpcMsg msg;
67431 + t_FmIpcReply reply;
67432 + uint32_t replyLength;
67433 +
67434 + ASSERT_COND(p_Fm);
67435 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67436 +
67437 + /* build the FM guest partition IPC address */
67438 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
67439 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67440 +
67441 + /* build the FM master partition IPC address */
67442 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
67443 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
67444 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
67445 +
67446 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67447 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67448 +
67449 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
67450 + if (p_Fm->h_IpcSessions[0])
67451 + {
67452 + uint8_t isMasterAlive;
67453 + t_FmIpcParams ipcParams;
67454 +
67455 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
67456 + if (err)
67457 + RETURN_ERROR(MAJOR, err, NO_MSG);
67458 +
67459 + memset(&msg, 0, sizeof(msg));
67460 + memset(&reply, 0, sizeof(reply));
67461 + msg.msgId = FM_MASTER_IS_ALIVE;
67462 + msg.msgBody[0] = p_Fm->guestId;
67463 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67464 + do
67465 + {
67466 + blockingFlag = TRUE;
67467 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67468 + (uint8_t*)&msg,
67469 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
67470 + (uint8_t*)&reply,
67471 + &replyLength,
67472 + IpcMsgCompletionCB,
67473 + p_Fm)) != E_OK)
67474 + REPORT_ERROR(MINOR, err, NO_MSG);
67475 + while (blockingFlag) ;
67476 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67477 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67478 + isMasterAlive = *(uint8_t*)(reply.replyBody);
67479 + } while (!isMasterAlive);
67480 +
67481 + /* read FM parameters and save */
67482 + memset(&msg, 0, sizeof(msg));
67483 + memset(&reply, 0, sizeof(reply));
67484 + msg.msgId = FM_GET_PARAMS;
67485 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67486 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67487 + (uint8_t*)&msg,
67488 + sizeof(msg.msgId),
67489 + (uint8_t*)&reply,
67490 + &replyLength,
67491 + NULL,
67492 + NULL)) != E_OK)
67493 + RETURN_ERROR(MAJOR, err, NO_MSG);
67494 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
67495 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67496 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
67497 +
67498 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
67499 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
67500 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
67501 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
67502 + }
67503 + else
67504 + {
67505 + DBG(WARNING, ("FM Guest mode - without IPC"));
67506 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
67507 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
67508 + if (p_Fm->baseAddr)
67509 + {
67510 + fman_get_revision(p_Fm->p_FmFpmRegs,
67511 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67512 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67513 +
67514 + }
67515 + }
67516 +
67517 +#if (DPAA_VERSION >= 11)
67518 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67519 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67520 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67521 +#endif /* (DPAA_VERSION >= 11) */
67522 +
67523 + /* General FM driver initialization */
67524 + if (p_Fm->baseAddr)
67525 + p_Fm->fmMuramPhysBaseAddr =
67526 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67527 +
67528 + XX_Free(p_Fm->p_FmDriverParam);
67529 + p_Fm->p_FmDriverParam = NULL;
67530 +
67531 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
67532 + (p_Fm->h_IpcSessions[0]))
67533 + {
67534 + FM_DisableRamsEcc(p_Fm);
67535 + FmMuramClear(p_Fm->h_FmMuram);
67536 + FM_EnableRamsEcc(p_Fm);
67537 + }
67538 +
67539 + return E_OK;
67540 +}
67541 +
67542 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
67543 +{
67544 + switch (exception) {
67545 + case e_FM_EX_DMA_BUS_ERROR:
67546 + return E_FMAN_EX_DMA_BUS_ERROR;
67547 + case e_FM_EX_DMA_READ_ECC:
67548 + return E_FMAN_EX_DMA_READ_ECC;
67549 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
67550 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
67551 + case e_FM_EX_DMA_FM_WRITE_ECC:
67552 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
67553 + case e_FM_EX_FPM_STALL_ON_TASKS:
67554 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
67555 + case e_FM_EX_FPM_SINGLE_ECC:
67556 + return E_FMAN_EX_FPM_SINGLE_ECC;
67557 + case e_FM_EX_FPM_DOUBLE_ECC:
67558 + return E_FMAN_EX_FPM_DOUBLE_ECC;
67559 + case e_FM_EX_QMI_SINGLE_ECC:
67560 + return E_FMAN_EX_QMI_SINGLE_ECC;
67561 + case e_FM_EX_QMI_DOUBLE_ECC:
67562 + return E_FMAN_EX_QMI_DOUBLE_ECC;
67563 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
67564 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
67565 + case e_FM_EX_BMI_LIST_RAM_ECC:
67566 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
67567 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
67568 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
67569 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
67570 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
67571 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
67572 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
67573 + case e_FM_EX_IRAM_ECC:
67574 + return E_FMAN_EX_IRAM_ECC;
67575 + case e_FM_EX_MURAM_ECC:
67576 + return E_FMAN_EX_MURAM_ECC;
67577 + default:
67578 + return E_FMAN_EX_DMA_BUS_ERROR;
67579 + }
67580 +}
67581 +
67582 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
67583 +{
67584 + switch (type)
67585 + {
67586 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
67587 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
67588 + CHECK_PORT_ID_OH_PORTS(relativePortId);
67589 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
67590 + case (e_FM_PORT_TYPE_RX):
67591 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67592 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67593 + case (e_FM_PORT_TYPE_RX_10G):
67594 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67595 + * This is the reason why the 1G port offset is used.
67596 + */
67597 + if (majorRev == 6 && minorRev == 4)
67598 + {
67599 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
67600 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
67601 + }
67602 + else
67603 + {
67604 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
67605 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
67606 + }
67607 + case (e_FM_PORT_TYPE_TX):
67608 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67609 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67610 + case (e_FM_PORT_TYPE_TX_10G):
67611 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
67612 + * This is the reason why the 1G port offset is used.
67613 + */
67614 + if (majorRev == 6 && minorRev == 4)
67615 + {
67616 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
67617 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
67618 + }
67619 + else
67620 + {
67621 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
67622 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
67623 + }
67624 + default:
67625 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
67626 + return 0;
67627 + }
67628 +}
67629 +
67630 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
67631 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
67632 +{
67633 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67634 +
67635 + DECLARE_DUMP;
67636 +
67637 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
67638 +
67639 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67640 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
67641 + p_Fm->baseAddr), E_INVALID_OPERATION);
67642 +
67643 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
67644 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
67645 +
67646 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
67647 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
67648 +
67649 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
67650 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
67651 +
67652 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
67653 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
67654 +
67655 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
67656 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
67657 +
67658 + return E_OK;
67659 +}
67660 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
67661 +
67662 +
67663 +/*****************************************************************************/
67664 +/* API Init unit functions */
67665 +/*****************************************************************************/
67666 +t_Handle FM_Config(t_FmParams *p_FmParam)
67667 +{
67668 + t_Fm *p_Fm;
67669 + uint8_t i;
67670 + uintptr_t baseAddr;
67671 +
67672 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
67673 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
67674 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
67675 + E_INVALID_VALUE, NULL);
67676 +
67677 + baseAddr = p_FmParam->baseAddr;
67678 +
67679 + /* Allocate FM structure */
67680 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
67681 + if (!p_Fm)
67682 + {
67683 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
67684 + return NULL;
67685 + }
67686 + memset(p_Fm, 0, sizeof(t_Fm));
67687 +
67688 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
67689 + if (!p_Fm->p_FmStateStruct)
67690 + {
67691 + XX_Free(p_Fm);
67692 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
67693 + return NULL;
67694 + }
67695 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
67696 +
67697 + /* Initialize FM parameters which will be kept by the driver */
67698 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67699 + p_Fm->guestId = p_FmParam->guestId;
67700 +
67701 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
67702 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
67703 +
67704 + /* Allocate the FM driver's parameters structure */
67705 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
67706 + if (!p_Fm->p_FmDriverParam)
67707 + {
67708 + XX_Free(p_Fm->p_FmStateStruct);
67709 + XX_Free(p_Fm);
67710 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
67711 + return NULL;
67712 + }
67713 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
67714 +
67715 +#if (DPAA_VERSION >= 11)
67716 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
67717 + if (!p_Fm->p_FmSp)
67718 + {
67719 + XX_Free(p_Fm->p_FmDriverParam);
67720 + XX_Free(p_Fm->p_FmStateStruct);
67721 + XX_Free(p_Fm);
67722 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
67723 + return NULL;
67724 + }
67725 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
67726 +
67727 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
67728 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
67729 +#endif /* (DPAA_VERSION >= 11) */
67730 +
67731 + /* Initialize FM parameters which will be kept by the driver */
67732 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
67733 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
67734 + p_Fm->h_App = p_FmParam->h_App;
67735 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
67736 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
67737 + p_Fm->f_Exception = p_FmParam->f_Exception;
67738 + p_Fm->f_BusError = p_FmParam->f_BusError;
67739 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
67740 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67741 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
67742 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
67743 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
67744 + p_Fm->baseAddr = baseAddr;
67745 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
67746 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
67747 + p_Fm->hcPortInitialized = FALSE;
67748 + p_Fm->independentMode = FALSE;
67749 +
67750 + p_Fm->h_Spinlock = XX_InitSpinlock();
67751 + if (!p_Fm->h_Spinlock)
67752 + {
67753 + XX_Free(p_Fm->p_FmDriverParam);
67754 + XX_Free(p_Fm->p_FmStateStruct);
67755 + XX_Free(p_Fm);
67756 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
67757 + return NULL;
67758 + }
67759 +
67760 +#if (DPAA_VERSION >= 11)
67761 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
67762 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
67763 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
67764 +#endif /* (DPAA_VERSION >= 11) */
67765 +
67766 + fman_defconfig(p_Fm->p_FmDriverParam,
67767 + !!(p_Fm->guestId == NCSW_MASTER_ID));
67768 +/* overide macros dependent parameters */
67769 +#ifdef FM_PEDANTIC_DMA
67770 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
67771 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
67772 +#endif /* FM_PEDANTIC_DMA */
67773 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67774 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
67775 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67776 +
67777 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
67778 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
67779 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
67780 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
67781 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
67782 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
67783 + p_Fm->firmware.size = p_FmParam->firmware.size;
67784 + if (p_Fm->firmware.size)
67785 + {
67786 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
67787 + if (!p_Fm->firmware.p_Code)
67788 + {
67789 + XX_FreeSpinlock(p_Fm->h_Spinlock);
67790 + XX_Free(p_Fm->p_FmStateStruct);
67791 + XX_Free(p_Fm->p_FmDriverParam);
67792 + XX_Free(p_Fm);
67793 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
67794 + return NULL;
67795 + }
67796 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
67797 + }
67798 +
67799 + if (p_Fm->guestId != NCSW_MASTER_ID)
67800 + return p_Fm;
67801 +
67802 + /* read revision */
67803 + /* Chip dependent, will be configured in Init */
67804 + fman_get_revision(p_Fm->p_FmFpmRegs,
67805 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
67806 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
67807 +
67808 +#ifdef FM_AID_MODE_NO_TNUM_SW005
67809 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
67810 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
67811 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
67812 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
67813 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
67814 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
67815 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
67816 +
67817 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
67818 + p_Fm->p_FmStateStruct->totalNumOfTasks =
67819 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
67820 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67821 +
67822 +#ifdef FM_HAS_TOTAL_DMAS
67823 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
67824 +#endif /* FM_HAS_TOTAL_DMAS */
67825 +#if (DPAA_VERSION < 11)
67826 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
67827 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
67828 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
67829 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
67830 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
67831 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
67832 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
67833 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
67834 +#endif /* (DPAA_VERSION < 11) */
67835 +#ifdef FM_NO_TNUM_AGING
67836 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
67837 +#endif
67838 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
67839 +
67840 + return p_Fm;
67841 +}
67842 +
67843 +/**************************************************************************//**
67844 + @Function FM_Init
67845 +
67846 + @Description Initializes the FM module
67847 +
67848 + @Param[in] h_Fm - FM module descriptor
67849 +
67850 + @Return E_OK on success; Error code otherwise.
67851 +*//***************************************************************************/
67852 +t_Error FM_Init(t_Handle h_Fm)
67853 +{
67854 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67855 + struct fman_cfg *p_FmDriverParam = NULL;
67856 + t_Error err = E_OK;
67857 + int i;
67858 + t_FmRevisionInfo revInfo;
67859 + struct fman_rg fman_rg;
67860 +
67861 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67862 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
67863 +
67864 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
67865 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
67866 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
67867 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
67868 +
67869 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
67870 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
67871 +
67872 + if (p_Fm->guestId != NCSW_MASTER_ID)
67873 + return InitGuestMode(p_Fm);
67874 +
67875 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
67876 + * according to chip. otherwise, we use user's configuration.
67877 + */
67878 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
67879 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
67880 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67881 +
67882 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
67883 +
67884 + p_FmDriverParam = p_Fm->p_FmDriverParam;
67885 +
67886 + FM_GetRevision(p_Fm, &revInfo);
67887 +
67888 + /* clear revision-dependent non existing exception */
67889 +#ifdef FM_NO_DISPATCH_RAM_ECC
67890 + if ((revInfo.majorRev != 4) &&
67891 + (revInfo.majorRev < 6))
67892 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
67893 +#endif /* FM_NO_DISPATCH_RAM_ECC */
67894 +
67895 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
67896 + if (revInfo.majorRev == 4)
67897 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
67898 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
67899 +
67900 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
67901 + if (revInfo.majorRev >= 6)
67902 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
67903 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
67904 +
67905 + FmMuramClear(p_Fm->h_FmMuram);
67906 +
67907 + /* clear CPG */
67908 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
67909 +
67910 + /* add to the default exceptions the user's definitions */
67911 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
67912 +
67913 + /* Reset the FM if required */
67914 + if (p_Fm->resetOnInit)
67915 + {
67916 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67917 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
67918 + RETURN_ERROR(MAJOR, err, NO_MSG);
67919 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67920 +
67921 + if (p_Fm->f_ResetOnInitOverride)
67922 + {
67923 + /* Perform user specific FMan reset */
67924 + p_Fm->f_ResetOnInitOverride(h_Fm);
67925 + }
67926 + else
67927 + {
67928 + /* Perform FMan reset */
67929 + FmReset(h_Fm);
67930 + }
67931 +
67932 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
67933 + {
67934 + fman_resume(p_Fm->p_FmFpmRegs);
67935 + XX_UDelay(100);
67936 + }
67937 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67938 + }
67939 +
67940 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67941 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
67942 + {
67943 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67944 + /* Load FMan-Controller code to IRAM */
67945 +
67946 + ClearIRam(p_Fm);
67947 +
67948 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
67949 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
67950 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
67951 + }
67952 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
67953 +
67954 +#ifdef FM_CAPWAP_SUPPORT
67955 + /* save first 256 byte in MURAM */
67956 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
67957 + if (!p_Fm->resAddr)
67958 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
67959 +
67960 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
67961 +#endif /* FM_CAPWAP_SUPPORT */
67962 +
67963 +#if (DPAA_VERSION >= 11)
67964 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
67965 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
67966 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
67967 +#endif /* (DPAA_VERSION >= 11) */
67968 +
67969 + /* General FM driver initialization */
67970 + p_Fm->fmMuramPhysBaseAddr =
67971 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
67972 +
67973 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
67974 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
67975 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67976 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
67977 +
67978 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
67979 +
67980 + /**********************/
67981 + /* Init DMA Registers */
67982 + /**********************/
67983 + err = InitFmDma(p_Fm);
67984 + if (err != E_OK)
67985 + {
67986 + FreeInitResources(p_Fm);
67987 + RETURN_ERROR(MAJOR, err, NO_MSG);
67988 + }
67989 +
67990 + /**********************/
67991 + /* Init FPM Registers */
67992 + /**********************/
67993 + err = InitFmFpm(p_Fm);
67994 + if (err != E_OK)
67995 + {
67996 + FreeInitResources(p_Fm);
67997 + RETURN_ERROR(MAJOR, err, NO_MSG);
67998 + }
67999 +
68000 + /* define common resources */
68001 + /* allocate MURAM for FIFO according to total size */
68002 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
68003 + p_Fm->p_FmStateStruct->totalFifoSize,
68004 + BMI_FIFO_ALIGN));
68005 + if (!p_Fm->fifoBaseAddr)
68006 + {
68007 + FreeInitResources(p_Fm);
68008 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
68009 + }
68010 +
68011 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
68012 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
68013 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
68014 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
68015 +
68016 + /**********************/
68017 + /* Init BMI Registers */
68018 + /**********************/
68019 + err = InitFmBmi(p_Fm);
68020 + if (err != E_OK)
68021 + {
68022 + FreeInitResources(p_Fm);
68023 + RETURN_ERROR(MAJOR, err, NO_MSG);
68024 + }
68025 +
68026 + /**********************/
68027 + /* Init QMI Registers */
68028 + /**********************/
68029 + err = InitFmQmi(p_Fm);
68030 + if (err != E_OK)
68031 + {
68032 + FreeInitResources(p_Fm);
68033 + RETURN_ERROR(MAJOR, err, NO_MSG);
68034 + }
68035 +
68036 + /* build the FM master partition IPC address */
68037 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
68038 + {
68039 + FreeInitResources(p_Fm);
68040 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
68041 + }
68042 +
68043 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
68044 + if (err)
68045 + {
68046 + FreeInitResources(p_Fm);
68047 + RETURN_ERROR(MAJOR, err, NO_MSG);
68048 + }
68049 +
68050 + /* Register the FM interrupts handlers */
68051 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
68052 + {
68053 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
68054 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
68055 + }
68056 +
68057 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
68058 + {
68059 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
68060 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
68061 + }
68062 +
68063 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
68064 + if (err != E_OK)
68065 + return err; /* FIXME */
68066 +
68067 + EnableTimeStamp(p_Fm);
68068 +
68069 + if (p_Fm->firmware.p_Code)
68070 + {
68071 + XX_Free(p_Fm->firmware.p_Code);
68072 + p_Fm->firmware.p_Code = NULL;
68073 + }
68074 +
68075 + XX_Free(p_Fm->p_FmDriverParam);
68076 + p_Fm->p_FmDriverParam = NULL;
68077 +
68078 + return E_OK;
68079 +}
68080 +
68081 +/**************************************************************************//**
68082 + @Function FM_Free
68083 +
68084 + @Description Frees all resources that were assigned to FM module.
68085 +
68086 + Calling this routine invalidates the descriptor.
68087 +
68088 + @Param[in] h_Fm - FM module descriptor
68089 +
68090 + @Return E_OK on success; Error code otherwise.
68091 +*//***************************************************************************/
68092 +t_Error FM_Free(t_Handle h_Fm)
68093 +{
68094 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68095 + struct fman_rg fman_rg;
68096 +
68097 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68098 +
68099 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68100 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68101 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68102 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68103 +
68104 + if (p_Fm->guestId != NCSW_MASTER_ID)
68105 + {
68106 +#if (DPAA_VERSION >= 11)
68107 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68108 +
68109 + if (p_Fm->p_FmSp)
68110 + {
68111 + XX_Free(p_Fm->p_FmSp);
68112 + p_Fm->p_FmSp = NULL;
68113 + }
68114 +#endif /* (DPAA_VERSION >= 11) */
68115 +
68116 + if (p_Fm->fmModuleName[0] != 0)
68117 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68118 +
68119 + if (!p_Fm->recoveryMode)
68120 + XX_Free(p_Fm->p_FmStateStruct);
68121 +
68122 + XX_Free(p_Fm);
68123 +
68124 + return E_OK;
68125 + }
68126 +
68127 + fman_free_resources(&fman_rg);
68128 +
68129 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
68130 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
68131 +
68132 + if (p_Fm->p_FmStateStruct)
68133 + {
68134 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
68135 + {
68136 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
68137 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
68138 + }
68139 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
68140 + {
68141 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
68142 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
68143 + }
68144 + }
68145 +
68146 +#if (DPAA_VERSION >= 11)
68147 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
68148 +
68149 + if (p_Fm->p_FmSp)
68150 + {
68151 + XX_Free(p_Fm->p_FmSp);
68152 + p_Fm->p_FmSp = NULL;
68153 + }
68154 +#endif /* (DPAA_VERSION >= 11) */
68155 +
68156 + if (p_Fm->h_Spinlock)
68157 + XX_FreeSpinlock(p_Fm->h_Spinlock);
68158 +
68159 + if (p_Fm->p_FmDriverParam)
68160 + {
68161 + if (p_Fm->firmware.p_Code)
68162 + XX_Free(p_Fm->firmware.p_Code);
68163 + XX_Free(p_Fm->p_FmDriverParam);
68164 + p_Fm->p_FmDriverParam = NULL;
68165 + }
68166 +
68167 + FreeInitResources(p_Fm);
68168 +
68169 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
68170 + XX_Free(p_Fm->p_FmStateStruct);
68171 +
68172 + XX_Free(p_Fm);
68173 +
68174 + return E_OK;
68175 +}
68176 +
68177 +/*************************************************/
68178 +/* API Advanced Init unit functions */
68179 +/*************************************************/
68180 +
68181 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
68182 +{
68183 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68184 +
68185 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68186 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68187 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68188 +
68189 + p_Fm->resetOnInit = enable;
68190 +
68191 + return E_OK;
68192 +}
68193 +
68194 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
68195 +{
68196 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68197 +
68198 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68199 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68200 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68201 +
68202 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
68203 +
68204 + return E_OK;
68205 +}
68206 +
68207 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
68208 +{
68209 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68210 +
68211 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68212 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68213 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68214 +
68215 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
68216 +
68217 + return E_OK;
68218 +}
68219 +
68220 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
68221 +{
68222 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68223 + enum fman_dma_cache_override fsl_cache_override;
68224 +
68225 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68226 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68227 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68228 +
68229 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
68230 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
68231 +
68232 + return E_OK;
68233 +}
68234 +
68235 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
68236 +{
68237 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68238 +
68239 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68240 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68241 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68242 +
68243 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
68244 +
68245 + return E_OK;
68246 +}
68247 +
68248 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
68249 +{
68250 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68251 + enum fman_dma_aid_mode fsl_aid_mode;
68252 +
68253 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68254 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68255 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68256 +
68257 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
68258 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
68259 +
68260 + return E_OK;
68261 +}
68262 +
68263 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
68264 +{
68265 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68266 +
68267 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68268 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68269 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68270 +
68271 +#if (DPAA_VERSION >= 11)
68272 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68273 +#else
68274 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
68275 +
68276 + return E_OK;
68277 +#endif /* (DPAA_VERSION >= 11) */
68278 +}
68279 +
68280 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
68281 +{
68282 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68283 +
68284 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68285 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68286 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68287 +
68288 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
68289 +
68290 + return E_OK;
68291 +}
68292 +
68293 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
68294 +{
68295 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68296 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
68297 +
68298 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68299 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68300 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68301 +
68302 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
68303 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
68304 +
68305 + return E_OK;
68306 +}
68307 +
68308 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
68309 +{
68310 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68311 +
68312 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68313 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68314 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68315 +
68316 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
68317 +
68318 + return E_OK;
68319 +}
68320 +
68321 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
68322 +{
68323 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68324 + enum fman_dma_emergency_level fsl_dma_emer;
68325 +
68326 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68327 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68328 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68329 +
68330 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
68331 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
68332 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
68333 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
68334 +
68335 + return E_OK;
68336 +}
68337 +
68338 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
68339 +{
68340 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68341 +
68342 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68343 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68344 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68345 +
68346 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
68347 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
68348 +
68349 + return E_OK;
68350 +}
68351 +
68352 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
68353 +{
68354 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68355 + enum fman_dma_err fsl_dma_err;
68356 +
68357 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68358 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68359 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68360 +
68361 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
68362 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
68363 +
68364 + return E_OK;
68365 +}
68366 +
68367 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
68368 +{
68369 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68370 + enum fman_catastrophic_err fsl_catastrophic_err;
68371 +
68372 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68373 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68374 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68375 +
68376 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
68377 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
68378 +
68379 + return E_OK;
68380 +}
68381 +
68382 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
68383 +{
68384 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68385 +
68386 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68387 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68388 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68389 +
68390 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68391 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68392 +
68393 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
68394 +
68395 + return E_OK;
68396 +}
68397 +
68398 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
68399 +{
68400 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68401 +
68402 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
68403 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68404 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68405 +
68406 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68407 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68408 +
68409 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
68410 +
68411 + return E_OK;
68412 +}
68413 +
68414 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
68415 +{
68416 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68417 +
68418 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68419 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68420 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68421 +
68422 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
68423 +
68424 + return E_OK;
68425 +}
68426 +
68427 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
68428 +{
68429 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68430 +
68431 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68432 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68433 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68434 +
68435 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68436 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68437 +
68438 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
68439 +
68440 + return E_OK;
68441 +}
68442 +
68443 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
68444 +{
68445 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68446 + uint32_t bitMask = 0;
68447 +
68448 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68449 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68450 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68451 +
68452 + GET_EXCEPTION_FLAG(bitMask, exception);
68453 + if (bitMask)
68454 + {
68455 + if (enable)
68456 + p_Fm->userSetExceptions |= bitMask;
68457 + else
68458 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
68459 + }
68460 + else
68461 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
68462 +
68463 + return E_OK;
68464 +}
68465 +
68466 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
68467 +{
68468 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68469 +
68470 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68471 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68472 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68473 +
68474 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
68475 +
68476 + return E_OK;
68477 +}
68478 +
68479 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
68480 +{
68481 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68482 +
68483 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68484 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68485 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68486 +
68487 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
68488 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
68489 +
68490 + return E_OK;
68491 +}
68492 +
68493 +/****************************************************/
68494 +/* Hidden-DEBUG Only API */
68495 +/****************************************************/
68496 +
68497 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
68498 +{
68499 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68500 +
68501 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68502 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68503 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68504 +
68505 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
68506 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
68507 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
68508 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
68509 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
68510 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
68511 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
68512 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
68513 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
68514 +
68515 + return E_OK;
68516 +}
68517 +
68518 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
68519 +{
68520 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68521 +
68522 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68523 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68524 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68525 +
68526 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
68527 +
68528 + return E_OK;
68529 +}
68530 +
68531 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68532 +
68533 +{
68534 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68535 +
68536 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68537 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68538 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68539 +
68540 +#if (DPAA_VERSION >= 11)
68541 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68542 +#else
68543 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68544 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68545 +
68546 + return E_OK;
68547 +#endif
68548 +}
68549 +
68550 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68551 +{
68552 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68553 +
68554 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68555 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68556 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68557 +
68558 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68559 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68560 +
68561 + return E_OK;
68562 +}
68563 +
68564 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
68565 +{
68566 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68567 +
68568 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68569 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68570 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68571 +
68572 +#if (DPAA_VERSION >= 11)
68573 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
68574 +#else
68575 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
68576 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
68577 +
68578 + return E_OK;
68579 +#endif
68580 +}
68581 +
68582 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
68583 +{
68584 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68585 +
68586 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68587 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68588 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68589 +
68590 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
68591 +
68592 + return E_OK;
68593 +}
68594 +
68595 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
68596 +{
68597 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68598 +
68599 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68600 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68601 +UNUSED(p_Fm);
68602 +
68603 + return E_OK;
68604 +}
68605 +
68606 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
68607 +{
68608 + t_Fm* p_Fm = (t_Fm*)h_Fm;
68609 + if (p_Params->setParams.type & UPDATE_FM_CLD)
68610 + {
68611 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
68612 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
68613 + }
68614 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
68615 + {
68616 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
68617 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
68618 + }
68619 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
68620 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
68621 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
68622 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
68623 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
68624 + {
68625 + if (p_Params->setParams.sleep)
68626 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68627 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
68628 + else
68629 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
68630 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
68631 + }
68632 + if (p_Params->getParams.type & GET_FM_CLD)
68633 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
68634 + if (p_Params->getParams.type & GET_FMQM_GS)
68635 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
68636 + if (p_Params->getParams.type & GET_FM_NPI)
68637 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
68638 + if (p_Params->getParams.type & GET_FMFP_EXTC)
68639 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
68640 + return E_OK;
68641 +}
68642 +
68643 +
68644 +/****************************************************/
68645 +/* API Run-time Control uint functions */
68646 +/****************************************************/
68647 +void FM_EventIsr(t_Handle h_Fm)
68648 +{
68649 +#define FM_M_CALL_1G_MAC_ISR(_id) \
68650 + { \
68651 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
68652 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
68653 + else \
68654 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].h_SrcHandle);\
68655 + }
68656 +#define FM_M_CALL_10G_MAC_ISR(_id) \
68657 + { \
68658 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
68659 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
68660 + else \
68661 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].h_SrcHandle);\
68662 + }
68663 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68664 + uint32_t pending, event;
68665 + struct fman_fpm_regs *fpm_rg;
68666 +
68667 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
68668 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68669 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68670 +
68671 + fpm_rg = p_Fm->p_FmFpmRegs;
68672 +
68673 + /* normal interrupts */
68674 + pending = fman_get_normal_pending(fpm_rg);
68675 + if (!pending)
68676 + return;
68677 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
68678 + {
68679 + t_FmGetSetParams fmGetSetParams;
68680 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
68681 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
68682 + fmGetSetParams.setParams.sleep = 0;
68683 + FmGetSetParams(h_Fm, &fmGetSetParams);
68684 + }
68685 + if (pending & INTR_EN_QMI)
68686 + QmiEvent(p_Fm);
68687 + if (pending & INTR_EN_PRS)
68688 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
68689 + if (pending & INTR_EN_PLCR)
68690 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
68691 + if (pending & INTR_EN_TMR)
68692 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
68693 +
68694 + /* MAC events may belong to different partitions */
68695 + if (pending & INTR_EN_1G_MAC0)
68696 + FM_M_CALL_1G_MAC_ISR(0);
68697 + if (pending & INTR_EN_1G_MAC1)
68698 + FM_M_CALL_1G_MAC_ISR(1);
68699 + if (pending & INTR_EN_1G_MAC2)
68700 + FM_M_CALL_1G_MAC_ISR(2);
68701 + if (pending & INTR_EN_1G_MAC3)
68702 + FM_M_CALL_1G_MAC_ISR(3);
68703 + if (pending & INTR_EN_1G_MAC4)
68704 + FM_M_CALL_1G_MAC_ISR(4);
68705 + if (pending & INTR_EN_1G_MAC5)
68706 + FM_M_CALL_1G_MAC_ISR(5);
68707 + if (pending & INTR_EN_1G_MAC6)
68708 + FM_M_CALL_1G_MAC_ISR(6);
68709 + if (pending & INTR_EN_1G_MAC7)
68710 + FM_M_CALL_1G_MAC_ISR(7);
68711 + if (pending & INTR_EN_10G_MAC0)
68712 + FM_M_CALL_10G_MAC_ISR(0);
68713 + if (pending & INTR_EN_10G_MAC1)
68714 + FM_M_CALL_10G_MAC_ISR(1);
68715 +
68716 + /* IM port events may belong to different partitions */
68717 + if (pending & INTR_EN_REV0)
68718 + {
68719 + event = fman_get_controller_event(fpm_rg, 0);
68720 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
68721 + /*TODO IPC ISR For Fman Ctrl */
68722 + ASSERT_COND(0);
68723 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
68724 + else
68725 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
68726 +
68727 + }
68728 + if (pending & INTR_EN_REV1)
68729 + {
68730 + event = fman_get_controller_event(fpm_rg, 1);
68731 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
68732 + /*TODO IPC ISR For Fman Ctrl */
68733 + ASSERT_COND(0);
68734 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
68735 + else
68736 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
68737 + }
68738 + if (pending & INTR_EN_REV2)
68739 + {
68740 + event = fman_get_controller_event(fpm_rg, 2);
68741 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
68742 + /*TODO IPC ISR For Fman Ctrl */
68743 + ASSERT_COND(0);
68744 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
68745 + else
68746 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
68747 + }
68748 + if (pending & INTR_EN_REV3)
68749 + {
68750 + event = fman_get_controller_event(fpm_rg, 3);
68751 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
68752 + /*TODO IPC ISR For Fman Ctrl */
68753 + ASSERT_COND(0);
68754 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
68755 + else
68756 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
68757 + }
68758 +#ifdef FM_MACSEC_SUPPORT
68759 + if (pending & INTR_EN_MACSEC_MAC0)
68760 + {
68761 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
68762 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
68763 + else
68764 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
68765 + }
68766 +#endif /* FM_MACSEC_SUPPORT */
68767 +}
68768 +
68769 +t_Error FM_ErrorIsr(t_Handle h_Fm)
68770 +{
68771 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
68772 + { \
68773 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
68774 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
68775 + else \
68776 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].h_SrcHandle);\
68777 + }
68778 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
68779 + { \
68780 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
68781 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
68782 + else \
68783 + p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].f_Isr(p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].h_SrcHandle);\
68784 + }
68785 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68786 + uint32_t pending;
68787 + struct fman_fpm_regs *fpm_rg;
68788 +
68789 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
68790 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68791 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68792 +
68793 + fpm_rg = p_Fm->p_FmFpmRegs;
68794 +
68795 + /* error interrupts */
68796 + pending = fman_get_fpm_error_interrupts(fpm_rg);
68797 + if (!pending)
68798 + return ERROR_CODE(E_EMPTY);
68799 +
68800 + if (pending & ERR_INTR_EN_BMI)
68801 + BmiErrEvent(p_Fm);
68802 + if (pending & ERR_INTR_EN_QMI)
68803 + QmiErrEvent(p_Fm);
68804 + if (pending & ERR_INTR_EN_FPM)
68805 + FpmErrEvent(p_Fm);
68806 + if (pending & ERR_INTR_EN_DMA)
68807 + DmaErrEvent(p_Fm);
68808 + if (pending & ERR_INTR_EN_IRAM)
68809 + IramErrIntr(p_Fm);
68810 + if (pending & ERR_INTR_EN_MURAM)
68811 + MuramErrIntr(p_Fm);
68812 + if (pending & ERR_INTR_EN_PRS)
68813 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
68814 + if (pending & ERR_INTR_EN_PLCR)
68815 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
68816 + if (pending & ERR_INTR_EN_KG)
68817 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
68818 +
68819 + /* MAC events may belong to different partitions */
68820 + if (pending & ERR_INTR_EN_1G_MAC0)
68821 + FM_M_CALL_1G_MAC_ERR_ISR(0);
68822 + if (pending & ERR_INTR_EN_1G_MAC1)
68823 + FM_M_CALL_1G_MAC_ERR_ISR(1);
68824 + if (pending & ERR_INTR_EN_1G_MAC2)
68825 + FM_M_CALL_1G_MAC_ERR_ISR(2);
68826 + if (pending & ERR_INTR_EN_1G_MAC3)
68827 + FM_M_CALL_1G_MAC_ERR_ISR(3);
68828 + if (pending & ERR_INTR_EN_1G_MAC4)
68829 + FM_M_CALL_1G_MAC_ERR_ISR(4);
68830 + if (pending & ERR_INTR_EN_1G_MAC5)
68831 + FM_M_CALL_1G_MAC_ERR_ISR(5);
68832 + if (pending & ERR_INTR_EN_1G_MAC6)
68833 + FM_M_CALL_1G_MAC_ERR_ISR(6);
68834 + if (pending & ERR_INTR_EN_1G_MAC7)
68835 + FM_M_CALL_1G_MAC_ERR_ISR(7);
68836 + if (pending & ERR_INTR_EN_10G_MAC0)
68837 + FM_M_CALL_10G_MAC_ERR_ISR(0);
68838 + if (pending & ERR_INTR_EN_10G_MAC1)
68839 + FM_M_CALL_10G_MAC_ERR_ISR(1);
68840 +
68841 +#ifdef FM_MACSEC_SUPPORT
68842 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
68843 + {
68844 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
68845 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
68846 + else
68847 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
68848 + }
68849 +#endif /* FM_MACSEC_SUPPORT */
68850 +
68851 + return E_OK;
68852 +}
68853 +
68854 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
68855 +{
68856 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68857 + int i;
68858 + uint8_t sum;
68859 + uint8_t hardwarePortId;
68860 + uint8_t weights[64];
68861 + uint8_t weight, maxPercent = 0;
68862 + struct fman_bmi_regs *bmi_rg;
68863 +
68864 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68865 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
68866 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
68867 +
68868 + bmi_rg = p_Fm->p_FmBmiRegs;
68869 +
68870 + memset(weights, 0, (sizeof(uint8_t) * 64));
68871 +
68872 + /* check that all ports add up to 100% */
68873 + sum = 0;
68874 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68875 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
68876 + if (sum != 100)
68877 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
68878 +
68879 + /* find highest percent */
68880 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68881 + {
68882 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
68883 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
68884 + }
68885 +
68886 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
68887 +
68888 + /* calculate weight for each port */
68889 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
68890 + {
68891 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
68892 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
68893 + is not reached, we round up so that:
68894 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
68895 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
68896 + ...
68897 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
68898 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
68899 + weight++;
68900 +
68901 + /* find the location of this port within the register */
68902 + hardwarePortId =
68903 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
68904 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
68905 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68906 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68907 +
68908 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68909 + weights[hardwarePortId] = weight;
68910 + }
68911 +
68912 + fman_set_ports_bandwidth(bmi_rg, weights);
68913 +
68914 + return E_OK;
68915 +}
68916 +
68917 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
68918 +{
68919 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68920 + struct fman_fpm_regs *fpm_rg;
68921 +
68922 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68923 +
68924 + fpm_rg = p_Fm->p_FmFpmRegs;
68925 +
68926 + if (p_Fm->guestId != NCSW_MASTER_ID)
68927 + {
68928 + t_FmIpcMsg msg;
68929 + t_Error err;
68930 +
68931 + memset(&msg, 0, sizeof(msg));
68932 + msg.msgId = FM_ENABLE_RAM_ECC;
68933 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68934 + (uint8_t*)&msg,
68935 + sizeof(msg.msgId),
68936 + NULL,
68937 + NULL,
68938 + NULL,
68939 + NULL);
68940 + if (err != E_OK)
68941 + RETURN_ERROR(MINOR, err, NO_MSG);
68942 + return E_OK;
68943 + }
68944 +
68945 + if (!p_Fm->p_FmStateStruct->internalCall)
68946 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
68947 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68948 +
68949 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
68950 + return E_OK;
68951 + else
68952 + {
68953 + fman_enable_rams_ecc(fpm_rg);
68954 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
68955 + }
68956 +
68957 + return E_OK;
68958 +}
68959 +
68960 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
68961 +{
68962 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68963 + bool explicitDisable = FALSE;
68964 + struct fman_fpm_regs *fpm_rg;
68965 +
68966 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68967 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
68968 +
68969 + fpm_rg = p_Fm->p_FmFpmRegs;
68970 +
68971 + if (p_Fm->guestId != NCSW_MASTER_ID)
68972 + {
68973 + t_Error err;
68974 + t_FmIpcMsg msg;
68975 +
68976 + memset(&msg, 0, sizeof(msg));
68977 + msg.msgId = FM_DISABLE_RAM_ECC;
68978 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68979 + (uint8_t*)&msg,
68980 + sizeof(msg.msgId),
68981 + NULL,
68982 + NULL,
68983 + NULL,
68984 + NULL)) != E_OK)
68985 + RETURN_ERROR(MINOR, err, NO_MSG);
68986 + return E_OK;
68987 + }
68988 +
68989 + if (!p_Fm->p_FmStateStruct->internalCall)
68990 + explicitDisable = TRUE;
68991 + p_Fm->p_FmStateStruct->internalCall = FALSE;
68992 +
68993 + /* if rams are already disabled, or if rams were explicitly enabled and are
68994 + currently called indirectly (not explicitly), ignore this call. */
68995 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
68996 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
68997 + return E_OK;
68998 + else
68999 + {
69000 + if (p_Fm->p_FmStateStruct->explicitEnable)
69001 + /* This is the case were both explicit are TRUE.
69002 + Turn off this flag for cases were following ramsEnable
69003 + routines are called */
69004 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
69005 +
69006 + fman_enable_rams_ecc(fpm_rg);
69007 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
69008 + }
69009 +
69010 + return E_OK;
69011 +}
69012 +
69013 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
69014 +{
69015 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69016 + uint32_t bitMask = 0;
69017 + enum fman_exceptions fslException;
69018 + struct fman_rg fman_rg;
69019 +
69020 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69021 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69022 +
69023 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69024 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69025 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69026 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69027 +
69028 + GET_EXCEPTION_FLAG(bitMask, exception);
69029 + if (bitMask)
69030 + {
69031 + if (enable)
69032 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
69033 + else
69034 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
69035 +
69036 + fslException = FmanExceptionTrans(exception);
69037 +
69038 + return (t_Error)fman_set_exception(&fman_rg,
69039 + fslException,
69040 + enable);
69041 + }
69042 + else
69043 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
69044 +
69045 + return E_OK;
69046 +}
69047 +
69048 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
69049 +{
69050 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69051 +
69052 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
69053 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
69054 +
69055 + return E_OK;
69056 +}
69057 +
69058 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
69059 +{
69060 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69061 + t_FMIramRegs *p_Iram;
69062 + uint32_t revInfo;
69063 +
69064 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69065 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
69066 +
69067 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69068 + p_Fm->h_IpcSessions[0])
69069 + {
69070 + t_Error err;
69071 + t_FmIpcMsg msg;
69072 + t_FmIpcReply reply;
69073 + uint32_t replyLength;
69074 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
69075 +
69076 + memset(&msg, 0, sizeof(msg));
69077 + memset(&reply, 0, sizeof(reply));
69078 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
69079 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
69080 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69081 + (uint8_t*)&msg,
69082 + sizeof(msg.msgId),
69083 + (uint8_t*)&reply,
69084 + &replyLength,
69085 + NULL,
69086 + NULL)) != E_OK)
69087 + RETURN_ERROR(MINOR, err, NO_MSG);
69088 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
69089 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69090 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
69091 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
69092 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
69093 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
69094 + return (t_Error)(reply.error);
69095 + }
69096 + else if (p_Fm->guestId != NCSW_MASTER_ID)
69097 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
69098 + ("running in guest-mode without IPC!"));
69099 +
69100 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
69101 + WRITE_UINT32(p_Iram->iadd, 0x4);
69102 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
69103 + revInfo = GET_UINT32(p_Iram->idata);
69104 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
69105 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
69106 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
69107 +
69108 + return E_OK;
69109 +}
69110 +
69111 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
69112 +{
69113 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69114 + t_Error err;
69115 + uint32_t counterValue;
69116 + struct fman_rg fman_rg;
69117 + enum fman_counters fsl_counter;
69118 +
69119 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
69120 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
69121 +
69122 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69123 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69124 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69125 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69126 +
69127 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69128 + !p_Fm->baseAddr &&
69129 + p_Fm->h_IpcSessions[0])
69130 + {
69131 + t_FmIpcMsg msg;
69132 + t_FmIpcReply reply;
69133 + uint32_t replyLength, outCounter;
69134 +
69135 + memset(&msg, 0, sizeof(msg));
69136 + memset(&reply, 0, sizeof(reply));
69137 + msg.msgId = FM_GET_COUNTER;
69138 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
69139 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
69140 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69141 + (uint8_t*)&msg,
69142 + sizeof(msg.msgId) +sizeof(counterValue),
69143 + (uint8_t*)&reply,
69144 + &replyLength,
69145 + NULL,
69146 + NULL);
69147 + if (err != E_OK)
69148 + {
69149 + REPORT_ERROR(MAJOR, err, NO_MSG);
69150 + return 0;
69151 + }
69152 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
69153 + {
69154 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69155 + return 0;
69156 + }
69157 +
69158 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
69159 + return outCounter;
69160 + }
69161 + else if (!p_Fm->baseAddr)
69162 + {
69163 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
69164 + return 0;
69165 + }
69166 +
69167 + /* When applicable (when there is an 'enable counters' bit,
69168 + check that counters are enabled */
69169 + switch (counter)
69170 + {
69171 + case (e_FM_COUNTERS_DEQ_1):
69172 + case (e_FM_COUNTERS_DEQ_2):
69173 + case (e_FM_COUNTERS_DEQ_3):
69174 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
69175 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
69176 + {
69177 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
69178 + return 0;
69179 + }
69180 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
69181 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
69182 + case (e_FM_COUNTERS_DEQ_0):
69183 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
69184 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
69185 + case (e_FM_COUNTERS_DEQ_FROM_FD):
69186 + case (e_FM_COUNTERS_DEQ_CONFIRM):
69187 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
69188 + {
69189 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
69190 + return 0;
69191 + }
69192 + break;
69193 + default:
69194 + break;
69195 + }
69196 +
69197 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69198 + return fman_get_counter(&fman_rg, fsl_counter);
69199 +}
69200 +
69201 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
69202 +{
69203 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69204 + struct fman_rg fman_rg;
69205 + enum fman_counters fsl_counter;
69206 +
69207 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69208 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69209 +
69210 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69211 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69212 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69213 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69214 +
69215 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
69216 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
69217 +}
69218 +
69219 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
69220 +{
69221 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69222 + struct fman_dma_regs *dma_rg;
69223 +
69224 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69225 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69226 +
69227 + dma_rg = p_Fm->p_FmDmaRegs;
69228 +
69229 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
69230 +}
69231 +
69232 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
69233 +{
69234 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69235 + struct fman_dma_regs *dma_rg;
69236 +
69237 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69238 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69239 +
69240 + dma_rg = p_Fm->p_FmDmaRegs;
69241 +
69242 + fman_set_dma_ext_bus_pri(dma_rg, pri);
69243 +}
69244 +
69245 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
69246 +{
69247 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69248 + uint32_t dmaStatus;
69249 + struct fman_dma_regs *dma_rg;
69250 +
69251 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69252 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69253 +
69254 + dma_rg = p_Fm->p_FmDmaRegs;
69255 +
69256 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
69257 + !p_Fm->baseAddr &&
69258 + p_Fm->h_IpcSessions[0])
69259 + {
69260 + t_FmIpcDmaStatus ipcDmaStatus;
69261 + t_FmIpcMsg msg;
69262 + t_FmIpcReply reply;
69263 + t_Error err;
69264 + uint32_t replyLength;
69265 +
69266 + memset(&msg, 0, sizeof(msg));
69267 + memset(&reply, 0, sizeof(reply));
69268 + msg.msgId = FM_DMA_STAT;
69269 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
69270 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69271 + (uint8_t*)&msg,
69272 + sizeof(msg.msgId),
69273 + (uint8_t*)&reply,
69274 + &replyLength,
69275 + NULL,
69276 + NULL);
69277 + if (err != E_OK)
69278 + {
69279 + REPORT_ERROR(MINOR, err, NO_MSG);
69280 + return;
69281 + }
69282 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
69283 + {
69284 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69285 + return;
69286 + }
69287 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
69288 +
69289 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
69290 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
69291 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
69292 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
69293 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
69294 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
69295 + return;
69296 + }
69297 + else if (!p_Fm->baseAddr)
69298 + {
69299 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
69300 + ("Either IPC or 'baseAddress' is required!"));
69301 + return;
69302 + }
69303 +
69304 + dmaStatus = fman_get_dma_status(dma_rg);
69305 +
69306 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
69307 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
69308 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69309 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
69310 + else
69311 + {
69312 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
69313 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
69314 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
69315 + }
69316 +}
69317 +
69318 +void FM_Resume(t_Handle h_Fm)
69319 +{
69320 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69321 + struct fman_fpm_regs *fpm_rg;
69322 +
69323 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
69324 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69325 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69326 +
69327 + fpm_rg = p_Fm->p_FmFpmRegs;
69328 +
69329 + fman_resume(fpm_rg);
69330 +}
69331 +
69332 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
69333 + fmSpecialOperations_t spOper,
69334 + uint8_t *p_SpOperCoding)
69335 +{
69336 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69337 + t_FmCtrlCodeRevisionInfo revInfo;
69338 + t_Error err;
69339 +
69340 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69341 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69342 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
69343 +
69344 + if (!spOper)
69345 + {
69346 + *p_SpOperCoding = 0;
69347 + return E_OK;
69348 + }
69349 +
69350 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
69351 + {
69352 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
69353 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
69354 + }
69355 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
69356 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
69357 +
69358 + switch (spOper)
69359 + {
69360 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
69361 + *p_SpOperCoding = 9;
69362 + break;
69363 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
69364 + *p_SpOperCoding = 10;
69365 + break;
69366 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
69367 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69368 + *p_SpOperCoding = 5;
69369 + break;
69370 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
69371 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
69372 + *p_SpOperCoding = 6;
69373 + break;
69374 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
69375 + *p_SpOperCoding = 3;
69376 + break;
69377 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
69378 + *p_SpOperCoding = 1;
69379 + break;
69380 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
69381 + *p_SpOperCoding = 12;
69382 + break;
69383 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
69384 + *p_SpOperCoding = 4;
69385 + break;
69386 + case (FM_SP_OP_IPSEC):
69387 + *p_SpOperCoding = 2;
69388 + break;
69389 + case (FM_SP_OP_DCL4C):
69390 + *p_SpOperCoding = 7;
69391 + break;
69392 + case (FM_SP_OP_CLEAR_RPD):
69393 + *p_SpOperCoding = 8;
69394 + break;
69395 + default:
69396 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
69397 + }
69398 +
69399 + return E_OK;
69400 +}
69401 +
69402 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
69403 +{
69404 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69405 + t_FmTrbRegs *p_MonRegs;
69406 + uint8_t i;
69407 +
69408 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69409 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69410 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69411 +
69412 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69413 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
69414 +
69415 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69416 + {
69417 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69418 +
69419 + /* Reset control registers */
69420 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
69421 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
69422 +
69423 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
69424 + counter #2 counts all stalls in risc - other stall*/
69425 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
69426 +
69427 + /* Enable monitoring */
69428 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
69429 + }
69430 +
69431 + return E_OK;
69432 +}
69433 +
69434 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
69435 +{
69436 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69437 + t_FmTrbRegs *p_MonRegs;
69438 + uint8_t i;
69439 +
69440 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69441 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69442 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69443 +
69444 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
69445 + {
69446 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
69447 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
69448 + }
69449 +
69450 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
69451 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
69452 +
69453 + return E_OK;
69454 +}
69455 +
69456 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
69457 +{
69458 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69459 + t_FmTrbRegs *p_MonRegs;
69460 + uint64_t clkCnt, utilValue, effValue;
69461 +
69462 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69463 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69464 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69465 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
69466 +
69467 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
69468 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
69469 +
69470 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
69471 +
69472 + clkCnt = (uint64_t)
69473 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
69474 +
69475 + utilValue = (uint64_t)
69476 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
69477 +
69478 + effValue = (uint64_t)
69479 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
69480 +
69481 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
69482 + if (clkCnt != utilValue)
69483 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
69484 + else
69485 + p_Mon->percentCnt[1] = 0;
69486 +
69487 + return E_OK;
69488 +}
69489 +
69490 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
69491 +{
69492 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69493 +
69494 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
69495 +
69496 + return (p_Fm->h_FmMuram);
69497 +}
69498 +
69499 +/****************************************************/
69500 +/* Hidden-DEBUG Only API */
69501 +/****************************************************/
69502 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
69503 +{
69504 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69505 + enum fman_exceptions fslException;
69506 + struct fman_rg fman_rg;
69507 +
69508 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69509 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
69510 +
69511 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69512 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69513 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69514 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69515 +
69516 + switch (exception)
69517 + {
69518 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69519 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
69520 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69521 + break;
69522 + case e_FM_EX_QMI_SINGLE_ECC:
69523 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69524 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
69525 +
69526 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
69527 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69528 + break;
69529 + case e_FM_EX_QMI_DOUBLE_ECC:
69530 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
69531 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69532 + break;
69533 + case e_FM_EX_BMI_LIST_RAM_ECC:
69534 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
69535 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69536 + break;
69537 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69538 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
69539 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69540 + break;
69541 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69542 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
69543 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69544 + break;
69545 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69546 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
69547 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
69548 + break;
69549 + default:
69550 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
69551 + }
69552 +
69553 + fslException = FmanExceptionTrans(exception);
69554 + fman_force_intr (&fman_rg, fslException);
69555 +
69556 + return E_OK;
69557 +}
69558 +
69559 +t_Handle FmGetPcd(t_Handle h_Fm)
69560 +{
69561 + return ((t_Fm*)h_Fm)->h_Pcd;
69562 +}
69563 +#if (DPAA_VERSION >= 11)
69564 +extern void *g_MemacRegs;
69565 +void fm_clk_down(void);
69566 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
69567 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
69568 +{
69569 + int macId;
69570 + uint32_t event, rcr;
69571 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69572 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69573 + rcr |= 0x04000000;
69574 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69575 +
69576 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
69577 + do
69578 + {
69579 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
69580 + } while ((event & 0x00000020) == 0);
69581 + fm_clk_down();
69582 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
69583 + rcr &= ~0x04000000;
69584 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
69585 +}
69586 +#endif
69587 --- /dev/null
69588 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
69589 @@ -0,0 +1,648 @@
69590 +/*
69591 + * Copyright 2008-2012 Freescale Semiconductor Inc.
69592 + *
69593 + * Redistribution and use in source and binary forms, with or without
69594 + * modification, are permitted provided that the following conditions are met:
69595 + * * Redistributions of source code must retain the above copyright
69596 + * notice, this list of conditions and the following disclaimer.
69597 + * * Redistributions in binary form must reproduce the above copyright
69598 + * notice, this list of conditions and the following disclaimer in the
69599 + * documentation and/or other materials provided with the distribution.
69600 + * * Neither the name of Freescale Semiconductor nor the
69601 + * names of its contributors may be used to endorse or promote products
69602 + * derived from this software without specific prior written permission.
69603 + *
69604 + *
69605 + * ALTERNATIVELY, this software may be distributed under the terms of the
69606 + * GNU General Public License ("GPL") as published by the Free Software
69607 + * Foundation, either version 2 of that License or (at your option) any
69608 + * later version.
69609 + *
69610 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
69611 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
69612 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
69613 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
69614 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
69615 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
69616 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
69617 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69618 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
69619 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69620 + */
69621 +
69622 +
69623 +/******************************************************************************
69624 + @File fm.h
69625 +
69626 + @Description FM internal structures and definitions.
69627 +*//***************************************************************************/
69628 +#ifndef __FM_H
69629 +#define __FM_H
69630 +
69631 +#include "error_ext.h"
69632 +#include "std_ext.h"
69633 +#include "fm_ext.h"
69634 +#include "fm_ipc.h"
69635 +
69636 +#include "fsl_fman.h"
69637 +
69638 +#define __ERR_MODULE__ MODULE_FM
69639 +
69640 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
69641 +#define FM_MAX_NUM_OF_GUESTS 100
69642 +
69643 +/**************************************************************************//**
69644 + @Description Exceptions
69645 +*//***************************************************************************/
69646 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
69647 +#define FM_EX_DMA_READ_ECC 0x40000000
69648 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
69649 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
69650 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
69651 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
69652 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
69653 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
69654 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
69655 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
69656 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
69657 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
69658 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
69659 +#define FM_EX_IRAM_ECC 0x00040000
69660 +#define FM_EX_MURAM_ECC 0x00020000
69661 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
69662 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
69663 +
69664 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
69665 +
69666 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
69667 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
69668 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
69669 +
69670 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
69671 +switch (exception){ \
69672 + case e_FM_EX_DMA_BUS_ERROR: \
69673 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
69674 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
69675 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
69676 + case e_FM_EX_DMA_READ_ECC: \
69677 + bitMask = FM_EX_DMA_READ_ECC; break; \
69678 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
69679 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
69680 + case e_FM_EX_DMA_FM_WRITE_ECC: \
69681 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
69682 + case e_FM_EX_FPM_STALL_ON_TASKS: \
69683 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
69684 + case e_FM_EX_FPM_SINGLE_ECC: \
69685 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
69686 + case e_FM_EX_FPM_DOUBLE_ECC: \
69687 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
69688 + case e_FM_EX_QMI_SINGLE_ECC: \
69689 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
69690 + case e_FM_EX_QMI_DOUBLE_ECC: \
69691 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
69692 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
69693 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
69694 + case e_FM_EX_BMI_LIST_RAM_ECC: \
69695 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
69696 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
69697 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
69698 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
69699 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
69700 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
69701 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
69702 + case e_FM_EX_IRAM_ECC: \
69703 + bitMask = FM_EX_IRAM_ECC; break; \
69704 + case e_FM_EX_MURAM_ECC: \
69705 + bitMask = FM_EX_MURAM_ECC; break; \
69706 + default: bitMask = 0;break; \
69707 +}
69708 +
69709 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
69710 + switch (_mod) { \
69711 + case e_FM_MOD_PRS: \
69712 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69713 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
69714 + break; \
69715 + case e_FM_MOD_KG: \
69716 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69717 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
69718 + break; \
69719 + case e_FM_MOD_PLCR: \
69720 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69721 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
69722 + break; \
69723 + case e_FM_MOD_TMR: \
69724 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
69725 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
69726 + break; \
69727 + case e_FM_MOD_10G_MAC: \
69728 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69729 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
69730 + break; \
69731 + case e_FM_MOD_1G_MAC: \
69732 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
69733 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
69734 + break; \
69735 + case e_FM_MOD_MACSEC: \
69736 + switch (_id){ \
69737 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
69738 + break; \
69739 + } \
69740 + break; \
69741 + case e_FM_MOD_FMAN_CTRL: \
69742 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
69743 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
69744 + break; \
69745 + default: _event = e_FM_EV_DUMMY_LAST; \
69746 + break; \
69747 + }
69748 +
69749 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
69750 + switch (_cache_override){ \
69751 + case e_FM_DMA_NO_CACHE_OR: \
69752 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69753 + case e_FM_DMA_NO_STASH_DATA: \
69754 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
69755 + case e_FM_DMA_MAY_STASH_DATA: \
69756 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
69757 + case e_FM_DMA_STASH_DATA: \
69758 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
69759 + default: \
69760 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
69761 + }
69762 +
69763 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
69764 + switch (_aid_mode){ \
69765 + case e_FM_DMA_AID_OUT_PORT_ID: \
69766 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69767 + case e_FM_DMA_AID_OUT_TNUM: \
69768 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
69769 + default: \
69770 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
69771 + }
69772 +
69773 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
69774 + switch (_dma_dbg_cnt){ \
69775 + case e_FM_DMA_DBG_NO_CNT: \
69776 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69777 + case e_FM_DMA_DBG_CNT_DONE: \
69778 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
69779 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
69780 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
69781 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
69782 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
69783 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
69784 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
69785 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
69786 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
69787 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
69788 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
69789 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
69790 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
69791 + default: \
69792 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
69793 + }
69794 +
69795 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
69796 + switch (_dma_emer){ \
69797 + case e_FM_DMA_EM_EBS: \
69798 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69799 + case e_FM_DMA_EM_SOS: \
69800 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
69801 + default: \
69802 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
69803 + }
69804 +
69805 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
69806 + switch (_dma_err){ \
69807 + case e_FM_DMA_ERR_CATASTROPHIC: \
69808 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69809 + case e_FM_DMA_ERR_REPORT: \
69810 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
69811 + default: \
69812 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
69813 + }
69814 +
69815 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
69816 + switch (_catastrophic_err){ \
69817 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
69818 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69819 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
69820 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
69821 + default: \
69822 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
69823 + }
69824 +
69825 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
69826 + switch (_counters){ \
69827 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
69828 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69829 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
69830 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
69831 + case e_FM_COUNTERS_DEQ_0: \
69832 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
69833 + case e_FM_COUNTERS_DEQ_1: \
69834 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
69835 + case e_FM_COUNTERS_DEQ_2: \
69836 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
69837 + case e_FM_COUNTERS_DEQ_3: \
69838 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
69839 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
69840 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
69841 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
69842 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
69843 + case e_FM_COUNTERS_DEQ_FROM_FD: \
69844 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
69845 + case e_FM_COUNTERS_DEQ_CONFIRM: \
69846 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
69847 + default: \
69848 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
69849 + }
69850 +
69851 +/**************************************************************************//**
69852 + @Description defaults
69853 +*//***************************************************************************/
69854 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
69855 + FM_EX_DMA_READ_ECC |\
69856 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
69857 + FM_EX_DMA_FM_WRITE_ECC |\
69858 + FM_EX_FPM_STALL_ON_TASKS |\
69859 + FM_EX_FPM_SINGLE_ECC |\
69860 + FM_EX_FPM_DOUBLE_ECC |\
69861 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
69862 + FM_EX_BMI_LIST_RAM_ECC |\
69863 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
69864 + FM_EX_BMI_STATISTICS_RAM_ECC |\
69865 + FM_EX_IRAM_ECC |\
69866 + FM_EX_MURAM_ECC |\
69867 + FM_EX_BMI_DISPATCH_RAM_ECC |\
69868 + FM_EX_QMI_DOUBLE_ECC |\
69869 + FM_EX_QMI_SINGLE_ECC)
69870 +
69871 +#define DEFAULT_eccEnable FALSE
69872 +#ifdef FM_PEDANTIC_DMA
69873 +#define DEFAULT_aidOverride TRUE
69874 +#else
69875 +#define DEFAULT_aidOverride FALSE
69876 +#endif /* FM_PEDANTIC_DMA */
69877 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
69878 +#define DEFAULT_dmaStopOnBusError FALSE
69879 +#define DEFAULT_stopAtBusError FALSE
69880 +#define DEFAULT_axiDbgNumOfBeats 1
69881 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69882 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69883 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
69884 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
69885 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
69886 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
69887 +#define DEFAULT_resetOnInit FALSE
69888 +#define DEFAULT_resetOnInitOverrideCallback NULL
69889 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
69890 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
69891 +#define DEFAULT_externalEccRamsEnable FALSE
69892 +#define DEFAULT_VerifyUcode FALSE
69893 +
69894 +#if (DPAA_VERSION < 11)
69895 +#define DEFAULT_totalFifoSize(major, minor) \
69896 + (((major == 2) || (major == 5)) ? \
69897 + (100*KILOBYTE) : ((major == 4) ? \
69898 + (49*KILOBYTE) : (122*KILOBYTE)))
69899 +#define DEFAULT_totalNumOfTasks(major, minor) \
69900 + BMI_MAX_NUM_OF_TASKS
69901 +
69902 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
69903 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
69904 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69905 +#define DEFAULT_dmaCamNumOfEntries 32
69906 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69907 +#define DEFAULT_dmaEnEmergency FALSE
69908 +#define DEFAULT_dmaSosEmergency 0
69909 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69910 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69911 +#define DEFAULT_dmaEmergencySwitchCounter 0
69912 +
69913 +#define DEFAULT_dispLimit 0
69914 +#define DEFAULT_prsDispTh 16
69915 +#define DEFAULT_plcrDispTh 16
69916 +#define DEFAULT_kgDispTh 16
69917 +#define DEFAULT_bmiDispTh 16
69918 +#define DEFAULT_qmiEnqDispTh 16
69919 +#define DEFAULT_qmiDeqDispTh 16
69920 +#define DEFAULT_fmCtl1DispTh 16
69921 +#define DEFAULT_fmCtl2DispTh 16
69922 +
69923 +#else /* (DPAA_VERSION < 11) */
69924 +/* Defaults are registers' reset values */
69925 +#define DEFAULT_totalFifoSize(major, minor) \
69926 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
69927 + (156*KILOBYTE) : (295*KILOBYTE))
69928 +
69929 +/* According to the default value of FMBM_CFG2[TNTSKS] */
69930 +#define DEFAULT_totalNumOfTasks(major, minor) \
69931 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
69932 +
69933 +#define DEFAULT_dmaCommQLow 0x2A
69934 +#define DEFAULT_dmaCommQHigh 0x3F
69935 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
69936 +#define DEFAULT_dmaCamNumOfEntries 64
69937 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
69938 +#define DEFAULT_dmaEnEmergency FALSE
69939 +#define DEFAULT_dmaSosEmergency 0
69940 +#define DEFAULT_dmaWatchdog 0 /* disabled */
69941 +#define DEFAULT_dmaEnEmergencySmoother FALSE
69942 +#define DEFAULT_dmaEmergencySwitchCounter 0
69943 +
69944 +#define DEFAULT_dispLimit 0
69945 +#define DEFAULT_prsDispTh 16
69946 +#define DEFAULT_plcrDispTh 16
69947 +#define DEFAULT_kgDispTh 16
69948 +#define DEFAULT_bmiDispTh 16
69949 +#define DEFAULT_qmiEnqDispTh 16
69950 +#define DEFAULT_qmiDeqDispTh 16
69951 +#define DEFAULT_fmCtl1DispTh 16
69952 +#define DEFAULT_fmCtl2DispTh 16
69953 +#endif /* (DPAA_VERSION < 11) */
69954 +
69955 +#define FM_TIMESTAMP_1_USEC_BIT 8
69956 +
69957 +/**************************************************************************//**
69958 + @Collection Defines used for enabling/disabling FM interrupts
69959 + @{
69960 +*//***************************************************************************/
69961 +#define ERR_INTR_EN_DMA 0x00010000
69962 +#define ERR_INTR_EN_FPM 0x80000000
69963 +#define ERR_INTR_EN_BMI 0x00800000
69964 +#define ERR_INTR_EN_QMI 0x00400000
69965 +#define ERR_INTR_EN_PRS 0x00200000
69966 +#define ERR_INTR_EN_KG 0x00100000
69967 +#define ERR_INTR_EN_PLCR 0x00080000
69968 +#define ERR_INTR_EN_MURAM 0x00040000
69969 +#define ERR_INTR_EN_IRAM 0x00020000
69970 +#define ERR_INTR_EN_10G_MAC0 0x00008000
69971 +#define ERR_INTR_EN_10G_MAC1 0x00000040
69972 +#define ERR_INTR_EN_1G_MAC0 0x00004000
69973 +#define ERR_INTR_EN_1G_MAC1 0x00002000
69974 +#define ERR_INTR_EN_1G_MAC2 0x00001000
69975 +#define ERR_INTR_EN_1G_MAC3 0x00000800
69976 +#define ERR_INTR_EN_1G_MAC4 0x00000400
69977 +#define ERR_INTR_EN_1G_MAC5 0x00000200
69978 +#define ERR_INTR_EN_1G_MAC6 0x00000100
69979 +#define ERR_INTR_EN_1G_MAC7 0x00000080
69980 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
69981 +
69982 +#define INTR_EN_QMI 0x40000000
69983 +#define INTR_EN_PRS 0x20000000
69984 +#define INTR_EN_WAKEUP 0x10000000
69985 +#define INTR_EN_PLCR 0x08000000
69986 +#define INTR_EN_1G_MAC0 0x00080000
69987 +#define INTR_EN_1G_MAC1 0x00040000
69988 +#define INTR_EN_1G_MAC2 0x00020000
69989 +#define INTR_EN_1G_MAC3 0x00010000
69990 +#define INTR_EN_1G_MAC4 0x00000040
69991 +#define INTR_EN_1G_MAC5 0x00000020
69992 +#define INTR_EN_1G_MAC6 0x00000008
69993 +#define INTR_EN_1G_MAC7 0x00000002
69994 +#define INTR_EN_10G_MAC0 0x00200000
69995 +#define INTR_EN_10G_MAC1 0x00100000
69996 +#define INTR_EN_REV0 0x00008000
69997 +#define INTR_EN_REV1 0x00004000
69998 +#define INTR_EN_REV2 0x00002000
69999 +#define INTR_EN_REV3 0x00001000
70000 +#define INTR_EN_BRK 0x00000080
70001 +#define INTR_EN_TMR 0x01000000
70002 +#define INTR_EN_MACSEC_MAC0 0x00000001
70003 +/* @} */
70004 +
70005 +/**************************************************************************//**
70006 + @Description Memory Mapped Registers
70007 +*//***************************************************************************/
70008 +
70009 +#if defined(__MWERKS__) && !defined(__GNUC__)
70010 +#pragma pack(push,1)
70011 +#endif /* defined(__MWERKS__) && ... */
70012 +
70013 +typedef struct
70014 +{
70015 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
70016 + volatile uint32_t idata; /**< FM IRAM instruction data register */
70017 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
70018 + volatile uint32_t iready; /**< FM IRAM ready register */
70019 + volatile uint32_t res[0x1FFFC];
70020 +} t_FMIramRegs;
70021 +
70022 +/* Trace buffer registers -
70023 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
70024 +typedef struct t_FmTrbRegs
70025 +{
70026 + volatile uint32_t tcrh;
70027 + volatile uint32_t tcrl;
70028 + volatile uint32_t tesr;
70029 + volatile uint32_t tecr0h;
70030 + volatile uint32_t tecr0l;
70031 + volatile uint32_t terf0h;
70032 + volatile uint32_t terf0l;
70033 + volatile uint32_t tecr1h;
70034 + volatile uint32_t tecr1l;
70035 + volatile uint32_t terf1h;
70036 + volatile uint32_t terf1l;
70037 + volatile uint32_t tpcch;
70038 + volatile uint32_t tpccl;
70039 + volatile uint32_t tpc1h;
70040 + volatile uint32_t tpc1l;
70041 + volatile uint32_t tpc2h;
70042 + volatile uint32_t tpc2l;
70043 + volatile uint32_t twdimr;
70044 + volatile uint32_t twicvr;
70045 + volatile uint32_t tar;
70046 + volatile uint32_t tdr;
70047 + volatile uint32_t tsnum1;
70048 + volatile uint32_t tsnum2;
70049 + volatile uint32_t tsnum3;
70050 + volatile uint32_t tsnum4;
70051 +} t_FmTrbRegs;
70052 +
70053 +#if defined(__MWERKS__) && !defined(__GNUC__)
70054 +#pragma pack(pop)
70055 +#endif /* defined(__MWERKS__) && ... */
70056 +
70057 +/**************************************************************************//**
70058 + @Description General defines
70059 +*//***************************************************************************/
70060 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
70061 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
70062 +
70063 +/**************************************************************************//**
70064 + @Description FPM defines
70065 +*//***************************************************************************/
70066 +/* masks */
70067 +#define FPM_BRKC_RDBG 0x00000200
70068 +#define FPM_BRKC_SLP 0x00000800
70069 +/**************************************************************************//**
70070 + @Description BMI defines
70071 +*//***************************************************************************/
70072 +/* masks */
70073 +#define BMI_INIT_START 0x80000000
70074 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
70075 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
70076 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
70077 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
70078 +/**************************************************************************//**
70079 + @Description QMI defines
70080 +*//***************************************************************************/
70081 +/* masks */
70082 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
70083 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
70084 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
70085 +
70086 +/**************************************************************************//**
70087 + @Description IRAM defines
70088 +*//***************************************************************************/
70089 +/* masks */
70090 +#define IRAM_IADD_AIE 0x80000000
70091 +#define IRAM_READY 0x80000000
70092 +
70093 +/**************************************************************************//**
70094 + @Description TRB defines
70095 +*//***************************************************************************/
70096 +/* masks */
70097 +#define TRB_TCRH_RESET 0x04000000
70098 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
70099 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
70100 +#define TRB_TCRL_RESET 0x20000000
70101 +#define TRB_TCRL_UTIL 0x00000460
70102 +typedef struct {
70103 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
70104 + t_Handle h_SrcHandle;
70105 +} t_FmanCtrlIntrSrc;
70106 +
70107 +
70108 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
70109 +
70110 +typedef struct
70111 +{
70112 +/***************************/
70113 +/* Master/Guest parameters */
70114 +/***************************/
70115 + uint8_t fmId;
70116 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
70117 + uint16_t fmClkFreq;
70118 + uint16_t fmMacClkFreq;
70119 + t_FmRevisionInfo revInfo;
70120 +/**************************/
70121 +/* Master Only parameters */
70122 +/**************************/
70123 + bool enabledTimeStamp;
70124 + uint8_t count1MicroBit;
70125 + uint8_t totalNumOfTasks;
70126 + uint32_t totalFifoSize;
70127 + uint8_t maxNumOfOpenDmas;
70128 + uint8_t accumulatedNumOfTasks;
70129 + uint32_t accumulatedFifoSize;
70130 + uint8_t accumulatedNumOfOpenDmas;
70131 + uint8_t accumulatedNumOfDeqTnums;
70132 +#ifdef FM_LOW_END_RESTRICTION
70133 + bool lowEndRestriction;
70134 +#endif /* FM_LOW_END_RESTRICTION */
70135 + uint32_t exceptions;
70136 + int irq;
70137 + int errIrq;
70138 + bool ramsEccEnable;
70139 + bool explicitEnable;
70140 + bool internalCall;
70141 + uint8_t ramsEccOwners;
70142 + uint32_t extraFifoPoolSize;
70143 + uint8_t extraTasksPoolSize;
70144 + uint8_t extraOpenDmasPoolSize;
70145 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
70146 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70147 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
70148 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
70149 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70150 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
70151 +} t_FmStateStruct;
70152 +
70153 +#if (DPAA_VERSION >= 11)
70154 +typedef struct t_FmMapParam {
70155 + uint16_t profilesBase;
70156 + uint16_t numOfProfiles;
70157 + t_Handle h_FmPort;
70158 +} t_FmMapParam;
70159 +
70160 +typedef struct t_FmAllocMng {
70161 + bool allocated;
70162 + uint8_t ownerId; /* guestId for KG in multi-partition only,
70163 + portId for PLCR in any environment */
70164 +} t_FmAllocMng;
70165 +
70166 +typedef struct t_FmPcdSpEntry {
70167 + bool valid;
70168 + t_FmAllocMng profilesMng;
70169 +} t_FmPcdSpEntry;
70170 +
70171 +typedef struct t_FmSp {
70172 + void *p_FmPcdStoragePrflRegs;
70173 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
70174 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
70175 +} t_FmSp;
70176 +#endif /* (DPAA_VERSION >= 11) */
70177 +
70178 +typedef struct t_Fm
70179 +{
70180 +/***************************/
70181 +/* Master/Guest parameters */
70182 +/***************************/
70183 +/* locals for recovery */
70184 + uintptr_t baseAddr;
70185 +
70186 +/* un-needed for recovery */
70187 + t_Handle h_Pcd;
70188 + char fmModuleName[MODULE_NAME_SIZE];
70189 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
70190 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
70191 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
70192 + uint8_t guestId;
70193 +/**************************/
70194 +/* Master Only parameters */
70195 +/**************************/
70196 +/* locals for recovery */
70197 + struct fman_fpm_regs *p_FmFpmRegs;
70198 + struct fman_bmi_regs *p_FmBmiRegs;
70199 + struct fman_qmi_regs *p_FmQmiRegs;
70200 + struct fman_dma_regs *p_FmDmaRegs;
70201 + struct fman_regs *p_FmRegs;
70202 + t_FmExceptionsCallback *f_Exception;
70203 + t_FmBusErrorCallback *f_BusError;
70204 + t_Handle h_App; /* Application handle */
70205 + t_Handle h_Spinlock;
70206 + bool recoveryMode;
70207 + t_FmStateStruct *p_FmStateStruct;
70208 + uint16_t tnumAgingPeriod;
70209 +#if (DPAA_VERSION >= 11)
70210 + t_FmSp *p_FmSp;
70211 + uint8_t partNumOfVSPs;
70212 + uint8_t partVSPBase;
70213 + uintptr_t vspBaseAddr;
70214 +#endif /* (DPAA_VERSION >= 11) */
70215 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70216 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
70217 +
70218 +/* un-needed for recovery */
70219 + struct fman_cfg *p_FmDriverParam;
70220 + t_Handle h_FmMuram;
70221 + uint64_t fmMuramPhysBaseAddr;
70222 + bool independentMode;
70223 + bool hcPortInitialized;
70224 + uintptr_t camBaseAddr; /* save for freeing */
70225 + uintptr_t resAddr;
70226 + uintptr_t fifoBaseAddr; /* save for freeing */
70227 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
70228 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
70229 + t_FmFirmwareParams firmware;
70230 + bool fwVerify;
70231 + bool resetOnInit;
70232 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
70233 + uint32_t userSetExceptions;
70234 +} t_Fm;
70235 +
70236 +
70237 +#endif /* __FM_H */
70238 --- /dev/null
70239 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
70240 @@ -0,0 +1,465 @@
70241 +/*
70242 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70243 + *
70244 + * Redistribution and use in source and binary forms, with or without
70245 + * modification, are permitted provided that the following conditions are met:
70246 + * * Redistributions of source code must retain the above copyright
70247 + * notice, this list of conditions and the following disclaimer.
70248 + * * Redistributions in binary form must reproduce the above copyright
70249 + * notice, this list of conditions and the following disclaimer in the
70250 + * documentation and/or other materials provided with the distribution.
70251 + * * Neither the name of Freescale Semiconductor nor the
70252 + * names of its contributors may be used to endorse or promote products
70253 + * derived from this software without specific prior written permission.
70254 + *
70255 + *
70256 + * ALTERNATIVELY, this software may be distributed under the terms of the
70257 + * GNU General Public License ("GPL") as published by the Free Software
70258 + * Foundation, either version 2 of that License or (at your option) any
70259 + * later version.
70260 + *
70261 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70262 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70263 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70264 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70265 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70266 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70267 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70268 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70269 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70270 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70271 + */
70272 +
70273 +
70274 +/**************************************************************************//**
70275 + @File fm_ipc.h
70276 +
70277 + @Description FM Inter-Partition prototypes, structures and definitions.
70278 +*//***************************************************************************/
70279 +#ifndef __FM_IPC_H
70280 +#define __FM_IPC_H
70281 +
70282 +#include "error_ext.h"
70283 +#include "std_ext.h"
70284 +
70285 +
70286 +/**************************************************************************//**
70287 + @Group FM_grp Frame Manager API
70288 +
70289 + @Description FM API functions, definitions and enums
70290 +
70291 + @{
70292 +*//***************************************************************************/
70293 +
70294 +/**************************************************************************//**
70295 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
70296 +
70297 + @Description FM Inter-Partition messaging unit API definitions and enums.
70298 +
70299 + @{
70300 +*//***************************************************************************/
70301 +
70302 +#if defined(__MWERKS__) && !defined(__GNUC__)
70303 +#pragma pack(push,1)
70304 +#endif /* defined(__MWERKS__) && ... */
70305 +
70306 +/**************************************************************************//**
70307 + @Description enum for defining MAC types
70308 +*//***************************************************************************/
70309 +
70310 +/**************************************************************************//**
70311 + @Description A structure of parameters for specifying a MAC.
70312 +*//***************************************************************************/
70313 +typedef _Packed struct
70314 +{
70315 + uint8_t id;
70316 + uint32_t enumType;
70317 +} _PackedType t_FmIpcMacParams;
70318 +
70319 +/**************************************************************************//**
70320 + @Description A structure of parameters for specifying a MAC.
70321 +*//***************************************************************************/
70322 +typedef _Packed struct
70323 +{
70324 + t_FmIpcMacParams macParams;
70325 + uint16_t maxFrameLength;
70326 +} _PackedType t_FmIpcMacMaxFrameParams;
70327 +
70328 +/**************************************************************************//**
70329 + @Description FM physical Address
70330 +*//***************************************************************************/
70331 +typedef _Packed struct t_FmIpcPhysAddr
70332 +{
70333 + volatile uint8_t high;
70334 + volatile uint32_t low;
70335 +} _PackedType t_FmIpcPhysAddr;
70336 +
70337 +
70338 +typedef _Packed struct t_FmIpcPortOutInitParams {
70339 + uint8_t numOfTasks; /**< OUT */
70340 + uint8_t numOfExtraTasks; /**< OUT */
70341 + uint8_t numOfOpenDmas; /**< OUT */
70342 + uint8_t numOfExtraOpenDmas; /**< OUT */
70343 + uint32_t sizeOfFifo; /**< OUT */
70344 + uint32_t extraSizeOfFifo; /**< OUT */
70345 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
70346 +} _PackedType t_FmIpcPortOutInitParams;
70347 +
70348 +/**************************************************************************//**
70349 + @Description Structure for IPC communication during FM_PORT_Init.
70350 +*//***************************************************************************/
70351 +typedef _Packed struct t_FmIpcPortInInitParams {
70352 + uint8_t hardwarePortId; /**< IN. port Id */
70353 + uint32_t enumPortType; /**< IN. Port type */
70354 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
70355 + uint16_t liodnOffset; /**< IN. Port's requested resource */
70356 + uint8_t numOfTasks; /**< IN. Port's requested resource */
70357 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
70358 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
70359 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
70360 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
70361 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
70362 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70363 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
70364 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
70365 + LIODN base for this port, to be
70366 + used together with LIODN offset. */
70367 +} _PackedType t_FmIpcPortInInitParams;
70368 +
70369 +
70370 +/**************************************************************************//**
70371 + @Description Structure for IPC communication between port and FM
70372 + regarding tasks and open DMA resources management.
70373 +*//***************************************************************************/
70374 +typedef _Packed struct t_FmIpcPortRsrcParams {
70375 + uint8_t hardwarePortId; /**< IN. port Id */
70376 + uint32_t val; /**< IN. Port's requested resource */
70377 + uint32_t extra; /**< IN. Port's requested resource */
70378 + uint8_t boolInitialConfig;
70379 +} _PackedType t_FmIpcPortRsrcParams;
70380 +
70381 +
70382 +/**************************************************************************//**
70383 + @Description Structure for IPC communication between port and FM
70384 + regarding tasks and open DMA resources management.
70385 +*//***************************************************************************/
70386 +typedef _Packed struct t_FmIpcPortFifoParams {
70387 + t_FmIpcPortRsrcParams rsrcParams;
70388 + uint32_t enumPortType;
70389 + uint8_t boolIndependentMode;
70390 + uint8_t deqPipelineDepth;
70391 + uint8_t numOfPools;
70392 + uint16_t secondLargestBufSize;
70393 + uint16_t largestBufSize;
70394 + uint8_t boolInitialConfig;
70395 +} _PackedType t_FmIpcPortFifoParams;
70396 +
70397 +/**************************************************************************//**
70398 + @Description Structure for port-FM communication during FM_PORT_Free.
70399 +*//***************************************************************************/
70400 +typedef _Packed struct t_FmIpcPortFreeParams {
70401 + uint8_t hardwarePortId; /**< IN. port Id */
70402 + uint32_t enumPortType; /**< IN. Port type */
70403 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
70404 +} _PackedType t_FmIpcPortFreeParams;
70405 +
70406 +/**************************************************************************//**
70407 + @Description Structure for defining DMA status
70408 +*//***************************************************************************/
70409 +typedef _Packed struct t_FmIpcDmaStatus {
70410 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
70411 + uint8_t boolBusError; /**< Bus error occurred */
70412 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
70413 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70414 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70415 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
70416 +} _PackedType t_FmIpcDmaStatus;
70417 +
70418 +typedef _Packed struct t_FmIpcRegisterIntr
70419 +{
70420 + uint8_t guestId; /* IN */
70421 + uint32_t event; /* IN */
70422 +} _PackedType t_FmIpcRegisterIntr;
70423 +
70424 +typedef _Packed struct t_FmIpcIsr
70425 +{
70426 + uint8_t boolErr; /* IN */
70427 + uint32_t pendingReg; /* IN */
70428 +} _PackedType t_FmIpcIsr;
70429 +
70430 +/**************************************************************************//**
70431 + @Description structure for returning FM parameters
70432 +*//***************************************************************************/
70433 +typedef _Packed struct t_FmIpcParams {
70434 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
70435 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
70436 + uint8_t majorRev; /**< OUT: FM Major revision */
70437 + uint8_t minorRev; /**< OUT: FM Minor revision */
70438 +} _PackedType t_FmIpcParams;
70439 +
70440 +
70441 +/**************************************************************************//**
70442 + @Description structure for returning Fman Ctrl Code revision information
70443 +*//***************************************************************************/
70444 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
70445 + uint16_t packageRev; /**< OUT: Package revision */
70446 + uint8_t majorRev; /**< OUT: Major revision */
70447 + uint8_t minorRev; /**< OUT: Minor revision */
70448 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
70449 +
70450 +/**************************************************************************//**
70451 + @Description Structure for defining Fm number of Fman controlers
70452 +*//***************************************************************************/
70453 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
70454 + uint8_t hardwarePortId; /**< IN. port Id */
70455 + uint8_t numOfFmanCtrls; /**< IN. Port type */
70456 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
70457 +} t_FmIpcPortNumOfFmanCtrls;
70458 +
70459 +/**************************************************************************//**
70460 + @Description structure for setting Fman contriller events
70461 +*//***************************************************************************/
70462 +typedef _Packed struct t_FmIpcFmanEvents {
70463 + uint8_t eventRegId; /**< IN: Fman controller event register id */
70464 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
70465 +} _PackedType t_FmIpcFmanEvents;
70466 +
70467 +typedef _Packed struct t_FmIpcResourceAllocParams {
70468 + uint8_t guestId;
70469 + uint16_t base;
70470 + uint16_t num;
70471 +}_PackedType t_FmIpcResourceAllocParams;
70472 +
70473 +typedef _Packed struct t_FmIpcVspSetPortWindow {
70474 + uint8_t hardwarePortId;
70475 + uint8_t baseStorageProfile;
70476 + uint8_t log2NumOfProfiles;
70477 +}_PackedType t_FmIpcVspSetPortWindow;
70478 +
70479 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
70480 + uint32_t congestionGroupId;
70481 + uint8_t priorityBitMap;
70482 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
70483 +
70484 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
70485 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
70486 +#define FM_IPC_MAX_MSG_SIZE 30
70487 +
70488 +typedef _Packed struct t_FmIpcMsg
70489 +{
70490 + uint32_t msgId;
70491 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
70492 +} _PackedType t_FmIpcMsg;
70493 +
70494 +typedef _Packed struct t_FmIpcReply
70495 +{
70496 + uint32_t error;
70497 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
70498 +} _PackedType t_FmIpcReply;
70499 +
70500 +#if defined(__MWERKS__) && !defined(__GNUC__)
70501 +#pragma pack(pop)
70502 +#endif /* defined(__MWERKS__) && ... */
70503 +
70504 +
70505 +/***************************************************************************/
70506 +/************************ FRONT-END-TO-BACK-END*****************************/
70507 +/***************************************************************************/
70508 +
70509 +/**************************************************************************//**
70510 + @Function FM_GET_TIMESTAMP_SCALE
70511 +
70512 + @Description Used by FM front-end.
70513 +
70514 + @Param[out] uint32_t Pointer
70515 +*//***************************************************************************/
70516 +#define FM_GET_TIMESTAMP_SCALE 1
70517 +
70518 +/**************************************************************************//**
70519 + @Function FM_GET_COUNTER
70520 +
70521 + @Description Used by FM front-end.
70522 +
70523 + @Param[in/out] t_FmIpcGetCounter Pointer
70524 +*//***************************************************************************/
70525 +#define FM_GET_COUNTER 2
70526 +
70527 +/**************************************************************************//**
70528 + @Function FM_GET_SET_PORT_PARAMS
70529 +
70530 + @Description Used by FM front-end for the PORT module in order to set and get
70531 + parameters in/from master FM module on FM PORT initialization time.
70532 +
70533 + @Param[in/out] t_FmIcPortInitParams Pointer
70534 +*//***************************************************************************/
70535 +#define FM_GET_SET_PORT_PARAMS 4
70536 +
70537 +/**************************************************************************//**
70538 + @Function FM_FREE_PORT
70539 +
70540 + @Description Used by FM front-end for the PORT module when a port is freed
70541 + to free all FM PORT resources.
70542 +
70543 + @Param[in] uint8_t Pointer
70544 +*//***************************************************************************/
70545 +#define FM_FREE_PORT 5
70546 +
70547 +/**************************************************************************//**
70548 + @Function FM_RESET_MAC
70549 +
70550 + @Description Used by front-end for the MAC module to reset the MAC registers
70551 +
70552 + @Param[in] t_FmIpcMacParams Pointer .
70553 +*//***************************************************************************/
70554 +#define FM_RESET_MAC 6
70555 +
70556 +/**************************************************************************//**
70557 + @Function FM_RESUME_STALLED_PORT
70558 +
70559 + @Description Used by FM front-end for the PORT module in order to
70560 + release a stalled FM Port.
70561 +
70562 + @Param[in] uint8_t Pointer
70563 +*//***************************************************************************/
70564 +#define FM_RESUME_STALLED_PORT 7
70565 +
70566 +/**************************************************************************//**
70567 + @Function FM_IS_PORT_STALLED
70568 +
70569 + @Description Used by FM front-end for the PORT module in order to check whether
70570 + an FM port is stalled.
70571 +
70572 + @Param[in/out] t_FmIcPortIsStalled Pointer
70573 +*//***************************************************************************/
70574 +#define FM_IS_PORT_STALLED 8
70575 +
70576 +/**************************************************************************//**
70577 + @Function FM_GET_PARAMS
70578 +
70579 + @Description Used by FM front-end for the PORT module in order to dump
70580 + return FM parameters.
70581 +
70582 + @Param[in] uint8_t Pointer
70583 +*//***************************************************************************/
70584 +#define FM_GET_PARAMS 10
70585 +
70586 +/**************************************************************************//**
70587 + @Function FM_REGISTER_INTR
70588 +
70589 + @Description Used by FM front-end to register an interrupt handler to
70590 + be called upon interrupt for guest.
70591 +
70592 + @Param[out] t_FmIpcRegisterIntr Pointer
70593 +*//***************************************************************************/
70594 +#define FM_REGISTER_INTR 11
70595 +
70596 +/**************************************************************************//**
70597 + @Function FM_DMA_STAT
70598 +
70599 + @Description Used by FM front-end to read the FM DMA status.
70600 +
70601 + @Param[out] t_FmIpcDmaStatus Pointer
70602 +*//***************************************************************************/
70603 +#define FM_DMA_STAT 13
70604 +
70605 +/**************************************************************************//**
70606 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
70607 +
70608 + @Description Used by FM front-end to allocate event register.
70609 +
70610 + @Param[out] Event register id Pointer
70611 +*//***************************************************************************/
70612 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
70613 +
70614 +/**************************************************************************//**
70615 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
70616 +
70617 + @Description Used by FM front-end to free locate event register.
70618 +
70619 + @Param[in] uint8_t Pointer - Event register id
70620 +*//***************************************************************************/
70621 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
70622 +
70623 +/**************************************************************************//**
70624 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70625 +
70626 + @Description Used by FM front-end to enable events in the FPM
70627 + Fman controller event register.
70628 +
70629 + @Param[in] t_FmIpcFmanEvents Pointer
70630 +*//***************************************************************************/
70631 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
70632 +
70633 +/**************************************************************************//**
70634 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
70635 +
70636 + @Description Used by FM front-end to enable events in the FPM
70637 + Fman controller event register.
70638 +
70639 + @Param[in/out] t_FmIpcFmanEvents Pointer
70640 +*//***************************************************************************/
70641 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
70642 +
70643 +/**************************************************************************//**
70644 + @Function FM_SET_MAC_MAX_FRAME
70645 +
70646 + @Description Used by FM front-end to set MAC's MTU/RTU's in
70647 + back-end.
70648 +
70649 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
70650 +*//***************************************************************************/
70651 +#define FM_SET_MAC_MAX_FRAME 18
70652 +
70653 +/**************************************************************************//**
70654 + @Function FM_GET_PHYS_MURAM_BASE
70655 +
70656 + @Description Used by FM front-end in order to get MURAM base address
70657 +
70658 + @Param[in/out] t_FmIpcPhysAddr Pointer
70659 +*//***************************************************************************/
70660 +#define FM_GET_PHYS_MURAM_BASE 19
70661 +
70662 +/**************************************************************************//**
70663 + @Function FM_MASTER_IS_ALIVE
70664 +
70665 + @Description Used by FM front-end in order to verify Master is up
70666 +
70667 + @Param[in/out] bool
70668 +*//***************************************************************************/
70669 +#define FM_MASTER_IS_ALIVE 20
70670 +
70671 +#define FM_ENABLE_RAM_ECC 21
70672 +#define FM_DISABLE_RAM_ECC 22
70673 +#define FM_SET_NUM_OF_FMAN_CTRL 23
70674 +#define FM_SET_SIZE_OF_FIFO 24
70675 +#define FM_SET_NUM_OF_TASKS 25
70676 +#define FM_SET_NUM_OF_OPEN_DMAS 26
70677 +#define FM_VSP_ALLOC 27
70678 +#define FM_VSP_FREE 28
70679 +#define FM_VSP_SET_PORT_WINDOW 29
70680 +#define FM_GET_FMAN_CTRL_CODE_REV 30
70681 +#define FM_SET_CONG_GRP_PFC_PRIO 31
70682 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
70683 +#define FM_10G_TX_ECC_WA 100
70684 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
70685 +
70686 +/***************************************************************************/
70687 +/************************ BACK-END-TO-FRONT-END*****************************/
70688 +/***************************************************************************/
70689 +
70690 +/**************************************************************************//**
70691 + @Function FM_GUEST_ISR
70692 +
70693 + @Description Used by FM back-end to report an interrupt to the front-end.
70694 +
70695 + @Param[out] t_FmIpcIsr Pointer
70696 +*//***************************************************************************/
70697 +#define FM_GUEST_ISR 1
70698 +
70699 +
70700 +
70701 +/** @} */ /* end of FM_IPC_grp group */
70702 +/** @} */ /* end of FM_grp group */
70703 +
70704 +
70705 +#endif /* __FM_IPC_H */
70706 --- /dev/null
70707 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
70708 @@ -0,0 +1,174 @@
70709 +/*
70710 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70711 + *
70712 + * Redistribution and use in source and binary forms, with or without
70713 + * modification, are permitted provided that the following conditions are met:
70714 + * * Redistributions of source code must retain the above copyright
70715 + * notice, this list of conditions and the following disclaimer.
70716 + * * Redistributions in binary form must reproduce the above copyright
70717 + * notice, this list of conditions and the following disclaimer in the
70718 + * documentation and/or other materials provided with the distribution.
70719 + * * Neither the name of Freescale Semiconductor nor the
70720 + * names of its contributors may be used to endorse or promote products
70721 + * derived from this software without specific prior written permission.
70722 + *
70723 + *
70724 + * ALTERNATIVELY, this software may be distributed under the terms of the
70725 + * GNU General Public License ("GPL") as published by the Free Software
70726 + * Foundation, either version 2 of that License or (at your option) any
70727 + * later version.
70728 + *
70729 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70730 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70731 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70732 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70733 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70734 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70735 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70736 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70737 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70738 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70739 + */
70740 +
70741 +
70742 +/******************************************************************************
70743 + @File FM_muram.c
70744 +
70745 + @Description FM MURAM ...
70746 +*//***************************************************************************/
70747 +#include "error_ext.h"
70748 +#include "std_ext.h"
70749 +#include "mm_ext.h"
70750 +#include "string_ext.h"
70751 +#include "sprint_ext.h"
70752 +#include "fm_muram_ext.h"
70753 +#include "fm_common.h"
70754 +
70755 +#define __ERR_MODULE__ MODULE_FM_MURAM
70756 +
70757 +
70758 +typedef struct
70759 +{
70760 + t_Handle h_Mem;
70761 + uintptr_t baseAddr;
70762 + uint32_t size;
70763 +} t_FmMuram;
70764 +
70765 +
70766 +void FmMuramClear(t_Handle h_FmMuram)
70767 +{
70768 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70769 +
70770 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
70771 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
70772 +}
70773 +
70774 +
70775 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
70776 +{
70777 + t_Handle h_Mem;
70778 + t_FmMuram *p_FmMuram;
70779 +
70780 + if (!baseAddress)
70781 + {
70782 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
70783 + return NULL;
70784 + }
70785 +
70786 + if (baseAddress%4)
70787 + {
70788 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
70789 + return NULL;
70790 + }
70791 +
70792 + /* Allocate FM MURAM structure */
70793 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
70794 + if (!p_FmMuram)
70795 + {
70796 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
70797 + return NULL;
70798 + }
70799 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
70800 +
70801 +
70802 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
70803 + {
70804 + XX_Free(p_FmMuram);
70805 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
70806 + return NULL;
70807 + }
70808 +
70809 + /* Initialize FM MURAM parameters which will be kept by the driver */
70810 + p_FmMuram->baseAddr = baseAddress;
70811 + p_FmMuram->size = size;
70812 + p_FmMuram->h_Mem = h_Mem;
70813 +
70814 + return p_FmMuram;
70815 +}
70816 +
70817 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
70818 +{
70819 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70820 +
70821 + if (p_FmMuram->h_Mem)
70822 + MM_Free(p_FmMuram->h_Mem);
70823 +
70824 + XX_Free(h_FmMuram);
70825 +
70826 + return E_OK;
70827 +}
70828 +
70829 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
70830 +{
70831 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70832 + uintptr_t addr;
70833 +
70834 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70835 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70836 +
70837 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
70838 +
70839 + if (addr == ILLEGAL_BASE)
70840 + return NULL;
70841 +
70842 + return UINT_TO_PTR(addr);
70843 +}
70844 +
70845 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
70846 +{
70847 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70848 + uintptr_t addr;
70849 +
70850 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
70851 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
70852 +
70853 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
70854 +
70855 + if (addr == ILLEGAL_BASE)
70856 + return NULL;
70857 +
70858 + return UINT_TO_PTR(addr);
70859 +}
70860 +
70861 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
70862 +{
70863 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70864 +
70865 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
70866 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
70867 +
70868 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
70869 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
70870 +
70871 + return E_OK;
70872 +}
70873 +
70874 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
70875 +{
70876 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
70877 +
70878 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
70879 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
70880 +
70881 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
70882 +}
70883 --- /dev/null
70884 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
70885 @@ -0,0 +1,1398 @@
70886 +/*
70887 + * Copyright 2008-2012 Freescale Semiconductor Inc.
70888 + *
70889 + * Redistribution and use in source and binary forms, with or without
70890 + * modification, are permitted provided that the following conditions are met:
70891 + * * Redistributions of source code must retain the above copyright
70892 + * notice, this list of conditions and the following disclaimer.
70893 + * * Redistributions in binary form must reproduce the above copyright
70894 + * notice, this list of conditions and the following disclaimer in the
70895 + * documentation and/or other materials provided with the distribution.
70896 + * * Neither the name of Freescale Semiconductor nor the
70897 + * names of its contributors may be used to endorse or promote products
70898 + * derived from this software without specific prior written permission.
70899 + *
70900 + *
70901 + * ALTERNATIVELY, this software may be distributed under the terms of the
70902 + * GNU General Public License ("GPL") as published by the Free Software
70903 + * Foundation, either version 2 of that License or (at your option) any
70904 + * later version.
70905 + *
70906 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
70907 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
70908 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
70909 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
70910 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
70911 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
70912 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
70913 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
70914 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
70915 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
70916 + */
70917 +
70918 +
70919 +#include <linux/math64.h>
70920 +#include "fsl_fman.h"
70921 +#include "dpaa_integration_ext.h"
70922 +
70923 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
70924 +{
70925 + uint32_t event, mask, force;
70926 +
70927 + event = ioread32be(&bmi_rg->fmbm_ievr);
70928 + mask = ioread32be(&bmi_rg->fmbm_ier);
70929 + event &= mask;
70930 + /* clear the forced events */
70931 + force = ioread32be(&bmi_rg->fmbm_ifr);
70932 + if (force & event)
70933 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
70934 + /* clear the acknowledged events */
70935 + iowrite32be(event, &bmi_rg->fmbm_ievr);
70936 + return event;
70937 +}
70938 +
70939 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
70940 +{
70941 + uint32_t event, mask, force;
70942 +
70943 + event = ioread32be(&qmi_rg->fmqm_eie);
70944 + mask = ioread32be(&qmi_rg->fmqm_eien);
70945 + event &= mask;
70946 +
70947 + /* clear the forced events */
70948 + force = ioread32be(&qmi_rg->fmqm_eif);
70949 + if (force & event)
70950 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
70951 + /* clear the acknowledged events */
70952 + iowrite32be(event, &qmi_rg->fmqm_eie);
70953 + return event;
70954 +}
70955 +
70956 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
70957 +{
70958 + return ioread32be(&dma_rg->fmdmtcid);
70959 +}
70960 +
70961 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
70962 +{
70963 + uint64_t addr;
70964 +
70965 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
70966 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
70967 +
70968 + return addr;
70969 +}
70970 +
70971 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
70972 +{
70973 + uint32_t status, mask;
70974 +
70975 + status = ioread32be(&dma_rg->fmdmsr);
70976 + mask = ioread32be(&dma_rg->fmdmmr);
70977 +
70978 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
70979 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
70980 + status &= ~DMA_STATUS_BUS_ERR;
70981 +
70982 + /* clear relevant bits if mask has no DMA_MODE_ECC */
70983 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
70984 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
70985 + DMA_STATUS_READ_ECC |
70986 + DMA_STATUS_SYSTEM_WRITE_ECC |
70987 + DMA_STATUS_FM_WRITE_ECC);
70988 +
70989 + /* clear set events */
70990 + iowrite32be(status, &dma_rg->fmdmsr);
70991 +
70992 + return status;
70993 +}
70994 +
70995 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
70996 +{
70997 + uint32_t event;
70998 +
70999 + event = ioread32be(&fpm_rg->fmfp_ee);
71000 + /* clear the all occurred events */
71001 + iowrite32be(event, &fpm_rg->fmfp_ee);
71002 + return event;
71003 +}
71004 +
71005 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
71006 +{
71007 + uint32_t event, mask;
71008 +
71009 + event = ioread32be(&fpm_rg->fm_rcr);
71010 + mask = ioread32be(&fpm_rg->fm_rie);
71011 +
71012 + /* clear MURAM event bit (do not clear IRAM event) */
71013 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
71014 +
71015 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
71016 + return event;
71017 + else
71018 + return 0;
71019 +}
71020 +
71021 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
71022 +{
71023 + uint32_t event, mask;
71024 +
71025 + event = ioread32be(&fpm_rg->fm_rcr) ;
71026 + mask = ioread32be(&fpm_rg->fm_rie);
71027 + /* clear IRAM event bit (do not clear MURAM event) */
71028 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
71029 + &fpm_rg->fm_rcr);
71030 +
71031 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
71032 + return event;
71033 + else
71034 + return 0;
71035 +}
71036 +
71037 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
71038 +{
71039 + uint32_t event, mask, force;
71040 +
71041 + event = ioread32be(&qmi_rg->fmqm_ie);
71042 + mask = ioread32be(&qmi_rg->fmqm_ien);
71043 + event &= mask;
71044 + /* clear the forced events */
71045 + force = ioread32be(&qmi_rg->fmqm_if);
71046 + if (force & event)
71047 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
71048 + /* clear the acknowledged events */
71049 + iowrite32be(event, &qmi_rg->fmqm_ie);
71050 + return event;
71051 +}
71052 +
71053 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
71054 + uint8_t count1ubit,
71055 + uint16_t fm_clk_freq)
71056 +{
71057 + uint32_t tmp;
71058 + uint64_t frac;
71059 + uint32_t intgr;
71060 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
71061 +
71062 + /* configure timestamp so that bit 8 will count 1 microsecond
71063 + * Find effective count rate at TIMESTAMP least significant bits:
71064 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
71065 + * Find frequency ratio between effective count rate and the clock:
71066 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
71067 + * 256/600 = 0.4266666... */
71068 +
71069 + intgr = ts_freq / fm_clk_freq;
71070 + /* we multiply by 2^16 to keep the fraction of the division
71071 + * we do not div back, since we write this value as a fraction
71072 + * see spec */
71073 +
71074 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
71075 + /* we check remainder of the division in order to round up if not int */
71076 + if (do_div(frac, fm_clk_freq))
71077 + frac++;
71078 +
71079 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
71080 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
71081 +
71082 + /* enable timestamp with original clock */
71083 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
71084 +}
71085 +
71086 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
71087 +{
71088 + return ioread32be(&fpm_rg->fm_epi);
71089 +}
71090 +
71091 +
71092 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
71093 +{
71094 + int timeout = 100;
71095 +
71096 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
71097 +
71098 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
71099 + udelay(10);
71100 +
71101 + if (!timeout)
71102 + return -EBUSY;
71103 + return 0;
71104 +}
71105 +
71106 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
71107 + uint8_t event_reg_id,
71108 + uint32_t enable_events)
71109 +{
71110 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
71111 +}
71112 +
71113 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
71114 +{
71115 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
71116 +}
71117 +
71118 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
71119 + uint8_t port_id,
71120 + uint8_t num_fman_ctrls,
71121 + uint32_t or_fman_ctrl)
71122 +{
71123 + uint32_t tmp = 0;
71124 +
71125 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71126 + /*TODO - maybe to put CTL# according to another criteria*/
71127 + if (num_fman_ctrls == 2)
71128 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
71129 + /* order restoration */
71130 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
71131 +
71132 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71133 +}
71134 +
71135 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
71136 + uint8_t port_id,
71137 + bool independent_mode,
71138 + bool is_rx_port)
71139 +{
71140 + uint32_t tmp = 0;
71141 +
71142 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
71143 + if (independent_mode) {
71144 + if (is_rx_port)
71145 + tmp |= (FPM_PRT_FM_CTL1 <<
71146 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
71147 + else
71148 + tmp |= (FPM_PRT_FM_CTL2 <<
71149 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
71150 + } else {
71151 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
71152 +
71153 + /* order restoration */
71154 + if (port_id % 2)
71155 + tmp |= (FPM_PRT_FM_CTL1 <<
71156 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71157 + else
71158 + tmp |= (FPM_PRT_FM_CTL2 <<
71159 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
71160 + }
71161 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71162 +}
71163 +
71164 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
71165 +{
71166 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
71167 +}
71168 +
71169 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
71170 +{
71171 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
71172 +}
71173 +
71174 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71175 +{
71176 + uint32_t tmp_reg;
71177 +
71178 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71179 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
71180 + tmp_reg |= ((uint32_t)val << 8);
71181 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71182 +}
71183 +
71184 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
71185 +{
71186 + uint32_t tmp_reg;
71187 +
71188 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
71189 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
71190 + tmp_reg |= (uint32_t)val;
71191 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
71192 +}
71193 +
71194 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
71195 +{
71196 + iowrite32be(0, &fpm_rg->fmfp_mxd);
71197 +}
71198 +
71199 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
71200 + uint16_t liodn_base,
71201 + uint16_t liodn_ofst)
71202 +{
71203 + uint32_t tmp;
71204 +
71205 + if ((port_id > 63) || (port_id < 1))
71206 + return;
71207 +
71208 + /* set LIODN base for this port */
71209 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
71210 + if (port_id % 2) {
71211 + tmp &= ~FM_LIODN_BASE_MASK;
71212 + tmp |= (uint32_t)liodn_base;
71213 + } else {
71214 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
71215 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
71216 + }
71217 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
71218 + iowrite32be((uint32_t)liodn_ofst,
71219 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
71220 +}
71221 +
71222 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71223 +{
71224 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
71225 +}
71226 +
71227 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
71228 +{
71229 + uint32_t tmp;
71230 +
71231 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
71232 + FPM_PRC_REALSE_STALLED);
71233 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
71234 +}
71235 +
71236 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
71237 +{
71238 + uint32_t msk, timeout = 100;
71239 +
71240 + /* Get the relevant bit mask */
71241 + if (is_10g) {
71242 + switch (mac_id) {
71243 + case(0):
71244 + msk = FPM_RSTC_10G0_RESET;
71245 + break;
71246 + case(1):
71247 + msk = FPM_RSTC_10G1_RESET;
71248 + break;
71249 + default:
71250 + return -EINVAL;
71251 + }
71252 + } else {
71253 + switch (mac_id) {
71254 + case(0):
71255 + msk = FPM_RSTC_1G0_RESET;
71256 + break;
71257 + case(1):
71258 + msk = FPM_RSTC_1G1_RESET;
71259 + break;
71260 + case(2):
71261 + msk = FPM_RSTC_1G2_RESET;
71262 + break;
71263 + case(3):
71264 + msk = FPM_RSTC_1G3_RESET;
71265 + break;
71266 + case(4):
71267 + msk = FPM_RSTC_1G4_RESET;
71268 + break;
71269 + case (5):
71270 + msk = FPM_RSTC_1G5_RESET;
71271 + break;
71272 + case (6):
71273 + msk = FPM_RSTC_1G6_RESET;
71274 + break;
71275 + case (7):
71276 + msk = FPM_RSTC_1G7_RESET;
71277 + break;
71278 + default:
71279 + return -EINVAL;
71280 + }
71281 + }
71282 + /* reset */
71283 + iowrite32be(msk, &fpm_rg->fm_rstc);
71284 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
71285 + udelay(10);
71286 +
71287 + if (!timeout)
71288 + return -EBUSY;
71289 + return 0;
71290 +}
71291 +
71292 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71293 +{
71294 + uint32_t tmp_reg;
71295 +
71296 + if ((port_id > 63) || (port_id < 1))
71297 + return 0;
71298 +
71299 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
71300 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
71301 +}
71302 +
71303 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
71304 +{
71305 + uint32_t reg, res;
71306 +
71307 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
71308 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
71309 + return res * FMAN_BMI_FIFO_UNITS;
71310 +}
71311 +
71312 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
71313 + uint8_t port_id)
71314 +{
71315 + uint32_t tmp_reg;
71316 +
71317 + if ((port_id > 63) || (port_id < 1))
71318 + return 0;
71319 +
71320 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
71321 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
71322 + BMI_EXTRA_FIFO_SIZE_SHIFT);
71323 +}
71324 +
71325 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
71326 + uint8_t port_id,
71327 + uint32_t sz_fifo,
71328 + uint32_t extra_sz_fifo)
71329 +{
71330 + uint32_t tmp;
71331 +
71332 + if ((port_id > 63) || (port_id < 1))
71333 + return;
71334 +
71335 + /* calculate reg */
71336 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
71337 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
71338 + BMI_EXTRA_FIFO_SIZE_SHIFT));
71339 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
71340 +}
71341 +
71342 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71343 +{
71344 + uint32_t tmp;
71345 +
71346 + if ((port_id > 63) || (port_id < 1))
71347 + return 0;
71348 +
71349 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71350 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
71351 + BMI_NUM_OF_TASKS_SHIFT) + 1);
71352 +}
71353 +
71354 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71355 +{
71356 + uint32_t tmp;
71357 +
71358 + if ((port_id > 63) || (port_id < 1))
71359 + return 0;
71360 +
71361 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71362 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
71363 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
71364 +}
71365 +
71366 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
71367 + uint8_t port_id,
71368 + uint8_t num_tasks,
71369 + uint8_t num_extra_tasks)
71370 +{
71371 + uint32_t tmp;
71372 +
71373 + if ((port_id > 63) || (port_id < 1))
71374 + return;
71375 +
71376 + /* calculate reg */
71377 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71378 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
71379 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
71380 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
71381 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71382 +}
71383 +
71384 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71385 +{
71386 + uint32_t tmp;
71387 +
71388 + if ((port_id > 63) || (port_id < 1))
71389 + return 0;
71390 +
71391 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71392 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
71393 + BMI_NUM_OF_DMAS_SHIFT) + 1);
71394 +}
71395 +
71396 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
71397 +{
71398 + uint32_t tmp;
71399 +
71400 + if ((port_id > 63) || (port_id < 1))
71401 + return 0;
71402 +
71403 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
71404 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
71405 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
71406 +}
71407 +
71408 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
71409 + uint8_t port_id,
71410 + uint8_t num_open_dmas,
71411 + uint8_t num_extra_open_dmas,
71412 + uint8_t total_num_dmas)
71413 +{
71414 + uint32_t tmp = 0;
71415 +
71416 + if ((port_id > 63) || (port_id < 1))
71417 + return;
71418 +
71419 + /* calculate reg */
71420 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
71421 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
71422 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
71423 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
71424 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
71425 +
71426 + /* update total num of DMA's with committed number of open DMAS,
71427 + * and max uncommitted pool. */
71428 + if (total_num_dmas)
71429 + {
71430 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
71431 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
71432 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
71433 + }
71434 +}
71435 +
71436 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
71437 + uint8_t port_id,
71438 + uint8_t base_storage_profile,
71439 + uint8_t log2_num_of_profiles)
71440 +{
71441 + uint32_t tmp = 0;
71442 + if ((port_id > 63) || (port_id < 1))
71443 + return;
71444 +
71445 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
71446 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
71447 + tmp |= (uint32_t)log2_num_of_profiles << 28;
71448 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
71449 +}
71450 +
71451 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
71452 + uint32_t congestion_group_id,
71453 + uint8_t priority_bit_map,
71454 + uint32_t reg_num)
71455 +{
71456 + uint32_t offset, tmp = 0;
71457 +
71458 + offset = (congestion_group_id%4)*8;
71459 +
71460 + tmp = ioread32be(&cpg_rg[reg_num]);
71461 + tmp &= ~(0xFF<<offset);
71462 + tmp |= (uint32_t)priority_bit_map << offset;
71463 +
71464 + iowrite32be(tmp,&cpg_rg[reg_num]);
71465 +}
71466 +
71467 +/*****************************************************************************/
71468 +/* API Init unit functions */
71469 +/*****************************************************************************/
71470 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
71471 +{
71472 + memset(cfg, 0, sizeof(struct fman_cfg));
71473 +
71474 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
71475 + cfg->dma_err = DEFAULT_DMA_ERR;
71476 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
71477 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
71478 + cfg->en_iram_test_mode = FALSE;
71479 + cfg->en_muram_test_mode = FALSE;
71480 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
71481 +
71482 + if (!is_master)
71483 + return;
71484 +
71485 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
71486 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
71487 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
71488 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
71489 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
71490 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
71491 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
71492 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
71493 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
71494 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
71495 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
71496 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
71497 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
71498 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
71499 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
71500 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
71501 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
71502 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
71503 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
71504 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
71505 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
71506 +
71507 + cfg->pedantic_dma = FALSE;
71508 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
71509 + cfg->dma_stop_on_bus_error = FALSE;
71510 + cfg->qmi_deq_option_support = FALSE;
71511 +}
71512 +
71513 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71514 +{
71515 + uint32_t tmp_reg;
71516 +
71517 + /* read the values from the registers as they are initialized by the HW with
71518 + * the required values.
71519 + */
71520 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
71521 + cfg->total_fifo_size =
71522 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
71523 +
71524 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
71525 + cfg->total_num_of_tasks =
71526 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
71527 +
71528 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
71529 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71530 +
71531 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
71532 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
71533 +
71534 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
71535 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
71536 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
71537 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
71538 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
71539 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
71540 +
71541 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
71542 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
71543 +
71544 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
71545 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
71546 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
71547 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
71548 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
71549 +
71550 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
71551 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
71552 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
71553 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
71554 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
71555 +
71556 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
71557 + cfg->dma_sos_emergency = tmp_reg;
71558 +
71559 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
71560 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
71561 +
71562 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
71563 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
71564 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
71565 +}
71566 +
71567 +void fman_reset(struct fman_fpm_regs *fpm_rg)
71568 +{
71569 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
71570 +}
71571 +
71572 +/**************************************************************************//**
71573 + @Function FM_Init
71574 +
71575 + @Description Initializes the FM module
71576 +
71577 + @Param[in] h_Fm - FM module descriptor
71578 +
71579 + @Return E_OK on success; Error code otherwise.
71580 +*//***************************************************************************/
71581 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
71582 +{
71583 + uint32_t tmp_reg;
71584 +
71585 + /**********************/
71586 + /* Init DMA Registers */
71587 + /**********************/
71588 + /* clear status reg events */
71589 + /* oren - check!!! */
71590 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
71591 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
71592 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
71593 + &dma_rg->fmdmsr);
71594 +
71595 + /* configure mode register */
71596 + tmp_reg = 0;
71597 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
71598 + if (cfg->dma_aid_override)
71599 + tmp_reg |= DMA_MODE_AID_OR;
71600 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
71601 + tmp_reg |= DMA_MODE_BER;
71602 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
71603 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
71604 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
71605 + tmp_reg |= DMA_MODE_ECC;
71606 + if (cfg->dma_stop_on_bus_error)
71607 + tmp_reg |= DMA_MODE_SBER;
71608 + if(cfg->dma_axi_dbg_num_of_beats)
71609 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
71610 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
71611 +
71612 + if (cfg->dma_en_emergency) {
71613 + tmp_reg |= cfg->dma_emergency_bus_select;
71614 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
71615 + if (cfg->dma_en_emergency_smoother)
71616 + iowrite32be(cfg->dma_emergency_switch_counter,
71617 + &dma_rg->fmdmemsr);
71618 + }
71619 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
71620 + DMA_MODE_CEN_SHIFT;
71621 + tmp_reg |= DMA_MODE_SECURE_PROT;
71622 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
71623 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
71624 +
71625 + if (cfg->pedantic_dma)
71626 + tmp_reg |= DMA_MODE_EMER_READ;
71627 +
71628 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
71629 +
71630 + /* configure thresholds register */
71631 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
71632 + DMA_THRESH_COMMQ_SHIFT) |
71633 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
71634 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71635 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
71636 +
71637 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
71638 +
71639 + /* configure hysteresis register */
71640 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
71641 + DMA_THRESH_COMMQ_SHIFT) |
71642 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
71643 + DMA_THRESH_READ_INT_BUF_SHIFT) |
71644 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
71645 +
71646 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
71647 +
71648 + /* configure emergency threshold */
71649 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
71650 +
71651 + /* configure Watchdog */
71652 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
71653 + &dma_rg->fmdmwcr);
71654 +
71655 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
71656 +
71657 + return 0;
71658 +}
71659 +
71660 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
71661 +{
71662 + uint32_t tmp_reg;
71663 + int i;
71664 +
71665 + /**********************/
71666 + /* Init FPM Registers */
71667 + /**********************/
71668 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
71669 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
71670 +
71671 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
71672 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
71673 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
71674 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
71675 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
71676 +
71677 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
71678 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
71679 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
71680 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
71681 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
71682 +
71683 + /* define exceptions and error behavior */
71684 + tmp_reg = 0;
71685 + /* Clear events */
71686 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
71687 + FPM_EV_MASK_SINGLE_ECC);
71688 + /* enable interrupts */
71689 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
71690 + tmp_reg |= FPM_EV_MASK_STALL_EN;
71691 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
71692 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
71693 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
71694 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
71695 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
71696 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
71697 + if (!cfg->halt_on_external_activ)
71698 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
71699 + if (!cfg->halt_on_unrecov_ecc_err)
71700 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
71701 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
71702 +
71703 + /* clear all fmCtls event registers */
71704 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
71705 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
71706 +
71707 + /* RAM ECC - enable and clear events*/
71708 + /* first we need to clear all parser memory,
71709 + * as it is uninitialized and may cause ECC errors */
71710 + /* event bits */
71711 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
71712 + /* Rams enable not effected by RCR bit, but by a COP configuration */
71713 + if (cfg->external_ecc_rams_enable)
71714 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
71715 +
71716 + /* enable test mode */
71717 + if (cfg->en_muram_test_mode)
71718 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
71719 + if (cfg->en_iram_test_mode)
71720 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
71721 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
71722 +
71723 + tmp_reg = 0;
71724 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
71725 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
71726 + fman_enable_rams_ecc(fpm_rg);
71727 + }
71728 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
71729 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
71730 + fman_enable_rams_ecc(fpm_rg);
71731 + }
71732 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
71733 +
71734 + return 0;
71735 +}
71736 +
71737 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
71738 +{
71739 + uint32_t tmp_reg;
71740 +
71741 + /**********************/
71742 + /* Init BMI Registers */
71743 + /**********************/
71744 +
71745 + /* define common resources */
71746 + tmp_reg = cfg->fifo_base_addr;
71747 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
71748 +
71749 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
71750 + BMI_CFG1_FIFO_SIZE_SHIFT);
71751 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
71752 +
71753 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
71754 + BMI_CFG2_TASKS_SHIFT);
71755 + /* num of DMA's will be dynamically updated when each port is set */
71756 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
71757 +
71758 + /* define unmaskable exceptions, enable and clear events */
71759 + tmp_reg = 0;
71760 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
71761 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
71762 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
71763 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
71764 + &bmi_rg->fmbm_ievr);
71765 +
71766 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
71767 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
71768 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
71769 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
71770 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
71771 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
71772 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
71773 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
71774 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
71775 +
71776 + return 0;
71777 +}
71778 +
71779 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
71780 +{
71781 + uint32_t tmp_reg;
71782 + uint16_t period_in_fm_clocks;
71783 + uint8_t remainder;
71784 + /**********************/
71785 + /* Init QMI Registers */
71786 + /**********************/
71787 + /* Clear error interrupt events */
71788 +
71789 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
71790 + &qmi_rg->fmqm_eie);
71791 + tmp_reg = 0;
71792 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
71793 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
71794 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
71795 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71796 + /* enable events */
71797 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
71798 +
71799 + if (cfg->tnum_aging_period) {
71800 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
71801 + period_in_fm_clocks = (uint16_t)
71802 + (cfg->tnum_aging_period * cfg->clk_freq);
71803 + /* period_in_fm_clocks must be a 64 multiply */
71804 + remainder = (uint8_t)(period_in_fm_clocks % 64);
71805 + if (remainder)
71806 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
71807 + else{
71808 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
71809 + if (!tmp_reg)
71810 + tmp_reg = 1;
71811 + }
71812 + tmp_reg <<= QMI_TAPC_TAP;
71813 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
71814 + }
71815 + tmp_reg = 0;
71816 + /* Clear interrupt events */
71817 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
71818 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
71819 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
71820 + /* enable events */
71821 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
71822 +
71823 + return 0;
71824 +}
71825 +
71826 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
71827 +{
71828 + uint32_t cfg_reg = 0;
71829 +
71830 + /**********************/
71831 + /* Enable all modules */
71832 + /**********************/
71833 + /* clear & enable global counters - calculate reg and save for later,
71834 + because it's the same reg for QMI enable */
71835 + cfg_reg = QMI_CFG_EN_COUNTERS;
71836 + if (cfg->qmi_deq_option_support)
71837 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
71838 + (uint32_t)cfg->qmi_def_tnums_thresh);
71839 +
71840 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
71841 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
71842 + &fman_rg->qmi_rg->fmqm_gc);
71843 +
71844 + return 0;
71845 +}
71846 +
71847 +void fman_free_resources(struct fman_rg *fman_rg)
71848 +{
71849 + /* disable BMI and QMI */
71850 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
71851 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
71852 +
71853 + /* release BMI resources */
71854 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
71855 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
71856 +
71857 + /* disable ECC */
71858 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
71859 +}
71860 +
71861 +/****************************************************/
71862 +/* API Run-time Control uint functions */
71863 +/****************************************************/
71864 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
71865 +{
71866 + return ioread32be(&fpm_rg->fm_npi);
71867 +}
71868 +
71869 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
71870 +{
71871 + uint32_t event;
71872 +
71873 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
71874 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
71875 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
71876 +
71877 + return event;
71878 +}
71879 +
71880 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
71881 +{
71882 + return ioread32be(&fpm_rg->fm_epi);
71883 +}
71884 +
71885 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
71886 +{
71887 + int i;
71888 + uint8_t shift;
71889 + uint32_t tmp = 0;
71890 +
71891 + for (i = 0; i < 64; i++) {
71892 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
71893 + /* Add this port to tmp_reg */
71894 + /* (each 8 ports result in one register)*/
71895 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
71896 + tmp |= ((weights[i] - 1) << shift);
71897 + }
71898 + if (i % 8 == 7) { /* last in this set */
71899 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
71900 + tmp = 0;
71901 + }
71902 + }
71903 +}
71904 +
71905 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71906 +{
71907 + uint32_t tmp;
71908 +
71909 + tmp = ioread32be(&fpm_rg->fm_rcr);
71910 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71911 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
71912 + &fpm_rg->fm_rcr);
71913 + else
71914 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
71915 + FPM_RAM_IRAM_ECC_EN,
71916 + &fpm_rg->fm_rcr);
71917 +}
71918 +
71919 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
71920 +{
71921 + uint32_t tmp;
71922 +
71923 + tmp = ioread32be(&fpm_rg->fm_rcr);
71924 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
71925 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
71926 + &fpm_rg->fm_rcr);
71927 + else
71928 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
71929 + &fpm_rg->fm_rcr);
71930 +}
71931 +
71932 +int fman_set_exception(struct fman_rg *fman_rg,
71933 + enum fman_exceptions exception,
71934 + bool enable)
71935 +{
71936 + uint32_t tmp;
71937 +
71938 + switch (exception) {
71939 + case(E_FMAN_EX_DMA_BUS_ERROR):
71940 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71941 + if (enable)
71942 + tmp |= DMA_MODE_BER;
71943 + else
71944 + tmp &= ~DMA_MODE_BER;
71945 + /* disable bus error */
71946 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71947 + break;
71948 + case(E_FMAN_EX_DMA_READ_ECC):
71949 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
71950 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
71951 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
71952 + if (enable)
71953 + tmp |= DMA_MODE_ECC;
71954 + else
71955 + tmp &= ~DMA_MODE_ECC;
71956 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
71957 + break;
71958 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
71959 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71960 + if (enable)
71961 + tmp |= FPM_EV_MASK_STALL_EN;
71962 + else
71963 + tmp &= ~FPM_EV_MASK_STALL_EN;
71964 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71965 + break;
71966 + case(E_FMAN_EX_FPM_SINGLE_ECC):
71967 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71968 + if (enable)
71969 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
71970 + else
71971 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
71972 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71973 + break;
71974 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
71975 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
71976 + if (enable)
71977 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
71978 + else
71979 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
71980 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
71981 + break;
71982 + case(E_FMAN_EX_QMI_SINGLE_ECC):
71983 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
71984 + if (enable)
71985 + tmp |= QMI_INTR_EN_SINGLE_ECC;
71986 + else
71987 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
71988 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
71989 + break;
71990 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
71991 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
71992 + if (enable)
71993 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
71994 + else
71995 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
71996 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
71997 + break;
71998 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
71999 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
72000 + if (enable)
72001 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
72002 + else
72003 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
72004 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
72005 + break;
72006 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
72007 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72008 + if (enable)
72009 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
72010 + else
72011 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
72012 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72013 + break;
72014 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
72015 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72016 + if (enable)
72017 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
72018 + else
72019 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
72020 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72021 + break;
72022 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
72023 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72024 + if (enable)
72025 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
72026 + else
72027 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
72028 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72029 + break;
72030 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
72031 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
72032 + if (enable)
72033 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
72034 + else
72035 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
72036 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
72037 + break;
72038 + case(E_FMAN_EX_IRAM_ECC):
72039 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
72040 + if (enable) {
72041 + /* enable ECC if not enabled */
72042 + fman_enable_rams_ecc(fman_rg->fpm_rg);
72043 + /* enable ECC interrupts */
72044 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
72045 + } else {
72046 + /* ECC mechanism may be disabled,
72047 + * depending on driver status */
72048 + fman_disable_rams_ecc(fman_rg->fpm_rg);
72049 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
72050 + }
72051 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
72052 + break;
72053 + case(E_FMAN_EX_MURAM_ECC):
72054 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
72055 + if (enable) {
72056 + /* enable ECC if not enabled */
72057 + fman_enable_rams_ecc(fman_rg->fpm_rg);
72058 + /* enable ECC interrupts */
72059 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
72060 + } else {
72061 + /* ECC mechanism may be disabled,
72062 + * depending on driver status */
72063 + fman_disable_rams_ecc(fman_rg->fpm_rg);
72064 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
72065 + }
72066 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
72067 + break;
72068 + default:
72069 + return -EINVAL;
72070 + }
72071 + return 0;
72072 +}
72073 +
72074 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
72075 + uint8_t *major,
72076 + uint8_t *minor)
72077 +{
72078 + uint32_t tmp;
72079 +
72080 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
72081 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
72082 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
72083 +
72084 +}
72085 +
72086 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
72087 + enum fman_counters reg_name)
72088 +{
72089 + uint32_t ret_val;
72090 +
72091 + switch (reg_name) {
72092 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72093 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
72094 + break;
72095 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72096 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
72097 + break;
72098 + case(E_FMAN_COUNTERS_DEQ_0):
72099 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
72100 + break;
72101 + case(E_FMAN_COUNTERS_DEQ_1):
72102 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
72103 + break;
72104 + case(E_FMAN_COUNTERS_DEQ_2):
72105 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
72106 + break;
72107 + case(E_FMAN_COUNTERS_DEQ_3):
72108 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
72109 + break;
72110 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72111 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
72112 + break;
72113 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72114 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
72115 + break;
72116 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72117 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
72118 + break;
72119 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72120 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
72121 + break;
72122 + default:
72123 + ret_val = 0;
72124 + }
72125 + return ret_val;
72126 +}
72127 +
72128 +int fman_modify_counter(struct fman_rg *fman_rg,
72129 + enum fman_counters reg_name,
72130 + uint32_t val)
72131 +{
72132 + /* When applicable (when there is an 'enable counters' bit,
72133 + * check that counters are enabled */
72134 + switch (reg_name) {
72135 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72136 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72137 + case(E_FMAN_COUNTERS_DEQ_0):
72138 + case(E_FMAN_COUNTERS_DEQ_1):
72139 + case(E_FMAN_COUNTERS_DEQ_2):
72140 + case(E_FMAN_COUNTERS_DEQ_3):
72141 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72142 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72143 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72144 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72145 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
72146 + QMI_CFG_EN_COUNTERS))
72147 + return -EINVAL;
72148 + break;
72149 + default:
72150 + break;
72151 + }
72152 + /* Set counter */
72153 + switch (reg_name) {
72154 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
72155 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
72156 + break;
72157 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
72158 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
72159 + break;
72160 + case(E_FMAN_COUNTERS_DEQ_0):
72161 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
72162 + break;
72163 + case(E_FMAN_COUNTERS_DEQ_1):
72164 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
72165 + break;
72166 + case(E_FMAN_COUNTERS_DEQ_2):
72167 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
72168 + break;
72169 + case(E_FMAN_COUNTERS_DEQ_3):
72170 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
72171 + break;
72172 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
72173 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
72174 + break;
72175 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
72176 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
72177 + break;
72178 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
72179 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
72180 + break;
72181 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
72182 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
72183 + break;
72184 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
72185 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
72186 + break;
72187 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
72188 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
72189 + break;
72190 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
72191 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
72192 + break;
72193 + default:
72194 + break;
72195 + }
72196 + return 0;
72197 +}
72198 +
72199 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
72200 + bool is_write,
72201 + bool enable)
72202 +{
72203 + uint32_t msk;
72204 +
72205 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
72206 +
72207 + if (enable)
72208 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
72209 + &dma_rg->fmdmmr);
72210 + else /* disable */
72211 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
72212 + &dma_rg->fmdmmr);
72213 +}
72214 +
72215 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
72216 +{
72217 + uint32_t tmp;
72218 +
72219 + tmp = ioread32be(&dma_rg->fmdmmr) |
72220 + (pri << DMA_MODE_BUS_PRI_SHIFT);
72221 +
72222 + iowrite32be(tmp, &dma_rg->fmdmmr);
72223 +}
72224 +
72225 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
72226 +{
72227 + return ioread32be(&dma_rg->fmdmsr);
72228 +}
72229 +
72230 +void fman_force_intr(struct fman_rg *fman_rg,
72231 + enum fman_exceptions exception)
72232 +{
72233 + switch (exception) {
72234 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
72235 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
72236 + &fman_rg->qmi_rg->fmqm_eif);
72237 + break;
72238 + case E_FMAN_EX_QMI_SINGLE_ECC:
72239 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
72240 + &fman_rg->qmi_rg->fmqm_if);
72241 + break;
72242 + case E_FMAN_EX_QMI_DOUBLE_ECC:
72243 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
72244 + &fman_rg->qmi_rg->fmqm_eif);
72245 + break;
72246 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
72247 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
72248 + &fman_rg->bmi_rg->fmbm_ifr);
72249 + break;
72250 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
72251 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
72252 + &fman_rg->bmi_rg->fmbm_ifr);
72253 + break;
72254 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
72255 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
72256 + &fman_rg->bmi_rg->fmbm_ifr);
72257 + break;
72258 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
72259 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
72260 + &fman_rg->bmi_rg->fmbm_ifr);
72261 + break;
72262 + default:
72263 + break;
72264 + }
72265 +}
72266 +
72267 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
72268 +{
72269 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
72270 +}
72271 +void fman_resume(struct fman_fpm_regs *fpm_rg)
72272 +{
72273 + uint32_t tmp;
72274 +
72275 + tmp = ioread32be(&fpm_rg->fmfp_ee);
72276 + /* clear tmp_reg event bits in order not to clear standing events */
72277 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
72278 + FPM_EV_MASK_STALL |
72279 + FPM_EV_MASK_SINGLE_ECC);
72280 + tmp |= FPM_EV_MASK_RELEASE_FM;
72281 +
72282 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
72283 +}
72284 --- /dev/null
72285 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
72286 @@ -0,0 +1,1214 @@
72287 +/*
72288 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72289 + *
72290 + * Redistribution and use in source and binary forms, with or without
72291 + * modification, are permitted provided that the following conditions are met:
72292 + * * Redistributions of source code must retain the above copyright
72293 + * notice, this list of conditions and the following disclaimer.
72294 + * * Redistributions in binary form must reproduce the above copyright
72295 + * notice, this list of conditions and the following disclaimer in the
72296 + * documentation and/or other materials provided with the distribution.
72297 + * * Neither the name of Freescale Semiconductor nor the
72298 + * names of its contributors may be used to endorse or promote products
72299 + * derived from this software without specific prior written permission.
72300 + *
72301 + *
72302 + * ALTERNATIVELY, this software may be distributed under the terms of the
72303 + * GNU General Public License ("GPL") as published by the Free Software
72304 + * Foundation, either version 2 of that License or (at your option) any
72305 + * later version.
72306 + *
72307 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72308 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72309 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72310 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72311 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72312 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72313 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72314 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72315 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72316 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72317 + */
72318 +
72319 +
72320 +/******************************************************************************
72321 + @File fm_common.h
72322 +
72323 + @Description FM internal structures and definitions.
72324 +*//***************************************************************************/
72325 +#ifndef __FM_COMMON_H
72326 +#define __FM_COMMON_H
72327 +
72328 +#include "error_ext.h"
72329 +#include "std_ext.h"
72330 +#include "fm_pcd_ext.h"
72331 +#include "fm_ext.h"
72332 +#include "fm_port_ext.h"
72333 +
72334 +
72335 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
72336 +
72337 +#define CLS_PLAN_NUM_PER_GRP 8
72338 +
72339 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
72340 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
72341 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
72342 +
72343 +
72344 +
72345 +/**************************************************************************//**
72346 + @Description Modules registers offsets
72347 +*//***************************************************************************/
72348 +#define FM_MM_MURAM 0x00000000
72349 +#define FM_MM_BMI 0x00080000
72350 +#define FM_MM_QMI 0x00080400
72351 +#define FM_MM_PRS 0x000c7000
72352 +#define FM_MM_KG 0x000C1000
72353 +#define FM_MM_DMA 0x000C2000
72354 +#define FM_MM_FPM 0x000C3000
72355 +#define FM_MM_PLCR 0x000C0000
72356 +#define FM_MM_IMEM 0x000C4000
72357 +#define FM_MM_CGP 0x000DB000
72358 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
72359 +#if (DPAA_VERSION >= 11)
72360 +#define FM_MM_SP 0x000dc000
72361 +#endif /* (DPAA_VERSION >= 11) */
72362 +
72363 +
72364 +/**************************************************************************//**
72365 + @Description Enum for inter-module interrupts registration
72366 +*//***************************************************************************/
72367 +typedef enum e_FmEventModules{
72368 + e_FM_MOD_PRS, /**< Parser event */
72369 + e_FM_MOD_KG, /**< Keygen event */
72370 + e_FM_MOD_PLCR, /**< Policer event */
72371 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
72372 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
72373 + e_FM_MOD_TMR, /**< Timer event */
72374 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
72375 + e_FM_MOD_MACSEC,
72376 + e_FM_MOD_DUMMY_LAST
72377 +} e_FmEventModules;
72378 +
72379 +/**************************************************************************//**
72380 + @Description Enum for interrupts types
72381 +*//***************************************************************************/
72382 +typedef enum e_FmIntrType {
72383 + e_FM_INTR_TYPE_ERR,
72384 + e_FM_INTR_TYPE_NORMAL
72385 +} e_FmIntrType;
72386 +
72387 +/**************************************************************************//**
72388 + @Description Enum for inter-module interrupts registration
72389 +*//***************************************************************************/
72390 +typedef enum e_FmInterModuleEvent
72391 +{
72392 + e_FM_EV_PRS = 0, /**< Parser event */
72393 + e_FM_EV_ERR_PRS, /**< Parser error event */
72394 + e_FM_EV_KG, /**< Keygen event */
72395 + e_FM_EV_ERR_KG, /**< Keygen error event */
72396 + e_FM_EV_PLCR, /**< Policer event */
72397 + e_FM_EV_ERR_PLCR, /**< Policer error event */
72398 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
72399 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
72400 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
72401 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
72402 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
72403 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
72404 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
72405 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
72406 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
72407 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
72408 + e_FM_EV_ERR_MACSEC_MAC0,
72409 + e_FM_EV_TMR, /**< Timer event */
72410 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
72411 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
72412 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
72413 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
72414 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
72415 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
72416 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
72417 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
72418 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
72419 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
72420 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
72421 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
72422 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
72423 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
72424 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
72425 + e_FM_EV_DUMMY_LAST
72426 +} e_FmInterModuleEvent;
72427 +
72428 +
72429 +#if defined(__MWERKS__) && !defined(__GNUC__)
72430 +#pragma pack(push,1)
72431 +#endif /* defined(__MWERKS__) && ... */
72432 +
72433 +/**************************************************************************//**
72434 + @Description PCD KG scheme registers
72435 +*//***************************************************************************/
72436 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
72437 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
72438 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
72439 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
72440 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
72441 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
72442 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
72443 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
72444 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
72445 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
72446 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
72447 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
72448 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
72449 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
72450 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
72451 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
72452 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
72453 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
72454 +} _PackedType t_FmPcdPlcrProfileRegs;
72455 +
72456 +
72457 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
72458 + volatile uint32_t portIdAndCapwapReassmTbl;
72459 + volatile uint32_t fqidForTimeOutFrames;
72460 + volatile uint32_t timeoutRequestTime;
72461 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
72462 +
72463 +/**************************************************************************//**
72464 + @Description PCD CTRL Parameters Page
72465 +*//***************************************************************************/
72466 +typedef _Packed struct t_FmPcdCtrlParamsPage {
72467 + volatile uint8_t reserved0[16];
72468 + volatile uint32_t iprIpv4Nia;
72469 + volatile uint32_t iprIpv6Nia;
72470 + volatile uint8_t reserved1[24];
72471 + volatile uint32_t ipfOptionsCounter;
72472 + volatile uint8_t reserved2[12];
72473 + volatile uint32_t misc;
72474 + volatile uint32_t errorsDiscardMask;
72475 + volatile uint32_t discardMask;
72476 + volatile uint8_t reserved3[4];
72477 + volatile uint32_t postBmiFetchNia;
72478 + volatile uint8_t reserved4[172];
72479 +} _PackedType t_FmPcdCtrlParamsPage;
72480 +
72481 +
72482 +
72483 +#if defined(__MWERKS__) && !defined(__GNUC__)
72484 +#pragma pack(pop)
72485 +#endif /* defined(__MWERKS__) && ... */
72486 +
72487 +
72488 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
72489 +typedef uint32_t t_FmFmanCtrl;
72490 +
72491 +#define FPM_PORT_FM_CTL1 0x00000001
72492 +#define FPM_PORT_FM_CTL2 0x00000002
72493 +
72494 +
72495 +
72496 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
72497 + uint32_t numOfBuffers;
72498 + uint8_t bufferPoolId;
72499 +} t_FmPcdCcFragScratchPoolCmdParams;
72500 +
72501 +typedef struct t_FmPcdCcReassmTimeoutParams {
72502 + bool activate;
72503 + uint8_t tsbs;
72504 + uint32_t iprcpt;
72505 +} t_FmPcdCcReassmTimeoutParams;
72506 +
72507 +typedef struct {
72508 + uint8_t baseEntry;
72509 + uint16_t numOfClsPlanEntries;
72510 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
72511 +} t_FmPcdKgInterModuleClsPlanSet;
72512 +
72513 +/**************************************************************************//**
72514 + @Description Structure for binding a port to keygen schemes.
72515 +*//***************************************************************************/
72516 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
72517 + uint8_t hardwarePortId;
72518 + uint8_t netEnvId;
72519 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
72520 + uint8_t numOfSchemes;
72521 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
72522 +} t_FmPcdKgInterModuleBindPortToSchemes;
72523 +
72524 +typedef struct {
72525 + uint32_t nextCcNodeInfo;
72526 + t_List node;
72527 +} t_CcNodeInfo;
72528 +
72529 +typedef struct
72530 +{
72531 + t_Handle h_CcNode;
72532 + uint16_t index;
72533 + t_List node;
72534 +}t_CcNodeInformation;
72535 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
72536 +
72537 +typedef enum e_ModifyState
72538 +{
72539 + e_MODIFY_STATE_ADD = 0,
72540 + e_MODIFY_STATE_REMOVE,
72541 + e_MODIFY_STATE_CHANGE
72542 +} e_ModifyState;
72543 +
72544 +typedef struct
72545 +{
72546 + t_Handle h_Manip;
72547 + t_List node;
72548 +}t_ManipInfo;
72549 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
72550 +
72551 +typedef struct {
72552 + uint32_t type;
72553 + uint8_t prOffset;
72554 + uint16_t dataOffset;
72555 + uint8_t internalBufferOffset;
72556 + uint8_t numOfTasks;
72557 + uint8_t numOfExtraTasks;
72558 + uint8_t hardwarePortId;
72559 + t_FmRevisionInfo revInfo;
72560 + uint32_t nia;
72561 + uint32_t discardMask;
72562 +} t_GetCcParams;
72563 +
72564 +typedef struct {
72565 + uint32_t type;
72566 + int psoSize;
72567 + uint32_t nia;
72568 + t_FmFmanCtrl orFmanCtrl;
72569 + bool overwrite;
72570 + uint8_t ofpDpde;
72571 +} t_SetCcParams;
72572 +
72573 +typedef struct {
72574 + t_GetCcParams getCcParams;
72575 + t_SetCcParams setCcParams;
72576 +} t_FmPortGetSetCcParams;
72577 +
72578 +typedef struct {
72579 + uint32_t type;
72580 + bool sleep;
72581 +} t_FmSetParams;
72582 +
72583 +typedef struct {
72584 + uint32_t type;
72585 + uint32_t fmqm_gs;
72586 + uint32_t fm_npi;
72587 + uint32_t fm_cld;
72588 + uint32_t fmfp_extc;
72589 +} t_FmGetParams;
72590 +
72591 +typedef struct {
72592 + t_FmSetParams setParams;
72593 + t_FmGetParams getParams;
72594 +} t_FmGetSetParams;
72595 +
72596 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
72597 +
72598 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
72599 +{
72600 + uint32_t intFlags;
72601 + if (h_Spinlock)
72602 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
72603 + else
72604 + intFlags = XX_DisableAllIntr();
72605 +
72606 + if (*p_Flag)
72607 + {
72608 + if (h_Spinlock)
72609 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72610 + else
72611 + XX_RestoreAllIntr(intFlags);
72612 + return FALSE;
72613 + }
72614 + *p_Flag = TRUE;
72615 +
72616 + if (h_Spinlock)
72617 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
72618 + else
72619 + XX_RestoreAllIntr(intFlags);
72620 +
72621 + return TRUE;
72622 +}
72623 +
72624 +#define RELEASE_LOCK(_flag) _flag = FALSE;
72625 +
72626 +/**************************************************************************//**
72627 + @Collection Defines used for manipulation CC and BMI
72628 + @{
72629 +*//***************************************************************************/
72630 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
72631 +#define OFFSET_OF_PR 0x40000000
72632 +#define MANIP_EXTRA_SPACE 0x20000000
72633 +#define NUM_OF_TASKS 0x10000000
72634 +#define OFFSET_OF_DATA 0x08000000
72635 +#define HW_PORT_ID 0x04000000
72636 +#define FM_REV 0x02000000
72637 +#define GET_NIA_FPNE 0x01000000
72638 +#define GET_NIA_PNDN 0x00800000
72639 +#define NUM_OF_EXTRA_TASKS 0x00400000
72640 +#define DISCARD_MASK 0x00200000
72641 +
72642 +#define UPDATE_NIA_PNEN 0x80000000
72643 +#define UPDATE_PSO 0x40000000
72644 +#define UPDATE_NIA_PNDN 0x20000000
72645 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
72646 +#define UPDATE_OFP_DPTE 0x08000000
72647 +#define UPDATE_NIA_FENE 0x04000000
72648 +#define UPDATE_NIA_CMNE 0x02000000
72649 +#define UPDATE_NIA_FPNE 0x01000000
72650 +/* @} */
72651 +
72652 +/**************************************************************************//**
72653 + @Collection Defines used for manipulation CC and CC
72654 + @{
72655 +*//***************************************************************************/
72656 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
72657 +#define UPDATE_CC_WITH_TREE 0x40000000
72658 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
72659 +#define UPDATE_KG_NIA_CC_WA 0x10000000
72660 +#define UPDATE_KG_OPT_MODE 0x08000000
72661 +#define UPDATE_KG_NIA 0x04000000
72662 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
72663 +/* @} */
72664 +
72665 +#define UPDATE_FPM_BRKC_SLP 0x80000000
72666 +#define UPDATE_FPM_EXTC 0x40000000
72667 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
72668 +#define GET_FMQM_GS 0x10000000
72669 +#define GET_FM_NPI 0x08000000
72670 +#define GET_FMFP_EXTC 0x04000000
72671 +#define CLEAR_IRAM_READY 0x02000000
72672 +#define UPDATE_FM_CLD 0x01000000
72673 +#define GET_FM_CLD 0x00800000
72674 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
72675 + FM_MAX_NUM_OF_1G_RX_PORTS + \
72676 + FM_MAX_NUM_OF_10G_RX_PORTS + \
72677 + FM_MAX_NUM_OF_1G_TX_PORTS + \
72678 + FM_MAX_NUM_OF_10G_TX_PORTS)
72679 +
72680 +#define MODULE_NAME_SIZE 30
72681 +#define DUMMY_PORT_ID 0
72682 +
72683 +#define FM_LIODN_OFFSET_MASK 0x3FF
72684 +
72685 +/**************************************************************************//**
72686 + @Description NIA Description
72687 +*//***************************************************************************/
72688 +#define NIA_ENG_MASK 0x007C0000
72689 +#define NIA_AC_MASK 0x0003ffff
72690 +
72691 +#define NIA_ORDER_RESTOR 0x00800000
72692 +#define NIA_ENG_FM_CTL 0x00000000
72693 +#define NIA_ENG_PRS 0x00440000
72694 +#define NIA_ENG_KG 0x00480000
72695 +#define NIA_ENG_PLCR 0x004C0000
72696 +#define NIA_ENG_BMI 0x00500000
72697 +#define NIA_ENG_QMI_ENQ 0x00540000
72698 +#define NIA_ENG_QMI_DEQ 0x00580000
72699 +
72700 +#define NIA_FM_CTL_AC_CC 0x00000006
72701 +#define NIA_FM_CTL_AC_HC 0x0000000C
72702 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
72703 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
72704 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
72705 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
72706 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
72707 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
72708 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
72709 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
72710 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
72711 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
72712 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
72713 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
72714 +/* V3 only */
72715 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
72716 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
72717 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
72718 +
72719 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
72720 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
72721 +#define NIA_BMI_AC_RELEASE 0x000000C0
72722 +#define NIA_BMI_AC_DISCARD 0x000000C1
72723 +#define NIA_BMI_AC_TX 0x00000274
72724 +#define NIA_BMI_AC_FETCH 0x00000208
72725 +#define NIA_BMI_AC_MASK 0x000003FF
72726 +
72727 +#define NIA_KG_DIRECT 0x00000100
72728 +#define NIA_KG_CC_EN 0x00000200
72729 +#define NIA_PLCR_ABSOLUTE 0x00008000
72730 +
72731 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
72732 +
72733 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
72734 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72735 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72736 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72737 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
72738 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72739 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72740 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72741 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
72742 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72743 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
72744 +#else
72745 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
72746 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72747 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
72748 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
72749 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
72750 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
72751 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
72752 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
72753 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
72754 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
72755 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
72756 +
72757 +/**************************************************************************//**
72758 + @Description CTRL Parameters Page defines
72759 +*//***************************************************************************/
72760 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
72761 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
72762 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
72763 +
72764 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
72765 +
72766 +/**************************************************************************//**
72767 + @Description Port Id defines
72768 +*//***************************************************************************/
72769 +#if (DPAA_VERSION == 10)
72770 +#define BASE_OH_PORTID 1
72771 +#else
72772 +#define BASE_OH_PORTID 2
72773 +#endif /* (DPAA_VERSION == 10) */
72774 +#define BASE_1G_RX_PORTID 8
72775 +#define BASE_10G_RX_PORTID 0x10
72776 +#define BASE_1G_TX_PORTID 0x28
72777 +#define BASE_10G_TX_PORTID 0x30
72778 +
72779 +#define FM_PCD_PORT_OH_BASE_INDX 0
72780 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
72781 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
72782 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
72783 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
72784 +
72785 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
72786 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72787 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
72788 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72789 +#else
72790 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
72791 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
72792 +#endif
72793 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
72794 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72795 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
72796 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72797 +#else
72798 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
72799 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
72800 +#endif
72801 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
72802 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72803 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
72804 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72805 +#else
72806 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
72807 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
72808 +#endif
72809 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
72810 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72811 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
72812 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72813 +#else
72814 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
72815 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
72816 +#endif
72817 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
72818 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72819 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
72820 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72821 +#else
72822 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
72823 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
72824 +#endif
72825 +
72826 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
72827 +
72828 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
72829 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
72830 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72831 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
72832 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72833 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72834 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
72835 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72836 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72837 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
72838 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72839 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72840 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
72841 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72842 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72843 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
72844 + else { \
72845 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
72846 + ASSERT_COND(TRUE); \
72847 + } \
72848 +}
72849 +
72850 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
72851 +do { \
72852 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
72853 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
72854 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
72855 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
72856 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
72857 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
72858 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
72859 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
72860 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
72861 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
72862 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
72863 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
72864 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
72865 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
72866 + else ASSERT_COND(FALSE); \
72867 +} while (0)
72868 +
72869 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
72870 +do { \
72871 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
72872 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
72873 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
72874 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
72875 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72876 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
72877 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
72878 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
72879 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
72880 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
72881 + else ASSERT_COND(FALSE); \
72882 +} while (0)
72883 +
72884 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
72885 +#define BMI_FIFO_UNITS 0x100
72886 +
72887 +typedef struct {
72888 + void (*f_Isr) (t_Handle h_Arg);
72889 + t_Handle h_SrcHandle;
72890 + uint8_t guestId;
72891 +} t_FmIntrSrc;
72892 +
72893 +#define ILLEGAL_HDR_NUM 0xFF
72894 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
72895 +
72896 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
72897 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
72898 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
72899 +
72900 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
72901 +{
72902 + switch (hdr)
72903 + { case (HEADER_TYPE_ETH): return 0;
72904 + case (HEADER_TYPE_LLC_SNAP): return 1;
72905 + case (HEADER_TYPE_VLAN): return 2;
72906 + case (HEADER_TYPE_PPPoE): return 3;
72907 + case (HEADER_TYPE_PPP): return 3;
72908 + case (HEADER_TYPE_MPLS): return 4;
72909 + case (HEADER_TYPE_IPv4): return 5;
72910 + case (HEADER_TYPE_IPv6): return 6;
72911 + case (HEADER_TYPE_GRE): return 7;
72912 + case (HEADER_TYPE_MINENCAP): return 8;
72913 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
72914 + case (HEADER_TYPE_TCP): return 10;
72915 + case (HEADER_TYPE_UDP): return 11;
72916 + case (HEADER_TYPE_IPSEC_AH):
72917 + case (HEADER_TYPE_IPSEC_ESP): return 12;
72918 + case (HEADER_TYPE_SCTP): return 13;
72919 + case (HEADER_TYPE_DCCP): return 14;
72920 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
72921 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
72922 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
72923 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
72924 + default:
72925 + return ILLEGAL_HDR_NUM;
72926 + }
72927 +}
72928 +
72929 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
72930 +
72931 +
72932 +/**************************************************************************//**
72933 + @Description A structure for initializing a keygen classification plan group
72934 +*//***************************************************************************/
72935 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
72936 + uint8_t netEnvId; /* IN */
72937 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
72938 + uint8_t clsPlanGrpId; /* OUT */
72939 + bool emptyClsPlanGrp; /* OUT */
72940 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72941 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72942 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72943 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
72944 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
72945 +} t_FmPcdKgInterModuleClsPlanGrpParams;
72946 +
72947 +typedef struct t_FmPcdLock {
72948 + t_Handle h_Spinlock;
72949 + volatile bool flag;
72950 + t_List node;
72951 +} t_FmPcdLock;
72952 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
72953 +
72954 +
72955 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
72956 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
72957 +
72958 +
72959 +/***********************************************************************/
72960 +/* Common API for FM-PCD module */
72961 +/***********************************************************************/
72962 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
72963 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
72964 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
72965 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
72966 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72967 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
72968 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
72969 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
72970 +uint32_t FmPcdLock(t_Handle h_FmPcd);
72971 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
72972 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
72973 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
72974 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72975 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
72976 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
72977 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
72978 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
72979 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
72980 +t_Handle FmGetPcd(t_Handle h_Fm);
72981 +/***********************************************************************/
72982 +/* Common API for FM-PCD KG module */
72983 +/***********************************************************************/
72984 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72985 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
72986 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
72987 +
72988 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
72989 +#if (DPAA_VERSION >= 11)
72990 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
72991 +#endif /* (DPAA_VERSION >= 11) */
72992 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
72993 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
72994 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
72995 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
72996 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
72997 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
72998 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
72999 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
73000 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
73001 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
73002 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
73003 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
73004 +
73005 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
73006 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
73007 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
73008 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
73009 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
73010 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
73011 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
73012 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
73013 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
73014 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
73015 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
73016 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
73017 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73018 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
73019 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
73020 +
73021 +/***********************************************************************/
73022 +/* Common API for FM-PCD parser module */
73023 +/***********************************************************************/
73024 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
73025 +
73026 +/***********************************************************************/
73027 +/* Common API for FM-PCD policer module */
73028 +/***********************************************************************/
73029 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
73030 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
73031 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73032 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
73033 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
73034 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
73035 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
73036 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
73037 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
73038 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
73039 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
73040 + e_FmPcdProfileTypeSelection profileType,
73041 + t_Handle h_FmPort,
73042 + uint16_t relativeProfile,
73043 + uint16_t *p_AbsoluteId);
73044 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73045 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73046 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
73047 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73048 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73049 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
73050 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
73051 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
73052 +
73053 +/***********************************************************************/
73054 +/* Common API for FM-PCD CC module */
73055 +/***********************************************************************/
73056 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
73057 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
73058 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
73059 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
73060 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask);
73061 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
73062 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73063 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
73064 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
73065 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
73066 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
73067 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73068 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
73069 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
73070 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
73071 +
73072 +/***********************************************************************/
73073 +/* Common API for FM-PCD Manip module */
73074 +/***********************************************************************/
73075 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad, bool validate, int level, t_Handle h_FmTree, bool modify);
73076 +
73077 +/***********************************************************************/
73078 +/* Common API for FM-Port module */
73079 +/***********************************************************************/
73080 +#if (DPAA_VERSION >= 11)
73081 +typedef enum e_FmPortGprFuncType
73082 +{
73083 + e_FM_PORT_GPR_EMPTY = 0,
73084 + e_FM_PORT_GPR_MURAM_PAGE
73085 +} e_FmPortGprFuncType;
73086 +
73087 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
73088 +#endif /* DPAA_VERSION >= 11) */
73089 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
73090 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
73091 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
73092 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
73093 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
73094 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
73095 +
73096 +
73097 +#if (DPAA_VERSION >= 11)
73098 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
73099 +#endif /* (DPAA_VERSION >= 11) */
73100 +
73101 +/**************************************************************************//**
73102 + @Function FmRegisterIntr
73103 +
73104 + @Description Used to register an inter-module event handler to be processed by FM
73105 +
73106 + @Param[in] h_Fm A handle to an FM Module.
73107 + @Param[in] mod The module that causes the event
73108 + @Param[in] modId Module id - if more than 1 instansiation of this
73109 + mode exists,0 otherwise.
73110 + @Param[in] intrType Interrupt type (error/normal) selection.
73111 + @Param[in] f_Isr The interrupt service routine.
73112 + @Param[in] h_Arg Argument to be passed to f_Isr.
73113 +
73114 + @Return None.
73115 +*//***************************************************************************/
73116 +void FmRegisterIntr(t_Handle h_Fm,
73117 + e_FmEventModules mod,
73118 + uint8_t modId,
73119 + e_FmIntrType intrType,
73120 + void (*f_Isr) (t_Handle h_Arg),
73121 + t_Handle h_Arg);
73122 +
73123 +/**************************************************************************//**
73124 + @Function FmUnregisterIntr
73125 +
73126 + @Description Used to un-register an inter-module event handler that was processed by FM
73127 +
73128 + @Param[in] h_Fm A handle to an FM Module.
73129 + @Param[in] mod The module that causes the event
73130 + @Param[in] modId Module id - if more than 1 instansiation of this
73131 + mode exists,0 otherwise.
73132 + @Param[in] intrType Interrupt type (error/normal) selection.
73133 +
73134 + @Return None.
73135 +*//***************************************************************************/
73136 +void FmUnregisterIntr(t_Handle h_Fm,
73137 + e_FmEventModules mod,
73138 + uint8_t modId,
73139 + e_FmIntrType intrType);
73140 +
73141 +/**************************************************************************//**
73142 + @Function FmRegisterFmCtlIntr
73143 +
73144 + @Description Used to register to one of the fmCtl events in the FM module
73145 +
73146 + @Param[in] h_Fm A handle to an FM Module.
73147 + @Param[in] eventRegId FmCtl event id (0-7).
73148 + @Param[in] f_Isr The interrupt service routine.
73149 +
73150 + @Return E_OK on success; Error code otherwise.
73151 +
73152 + @Cautions Allowed only following FM_Init().
73153 +*//***************************************************************************/
73154 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
73155 +
73156 +
73157 +/**************************************************************************//**
73158 + @Description enum for defining MAC types
73159 +*//***************************************************************************/
73160 +typedef enum e_FmMacType {
73161 + e_FM_MAC_10G = 0, /**< 10G MAC */
73162 + e_FM_MAC_1G /**< 1G MAC */
73163 +} e_FmMacType;
73164 +
73165 +/**************************************************************************//**
73166 + @Description Structure for port-FM communication during FM_PORT_Init.
73167 + Fields commented 'IN' are passed by the port module to be used
73168 + by the FM module.
73169 + Fields commented 'OUT' will be filled by FM before returning to port.
73170 + Some fields are optional (depending on configuration) and
73171 + will be analized by the port and FM modules accordingly.
73172 +*//***************************************************************************/
73173 +typedef struct t_FmInterModulePortInitParams {
73174 + uint8_t hardwarePortId; /**< IN. port Id */
73175 + e_FmPortType portType; /**< IN. Port type */
73176 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
73177 + uint16_t liodnOffset; /**< IN. Port's requested resource */
73178 + uint8_t numOfTasks; /**< IN. Port's requested resource */
73179 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
73180 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
73181 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
73182 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
73183 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
73184 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73185 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
73186 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
73187 + LIODN base for this port, to be
73188 + used together with LIODN offset. */
73189 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
73190 +} t_FmInterModulePortInitParams;
73191 +
73192 +/**************************************************************************//**
73193 + @Description Structure for port-FM communication during FM_PORT_Free.
73194 +*//***************************************************************************/
73195 +typedef struct t_FmInterModulePortFreeParams {
73196 + uint8_t hardwarePortId; /**< IN. port Id */
73197 + e_FmPortType portType; /**< IN. Port type */
73198 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
73199 +} t_FmInterModulePortFreeParams;
73200 +
73201 +/**************************************************************************//**
73202 + @Function FmGetPcdPrsBaseAddr
73203 +
73204 + @Description Get the base address of the Parser from the FM module
73205 +
73206 + @Param[in] h_Fm A handle to an FM Module.
73207 +
73208 + @Return Base address.
73209 +*//***************************************************************************/
73210 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
73211 +
73212 +/**************************************************************************//**
73213 + @Function FmGetPcdKgBaseAddr
73214 +
73215 + @Description Get the base address of the Keygen from the FM module
73216 +
73217 + @Param[in] h_Fm A handle to an FM Module.
73218 +
73219 + @Return Base address.
73220 +*//***************************************************************************/
73221 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
73222 +
73223 +/**************************************************************************//**
73224 + @Function FmGetPcdPlcrBaseAddr
73225 +
73226 + @Description Get the base address of the Policer from the FM module
73227 +
73228 + @Param[in] h_Fm A handle to an FM Module.
73229 +
73230 + @Return Base address.
73231 +*//***************************************************************************/
73232 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
73233 +
73234 +/**************************************************************************//**
73235 + @Function FmGetMuramHandle
73236 +
73237 + @Description Get the handle of the MURAM from the FM module
73238 +
73239 + @Param[in] h_Fm A handle to an FM Module.
73240 +
73241 + @Return MURAM module handle.
73242 +*//***************************************************************************/
73243 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
73244 +
73245 +/**************************************************************************//**
73246 + @Function FmGetPhysicalMuramBase
73247 +
73248 + @Description Get the physical base address of the MURAM from the FM module
73249 +
73250 + @Param[in] h_Fm A handle to an FM Module.
73251 + @Param[in] fmPhysAddr Physical MURAM base
73252 +
73253 + @Return Physical base address.
73254 +*//***************************************************************************/
73255 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
73256 +
73257 +/**************************************************************************//**
73258 + @Function FmGetTimeStampScale
73259 +
73260 + @Description Used internally by other modules in order to get the timeStamp
73261 + period as requested by the application.
73262 +
73263 + This function returns bit number that is incremented every 1 usec.
73264 + To calculate timestamp period in nsec, use
73265 + 1000 / (1 << FmGetTimeStampScale()).
73266 +
73267 + @Param[in] h_Fm A handle to an FM Module.
73268 +
73269 + @Return Bit that counts 1 usec.
73270 +
73271 + @Cautions Allowed only following FM_Init().
73272 +*//***************************************************************************/
73273 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
73274 +
73275 +/**************************************************************************//**
73276 + @Function FmResumeStalledPort
73277 +
73278 + @Description Used internally by FM port to release a stalled port.
73279 +
73280 + @Param[in] h_Fm A handle to an FM Module.
73281 + @Param[in] hardwarePortId HW port id.
73282 +
73283 + @Return E_OK on success; Error code otherwise.
73284 +
73285 + @Cautions Allowed only following FM_Init().
73286 +*//***************************************************************************/
73287 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
73288 +
73289 +/**************************************************************************//**
73290 + @Function FmIsPortStalled
73291 +
73292 + @Description Used internally by FM port to read the port's status.
73293 +
73294 + @Param[in] h_Fm A handle to an FM Module.
73295 + @Param[in] hardwarePortId HW port id.
73296 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
73297 +
73298 + @Return E_OK on success; Error code otherwise.
73299 +
73300 + @Cautions Allowed only following FM_Init().
73301 +*//***************************************************************************/
73302 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
73303 +
73304 +/**************************************************************************//**
73305 + @Function FmResetMac
73306 +
73307 + @Description Used by MAC driver to reset the MAC registers
73308 +
73309 + @Param[in] h_Fm A handle to an FM Module.
73310 + @Param[in] type MAC type.
73311 + @Param[in] macId MAC id - according to type.
73312 +
73313 + @Return E_OK on success; Error code otherwise.
73314 +
73315 + @Cautions Allowed only following FM_Init().
73316 +*//***************************************************************************/
73317 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
73318 +
73319 +/**************************************************************************//**
73320 + @Function FmGetClockFreq
73321 +
73322 + @Description Used by MAC driver to get the FM clock frequency
73323 +
73324 + @Param[in] h_Fm A handle to an FM Module.
73325 +
73326 + @Return clock-freq on success; 0 otherwise.
73327 +
73328 + @Cautions Allowed only following FM_Init().
73329 +*//***************************************************************************/
73330 +uint16_t FmGetClockFreq(t_Handle h_Fm);
73331 +
73332 +/**************************************************************************//**
73333 + @Function FmGetMacClockFreq
73334 +
73335 + @Description Used by MAC driver to get the MAC clock frequency
73336 +
73337 + @Param[in] h_Fm A handle to an FM Module.
73338 +
73339 + @Return clock-freq on success; 0 otherwise.
73340 +
73341 + @Cautions Allowed only following FM_Init().
73342 +*//***************************************************************************/
73343 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
73344 +
73345 +/**************************************************************************//**
73346 + @Function FmGetId
73347 +
73348 + @Description Used by PCD driver to read rhe FM id
73349 +
73350 + @Param[in] h_Fm A handle to an FM Module.
73351 +
73352 + @Return E_OK on success; Error code otherwise.
73353 +
73354 + @Cautions Allowed only following FM_Init().
73355 +*//***************************************************************************/
73356 +uint8_t FmGetId(t_Handle h_Fm);
73357 +
73358 +/**************************************************************************//**
73359 + @Function FmReset
73360 +
73361 + @Description Used to reset the FM
73362 +
73363 + @Param[in] h_Fm A handle to an FM Module.
73364 +
73365 + @Return E_OK on success; Error code otherwise.
73366 +*//***************************************************************************/
73367 +t_Error FmReset(t_Handle h_Fm);
73368 +
73369 +/**************************************************************************//**
73370 + @Function FmGetSetPortParams
73371 +
73372 + @Description Used by FM-PORT driver to pass and receive parameters between
73373 + PORT and FM modules.
73374 +
73375 + @Param[in] h_Fm A handle to an FM Module.
73376 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73377 +
73378 + @Return E_OK on success; Error code otherwise.
73379 +
73380 + @Cautions Allowed only following FM_Init().
73381 +*//***************************************************************************/
73382 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
73383 +
73384 +/**************************************************************************//**
73385 + @Function FmFreePortParams
73386 +
73387 + @Description Used by FM-PORT driver to free port's resources within the FM.
73388 +
73389 + @Param[in] h_Fm A handle to an FM Module.
73390 + @Param[in,out] p_PortParams A structure of FM Port parameters.
73391 +
73392 + @Return None.
73393 +
73394 + @Cautions Allowed only following FM_Init().
73395 +*//***************************************************************************/
73396 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
73397 +
73398 +/**************************************************************************//**
73399 + @Function FmSetNumOfRiscsPerPort
73400 +
73401 + @Description Used by FM-PORT driver to pass parameter between
73402 + PORT and FM modules for working with number of RISC..
73403 +
73404 + @Param[in] h_Fm A handle to an FM Module.
73405 + @Param[in] hardwarePortId hardware port Id.
73406 + @Param[in] numOfFmanCtrls number of Fman Controllers.
73407 + @Param[in] orFmanCtrl Fman Controller for order restoration.
73408 +
73409 + @Return None.
73410 +
73411 + @Cautions Allowed only following FM_Init().
73412 +*//***************************************************************************/
73413 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
73414 +
73415 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73416 +/**************************************************************************//*
73417 + @Function FmDumpPortRegs
73418 +
73419 + @Description Dumps FM port registers which are part of FM common registers
73420 +
73421 + @Param[in] h_Fm A handle to an FM Module.
73422 + @Param[in] hardwarePortId HW port id.
73423 +
73424 + @Return E_OK on success; Error code otherwise.
73425 +
73426 + @Cautions Allowed only FM_Init().
73427 +*//***************************************************************************/
73428 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
73429 +#endif /* (defined(DEBUG_ERRORS) && ... */
73430 +
73431 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
73432 +void FmUnregisterPcd(t_Handle h_Fm);
73433 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
73434 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
73435 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
73436 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
73437 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
73438 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
73439 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
73440 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73441 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
73442 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
73443 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
73444 +bool FmIsMaster(t_Handle h_Fm);
73445 +uint8_t FmGetGuestId(t_Handle h_Fm);
73446 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
73447 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
73448 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
73449 +
73450 +
73451 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
73452 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
73453 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
73454 +
73455 +void FmMuramClear(t_Handle h_FmMuram);
73456 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
73457 + uint8_t hardwarePortId,
73458 + uint8_t *p_NumOfOpenDmas,
73459 + uint8_t *p_NumOfExtraOpenDmas,
73460 + bool initialConfig);
73461 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
73462 + uint8_t hardwarePortId,
73463 + uint8_t *p_NumOfTasks,
73464 + uint8_t *p_NumOfExtraTasks,
73465 + bool initialConfig);
73466 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
73467 + uint8_t hardwarePortId,
73468 + uint32_t *p_SizeOfFifo,
73469 + uint32_t *p_ExtraSizeOfFifo,
73470 + bool initialConfig);
73471 +
73472 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
73473 + uint32_t congestionGroupId,
73474 + uint8_t priorityBitMap);
73475 +
73476 +#if (DPAA_VERSION >= 11)
73477 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
73478 + e_FmPortType portType,
73479 + uint8_t portId,
73480 + uint8_t numOfStorageProfiles);
73481 +
73482 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
73483 + e_FmPortType portType,
73484 + uint8_t portId);
73485 +
73486 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
73487 + e_FmPortType portType,
73488 + uint8_t portId,
73489 + uint16_t relativeProfile,
73490 + uint16_t *p_AbsoluteId);
73491 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
73492 + e_FmPortType portType,
73493 + uint8_t portId,
73494 + uint16_t relativeProfile);
73495 +
73496 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
73497 +#endif /* (DPAA_VERSION >= 11) */
73498 +
73499 +
73500 +#endif /* __FM_COMMON_H */
73501 --- /dev/null
73502 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
73503 @@ -0,0 +1,93 @@
73504 +/*
73505 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73506 + *
73507 + * Redistribution and use in source and binary forms, with or without
73508 + * modification, are permitted provided that the following conditions are met:
73509 + * * Redistributions of source code must retain the above copyright
73510 + * notice, this list of conditions and the following disclaimer.
73511 + * * Redistributions in binary form must reproduce the above copyright
73512 + * notice, this list of conditions and the following disclaimer in the
73513 + * documentation and/or other materials provided with the distribution.
73514 + * * Neither the name of Freescale Semiconductor nor the
73515 + * names of its contributors may be used to endorse or promote products
73516 + * derived from this software without specific prior written permission.
73517 + *
73518 + *
73519 + * ALTERNATIVELY, this software may be distributed under the terms of the
73520 + * GNU General Public License ("GPL") as published by the Free Software
73521 + * Foundation, either version 2 of that License or (at your option) any
73522 + * later version.
73523 + *
73524 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73525 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73526 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73527 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73528 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73529 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73530 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73531 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73532 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73533 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73534 + */
73535 +
73536 +
73537 +#ifndef __FM_HC_H
73538 +#define __FM_HC_H
73539 +
73540 +#include "std_ext.h"
73541 +#include "error_ext.h"
73542 +#include "fsl_fman_kg.h"
73543 +
73544 +#define __ERR_MODULE__ MODULE_FM_PCD
73545 +
73546 +
73547 +typedef struct t_FmHcParams {
73548 + t_Handle h_Fm;
73549 + t_Handle h_FmPcd;
73550 + t_FmPcdHcParams params;
73551 +} t_FmHcParams;
73552 +
73553 +
73554 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
73555 +void FmHcFree(t_Handle h_FmHc);
73556 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
73557 + uint8_t memId);
73558 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
73559 +
73560 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
73561 +
73562 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
73563 + t_Handle h_Scheme,
73564 + struct fman_kg_scheme_regs *p_SchemeRegs,
73565 + bool updateCounter);
73566 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
73567 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
73568 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
73569 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
73570 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
73571 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
73572 +
73573 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
73574 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
73575 +
73576 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
73577 +
73578 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
73579 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
73580 +
73581 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
73582 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
73583 +
73584 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
73585 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
73586 +
73587 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
73588 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
73589 +
73590 +t_Error FmHcPcdSync(t_Handle h_FmHc);
73591 +t_Handle FmHcGetPort(t_Handle h_FmHc);
73592 +
73593 +
73594 +
73595 +
73596 +#endif /* __FM_HC_H */
73597 --- /dev/null
73598 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
73599 @@ -0,0 +1,117 @@
73600 +/*
73601 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73602 + *
73603 + * Redistribution and use in source and binary forms, with or without
73604 + * modification, are permitted provided that the following conditions are met:
73605 + * * Redistributions of source code must retain the above copyright
73606 + * notice, this list of conditions and the following disclaimer.
73607 + * * Redistributions in binary form must reproduce the above copyright
73608 + * notice, this list of conditions and the following disclaimer in the
73609 + * documentation and/or other materials provided with the distribution.
73610 + * * Neither the name of Freescale Semiconductor nor the
73611 + * names of its contributors may be used to endorse or promote products
73612 + * derived from this software without specific prior written permission.
73613 + *
73614 + *
73615 + * ALTERNATIVELY, this software may be distributed under the terms of the
73616 + * GNU General Public License ("GPL") as published by the Free Software
73617 + * Foundation, either version 2 of that License or (at your option) any
73618 + * later version.
73619 + *
73620 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73621 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73622 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73623 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73624 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73625 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73626 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73627 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73628 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73629 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73630 + */
73631 +
73632 +
73633 +/******************************************************************************
73634 + @File fm_sp_common.h
73635 +
73636 + @Description FM SP ...
73637 +*//***************************************************************************/
73638 +#ifndef __FM_SP_COMMON_H
73639 +#define __FM_SP_COMMON_H
73640 +
73641 +#include "std_ext.h"
73642 +#include "error_ext.h"
73643 +#include "list_ext.h"
73644 +
73645 +#include "fm_ext.h"
73646 +#include "fm_pcd_ext.h"
73647 +#include "fsl_fman.h"
73648 +
73649 +/**************************************************************************//**
73650 + @Description defaults
73651 +*//***************************************************************************/
73652 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
73653 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
73654 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
73655 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
73656 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
73657 +
73658 +/**************************************************************************//**
73659 + @Description structure for defining internal context copying
73660 +*//***************************************************************************/
73661 +typedef struct
73662 +{
73663 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
73664 + context is copied to (Rx) or taken from (Tx, Op). */
73665 + uint8_t intContextOffset; /**< Offset within internal context to copy from
73666 + (Rx) or to copy to (Tx, Op). */
73667 + uint16_t size; /**< Internal offset size to be copied */
73668 +} t_FmSpIntContextDataCopy;
73669 +
73670 +/**************************************************************************//**
73671 + @Description struct for defining external buffer margins
73672 +*//***************************************************************************/
73673 +typedef struct {
73674 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
73675 + of the external buffer (must be divisible by 16) */
73676 + uint16_t endMargins; /**< number of bytes to be left at the end
73677 + of the external buffer(must be divisible by 16) */
73678 +} t_FmSpBufMargins;
73679 +
73680 +typedef struct {
73681 + uint32_t dataOffset;
73682 + uint32_t prsResultOffset;
73683 + uint32_t timeStampOffset;
73684 + uint32_t hashResultOffset;
73685 + uint32_t pcdInfoOffset;
73686 + uint32_t manipOffset;
73687 +} t_FmSpBufferOffsets;
73688 +
73689 +
73690 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
73691 + t_FmBufferPrefixContent *p_BufferPrefixContent,
73692 + t_FmSpBufMargins *p_FmPortBufMargins,
73693 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
73694 + uint8_t *internalBufferOffset);
73695 +
73696 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
73697 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
73698 + t_FmBackupBmPools *p_FmBackupBmPools,
73699 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
73700 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
73701 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
73702 +
73703 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
73704 + uint8_t hardwarePortId,
73705 + uint16_t numOfStorageProfiles,
73706 + uint16_t *base,
73707 + uint8_t *log2Num);
73708 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
73709 + t_Handle h_FmPort,
73710 + uint16_t relativeProfile,
73711 + uint16_t *p_AbsoluteId);
73712 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73713 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
73714 +
73715 +
73716 +#endif /* __FM_SP_COMMON_H */
73717 --- /dev/null
73718 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
73719 @@ -0,0 +1,12 @@
73720 +#
73721 +# Makefile for the Freescale Ethernet controllers
73722 +#
73723 +ccflags-y += -DVERSION=\"\"
73724 +#
73725 +#Include netcomm SW specific definitions
73726 +
73727 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
73728 +
73729 +obj-y += fsl-ncsw-etc.o
73730 +
73731 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
73732 --- /dev/null
73733 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
73734 @@ -0,0 +1,95 @@
73735 +/*
73736 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73737 + *
73738 + * Redistribution and use in source and binary forms, with or without
73739 + * modification, are permitted provided that the following conditions are met:
73740 + * * Redistributions of source code must retain the above copyright
73741 + * notice, this list of conditions and the following disclaimer.
73742 + * * Redistributions in binary form must reproduce the above copyright
73743 + * notice, this list of conditions and the following disclaimer in the
73744 + * documentation and/or other materials provided with the distribution.
73745 + * * Neither the name of Freescale Semiconductor nor the
73746 + * names of its contributors may be used to endorse or promote products
73747 + * derived from this software without specific prior written permission.
73748 + *
73749 + *
73750 + * ALTERNATIVELY, this software may be distributed under the terms of the
73751 + * GNU General Public License ("GPL") as published by the Free Software
73752 + * Foundation, either version 2 of that License or (at your option) any
73753 + * later version.
73754 + *
73755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73765 + */
73766 +
73767 +
73768 +/*
73769 +
73770 + @File error.c
73771 +
73772 + @Description General errors and events reporting utilities.
73773 +*//***************************************************************************/
73774 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
73775 +#include "error_ext.h"
73776 +
73777 +
73778 +const char *dbgLevelStrings[] =
73779 +{
73780 + "CRITICAL"
73781 + ,"MAJOR"
73782 + ,"MINOR"
73783 + ,"WARNING"
73784 + ,"INFO"
73785 + ,"TRACE"
73786 +};
73787 +
73788 +
73789 +char * ErrTypeStrings (e_ErrorType err)
73790 +{
73791 + switch (err)
73792 + {
73793 + case (E_OK): return "OK";
73794 + case (E_WRITE_FAILED): return "Write Access Failed";
73795 + case (E_NO_DEVICE): return "No Device";
73796 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
73797 + case (E_NO_MEMORY): return "Memory Allocation Failed";
73798 + case (E_INVALID_ADDRESS): return "Invalid Address";
73799 + case (E_BUSY): return "Resource Is Busy";
73800 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
73801 + case (E_INVALID_OPERATION): return "Invalid Operation";
73802 + case (E_INVALID_VALUE): return "Invalid Value";
73803 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
73804 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
73805 + case (E_INVALID_STATE): return "Invalid State";
73806 + case (E_INVALID_HANDLE): return "Invalid Handle";
73807 + case (E_INVALID_ID): return "Invalid ID";
73808 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
73809 + case (E_INVALID_SELECTION): return "Invalid Selection";
73810 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
73811 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
73812 + case (E_INVALID_CLOCK): return "Invalid Clock";
73813 + case (E_CONFLICT): return "Conflict In Settings";
73814 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
73815 + case (E_NOT_FOUND): return "Resource Not Found";
73816 + case (E_FULL): return "Resource Is Full";
73817 + case (E_EMPTY): return "Resource Is Empty";
73818 + case (E_ALREADY_FREE): return "Resource Already Free";
73819 + case (E_READ_FAILED): return "Read Access Failed";
73820 + case (E_INVALID_FRAME): return "Invalid Frame";
73821 + case (E_SEND_FAILED): return "Send Operation Failed";
73822 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
73823 + case (E_TIMEOUT): return "Operation Timed Out";
73824 + default:
73825 + break;
73826 + }
73827 + return NULL;
73828 +}
73829 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
73830 --- /dev/null
73831 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
73832 @@ -0,0 +1,71 @@
73833 +/*
73834 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73835 + *
73836 + * Redistribution and use in source and binary forms, with or without
73837 + * modification, are permitted provided that the following conditions are met:
73838 + * * Redistributions of source code must retain the above copyright
73839 + * notice, this list of conditions and the following disclaimer.
73840 + * * Redistributions in binary form must reproduce the above copyright
73841 + * notice, this list of conditions and the following disclaimer in the
73842 + * documentation and/or other materials provided with the distribution.
73843 + * * Neither the name of Freescale Semiconductor nor the
73844 + * names of its contributors may be used to endorse or promote products
73845 + * derived from this software without specific prior written permission.
73846 + *
73847 + *
73848 + * ALTERNATIVELY, this software may be distributed under the terms of the
73849 + * GNU General Public License ("GPL") as published by the Free Software
73850 + * Foundation, either version 2 of that License or (at your option) any
73851 + * later version.
73852 + *
73853 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73854 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73855 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73856 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73857 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73858 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73859 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73860 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73861 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73862 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73863 + */
73864 +
73865 +
73866 +/**************************************************************************//**
73867 +
73868 + @File list.c
73869 +
73870 + @Description Implementation of list.
73871 +*//***************************************************************************/
73872 +#include "std_ext.h"
73873 +#include "list_ext.h"
73874 +
73875 +
73876 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
73877 +{
73878 + t_List *p_First = LIST_FIRST(p_NewList);
73879 +
73880 + if (p_First != p_NewList)
73881 + {
73882 + t_List *p_Last = LIST_LAST(p_NewList);
73883 + t_List *p_Cur = LIST_NEXT(p_Head);
73884 +
73885 + LIST_PREV(p_First) = p_Head;
73886 + LIST_FIRST(p_Head) = p_First;
73887 + LIST_NEXT(p_Last) = p_Cur;
73888 + LIST_LAST(p_Cur) = p_Last;
73889 + }
73890 +}
73891 +
73892 +
73893 +int LIST_NumOfObjs(t_List *p_List)
73894 +{
73895 + t_List *p_Tmp;
73896 + int numOfObjs = 0;
73897 +
73898 + if (!LIST_IsEmpty(p_List))
73899 + LIST_FOR_EACH(p_Tmp, p_List)
73900 + numOfObjs++;
73901 +
73902 + return numOfObjs;
73903 +}
73904 --- /dev/null
73905 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
73906 @@ -0,0 +1,620 @@
73907 +/*
73908 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73909 + *
73910 + * Redistribution and use in source and binary forms, with or without
73911 + * modification, are permitted provided that the following conditions are met:
73912 + * * Redistributions of source code must retain the above copyright
73913 + * notice, this list of conditions and the following disclaimer.
73914 + * * Redistributions in binary form must reproduce the above copyright
73915 + * notice, this list of conditions and the following disclaimer in the
73916 + * documentation and/or other materials provided with the distribution.
73917 + * * Neither the name of Freescale Semiconductor nor the
73918 + * names of its contributors may be used to endorse or promote products
73919 + * derived from this software without specific prior written permission.
73920 + *
73921 + *
73922 + * ALTERNATIVELY, this software may be distributed under the terms of the
73923 + * GNU General Public License ("GPL") as published by the Free Software
73924 + * Foundation, either version 2 of that License or (at your option) any
73925 + * later version.
73926 + *
73927 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73928 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73929 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73930 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73931 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73932 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73933 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73934 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73935 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73936 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73937 + */
73938 +
73939 +
73940 +
73941 +#include "std_ext.h"
73942 +#include "xx_ext.h"
73943 +#include "memcpy_ext.h"
73944 +
73945 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
73946 +{
73947 + int i;
73948 +
73949 + for(i = 0; i < size; ++i)
73950 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
73951 +
73952 + return pDst;
73953 +}
73954 +
73955 +void * MemSet8(void* pDst, int c, uint32_t size)
73956 +{
73957 + int i;
73958 +
73959 + for(i = 0; i < size; ++i)
73960 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
73961 +
73962 + return pDst;
73963 +}
73964 +
73965 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
73966 +{
73967 + uint32_t leftAlign;
73968 + uint32_t rightAlign;
73969 + uint32_t lastWord;
73970 + uint32_t currWord;
73971 + uint32_t *p_Src32;
73972 + uint32_t *p_Dst32;
73973 + uint8_t *p_Src8;
73974 + uint8_t *p_Dst8;
73975 +
73976 + p_Src8 = (uint8_t*)(pSrc);
73977 + p_Dst8 = (uint8_t*)(pDst);
73978 + /* first copy byte by byte till the source first alignment
73979 + * this step is necessary to ensure we do not even try to access
73980 + * data which is before the source buffer, hence it is not ours.
73981 + */
73982 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
73983 + {
73984 + *p_Dst8++ = *p_Src8++;
73985 + size--;
73986 + }
73987 +
73988 + /* align destination (possibly disaligning source)*/
73989 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
73990 + {
73991 + *p_Dst8++ = *p_Src8++;
73992 + size--;
73993 + }
73994 +
73995 + /* dest is aligned and source is not necessarily aligned */
73996 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
73997 + rightAlign = 32 - leftAlign;
73998 +
73999 +
74000 + if (leftAlign == 0)
74001 + {
74002 + /* source is also aligned */
74003 + p_Src32 = (uint32_t*)(p_Src8);
74004 + p_Dst32 = (uint32_t*)(p_Dst8);
74005 + while (size >> 2) /* size >= 4 */
74006 + {
74007 + *p_Dst32++ = *p_Src32++;
74008 + size -= 4;
74009 + }
74010 + p_Src8 = (uint8_t*)(p_Src32);
74011 + p_Dst8 = (uint8_t*)(p_Dst32);
74012 + }
74013 + else
74014 + {
74015 + /* source is not aligned (destination is aligned)*/
74016 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74017 + p_Dst32 = (uint32_t*)(p_Dst8);
74018 + lastWord = *p_Src32++;
74019 + while(size >> 3) /* size >= 8 */
74020 + {
74021 + currWord = *p_Src32;
74022 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74023 + lastWord = currWord;
74024 + p_Src32++;
74025 + p_Dst32++;
74026 + size -= 4;
74027 + }
74028 + p_Dst8 = (uint8_t*)(p_Dst32);
74029 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74030 + }
74031 +
74032 + /* complete the left overs */
74033 + while (size--)
74034 + *p_Dst8++ = *p_Src8++;
74035 +
74036 + return pDst;
74037 +}
74038 +
74039 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
74040 +{
74041 + uint32_t leftAlign;
74042 + uint32_t rightAlign;
74043 + uint32_t lastWord;
74044 + uint32_t currWord;
74045 + uint32_t *p_Src32;
74046 + uint32_t *p_Dst32;
74047 + uint8_t *p_Src8;
74048 + uint8_t *p_Dst8;
74049 +
74050 + p_Src8 = (uint8_t*)(pSrc);
74051 + p_Dst8 = (uint8_t*)(pDst);
74052 + /* first copy byte by byte till the source first alignment
74053 + * this step is necessary to ensure we do not even try to access
74054 + * data which is before the source buffer, hence it is not ours.
74055 + */
74056 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74057 + {
74058 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74059 + p_Dst8++;p_Src8++;
74060 + size--;
74061 + }
74062 +
74063 + /* align destination (possibly disaligning source)*/
74064 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74065 + {
74066 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74067 + p_Dst8++;p_Src8++;
74068 + size--;
74069 + }
74070 +
74071 + /* dest is aligned and source is not necessarily aligned */
74072 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74073 + rightAlign = 32 - leftAlign;
74074 +
74075 + if (leftAlign == 0)
74076 + {
74077 + /* source is also aligned */
74078 + p_Src32 = (uint32_t*)(p_Src8);
74079 + p_Dst32 = (uint32_t*)(p_Dst8);
74080 + while (size >> 2) /* size >= 4 */
74081 + {
74082 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
74083 + p_Dst32++;p_Src32++;
74084 + size -= 4;
74085 + }
74086 + p_Src8 = (uint8_t*)(p_Src32);
74087 + p_Dst8 = (uint8_t*)(p_Dst32);
74088 + }
74089 + else
74090 + {
74091 + /* source is not aligned (destination is aligned)*/
74092 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74093 + p_Dst32 = (uint32_t*)(p_Dst8);
74094 + lastWord = GET_UINT32(*p_Src32);
74095 + p_Src32++;
74096 + while(size >> 3) /* size >= 8 */
74097 + {
74098 + currWord = GET_UINT32(*p_Src32);
74099 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74100 + lastWord = currWord;
74101 + p_Src32++;p_Dst32++;
74102 + size -= 4;
74103 + }
74104 + p_Dst8 = (uint8_t*)(p_Dst32);
74105 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74106 + }
74107 +
74108 + /* complete the left overs */
74109 + while (size--)
74110 + {
74111 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
74112 + p_Dst8++;p_Src8++;
74113 + }
74114 +
74115 + return pDst;
74116 +}
74117 +
74118 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
74119 +{
74120 + uint32_t leftAlign;
74121 + uint32_t rightAlign;
74122 + uint32_t lastWord;
74123 + uint32_t currWord;
74124 + uint32_t *p_Src32;
74125 + uint32_t *p_Dst32;
74126 + uint8_t *p_Src8;
74127 + uint8_t *p_Dst8;
74128 +
74129 + p_Src8 = (uint8_t*)(pSrc);
74130 + p_Dst8 = (uint8_t*)(pDst);
74131 + /* first copy byte by byte till the source first alignment
74132 + * this step is necessary to ensure we do not even try to access
74133 + * data which is before the source buffer, hence it is not ours.
74134 + */
74135 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74136 + {
74137 + WRITE_UINT8(*p_Dst8, *p_Src8);
74138 + p_Dst8++;p_Src8++;
74139 + size--;
74140 + }
74141 +
74142 + /* align destination (possibly disaligning source)*/
74143 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74144 + {
74145 + WRITE_UINT8(*p_Dst8, *p_Src8);
74146 + p_Dst8++;p_Src8++;
74147 + size--;
74148 + }
74149 +
74150 + /* dest is aligned and source is not necessarily aligned */
74151 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74152 + rightAlign = 32 - leftAlign;
74153 +
74154 + if (leftAlign == 0)
74155 + {
74156 + /* source is also aligned */
74157 + p_Src32 = (uint32_t*)(p_Src8);
74158 + p_Dst32 = (uint32_t*)(p_Dst8);
74159 + while (size >> 2) /* size >= 4 */
74160 + {
74161 + WRITE_UINT32(*p_Dst32, *p_Src32);
74162 + p_Dst32++;p_Src32++;
74163 + size -= 4;
74164 + }
74165 + p_Src8 = (uint8_t*)(p_Src32);
74166 + p_Dst8 = (uint8_t*)(p_Dst32);
74167 + }
74168 + else
74169 + {
74170 + /* source is not aligned (destination is aligned)*/
74171 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74172 + p_Dst32 = (uint32_t*)(p_Dst8);
74173 + lastWord = *p_Src32++;
74174 + while(size >> 3) /* size >= 8 */
74175 + {
74176 + currWord = *p_Src32;
74177 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
74178 + lastWord = currWord;
74179 + p_Src32++;p_Dst32++;
74180 + size -= 4;
74181 + }
74182 + p_Dst8 = (uint8_t*)(p_Dst32);
74183 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74184 + }
74185 +
74186 + /* complete the left overs */
74187 + while (size--)
74188 + {
74189 + WRITE_UINT8(*p_Dst8, *p_Src8);
74190 + p_Dst8++;p_Src8++;
74191 + }
74192 +
74193 + return pDst;
74194 +}
74195 +
74196 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
74197 +{
74198 + uint32_t leftAlign;
74199 + uint32_t rightAlign;
74200 + uint32_t lastWord;
74201 + uint32_t currWord;
74202 + uint32_t *p_Src32;
74203 + uint32_t *p_Dst32;
74204 + uint8_t *p_Src8;
74205 + uint8_t *p_Dst8;
74206 +
74207 + p_Src8 = (uint8_t*)(pSrc);
74208 + p_Dst8 = (uint8_t*)(pDst);
74209 + /* first copy byte by byte till the source first alignment
74210 + * this step is necessary to ensure we do not even try to access
74211 + * data which is before the source buffer, hence it is not ours.
74212 + */
74213 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
74214 + {
74215 + *p_Dst8 = GET_UINT8(*p_Src8);
74216 + p_Dst8++;p_Src8++;
74217 + size--;
74218 + }
74219 +
74220 + /* align destination (possibly disaligning source)*/
74221 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74222 + {
74223 + *p_Dst8 = GET_UINT8(*p_Src8);
74224 + p_Dst8++;p_Src8++;
74225 + size--;
74226 + }
74227 +
74228 + /* dest is aligned and source is not necessarily aligned */
74229 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
74230 + rightAlign = 32 - leftAlign;
74231 +
74232 + if (leftAlign == 0)
74233 + {
74234 + /* source is also aligned */
74235 + p_Src32 = (uint32_t*)(p_Src8);
74236 + p_Dst32 = (uint32_t*)(p_Dst8);
74237 + while (size >> 2) /* size >= 4 */
74238 + {
74239 + *p_Dst32 = GET_UINT32(*p_Src32);
74240 + p_Dst32++;p_Src32++;
74241 + size -= 4;
74242 + }
74243 + p_Src8 = (uint8_t*)(p_Src32);
74244 + p_Dst8 = (uint8_t*)(p_Dst32);
74245 + }
74246 + else
74247 + {
74248 + /* source is not aligned (destination is aligned)*/
74249 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
74250 + p_Dst32 = (uint32_t*)(p_Dst8);
74251 + lastWord = GET_UINT32(*p_Src32);
74252 + p_Src32++;
74253 + while(size >> 3) /* size >= 8 */
74254 + {
74255 + currWord = GET_UINT32(*p_Src32);
74256 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
74257 + lastWord = currWord;
74258 + p_Src32++;p_Dst32++;
74259 + size -= 4;
74260 + }
74261 + p_Dst8 = (uint8_t*)(p_Dst32);
74262 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
74263 + }
74264 +
74265 + /* complete the left overs */
74266 + while (size--)
74267 + {
74268 + *p_Dst8 = GET_UINT8(*p_Src8);
74269 + p_Dst8++;p_Src8++;
74270 + }
74271 +
74272 + return pDst;
74273 +}
74274 +
74275 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
74276 +{
74277 + uint32_t leftAlign;
74278 + uint32_t rightAlign;
74279 + uint64_t lastWord;
74280 + uint64_t currWord;
74281 + uint64_t *pSrc64;
74282 + uint64_t *pDst64;
74283 + uint8_t *p_Src8;
74284 + uint8_t *p_Dst8;
74285 +
74286 + p_Src8 = (uint8_t*)(pSrc);
74287 + p_Dst8 = (uint8_t*)(pDst);
74288 + /* first copy byte by byte till the source first alignment
74289 + * this step is necessarily to ensure we do not even try to access
74290 + * data which is before the source buffer, hence it is not ours.
74291 + */
74292 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
74293 + {
74294 + *p_Dst8++ = *p_Src8++;
74295 + size--;
74296 + }
74297 +
74298 + /* align destination (possibly disaligning source)*/
74299 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74300 + {
74301 + *p_Dst8++ = *p_Src8++;
74302 + size--;
74303 + }
74304 +
74305 + /* dest is aligned and source is not necessarily aligned */
74306 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
74307 + rightAlign = 64 - leftAlign;
74308 +
74309 +
74310 + if (leftAlign == 0)
74311 + {
74312 + /* source is also aligned */
74313 + pSrc64 = (uint64_t*)(p_Src8);
74314 + pDst64 = (uint64_t*)(p_Dst8);
74315 + while (size >> 3) /* size >= 8 */
74316 + {
74317 + *pDst64++ = *pSrc64++;
74318 + size -= 8;
74319 + }
74320 + p_Src8 = (uint8_t*)(pSrc64);
74321 + p_Dst8 = (uint8_t*)(pDst64);
74322 + }
74323 + else
74324 + {
74325 + /* source is not aligned (destination is aligned)*/
74326 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
74327 + pDst64 = (uint64_t*)(p_Dst8);
74328 + lastWord = *pSrc64++;
74329 + while(size >> 4) /* size >= 16 */
74330 + {
74331 + currWord = *pSrc64;
74332 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
74333 + lastWord = currWord;
74334 + pSrc64++;
74335 + pDst64++;
74336 + size -= 8;
74337 + }
74338 + p_Dst8 = (uint8_t*)(pDst64);
74339 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
74340 + }
74341 +
74342 + /* complete the left overs */
74343 + while (size--)
74344 + *p_Dst8++ = *p_Src8++;
74345 +
74346 + return pDst;
74347 +}
74348 +
74349 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
74350 +{
74351 + uint32_t val32;
74352 + uint32_t *p_Dst32;
74353 + uint8_t *p_Dst8;
74354 +
74355 + p_Dst8 = (uint8_t*)(pDst);
74356 +
74357 + /* generate four 8-bit val's in 32-bit container */
74358 + val32 = (uint32_t) val;
74359 + val32 |= (val32 << 8);
74360 + val32 |= (val32 << 16);
74361 +
74362 + /* align destination to 32 */
74363 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74364 + {
74365 + *p_Dst8++ = val;
74366 + size--;
74367 + }
74368 +
74369 + /* 32-bit chunks */
74370 + p_Dst32 = (uint32_t*)(p_Dst8);
74371 + while (size >> 2) /* size >= 4 */
74372 + {
74373 + *p_Dst32++ = val32;
74374 + size -= 4;
74375 + }
74376 +
74377 + /* complete the leftovers */
74378 + p_Dst8 = (uint8_t*)(p_Dst32);
74379 + while (size--)
74380 + *p_Dst8++ = val;
74381 +
74382 + return pDst;
74383 +}
74384 +
74385 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
74386 +{
74387 + uint32_t val32;
74388 + uint32_t *p_Dst32;
74389 + uint8_t *p_Dst8;
74390 +
74391 + p_Dst8 = (uint8_t*)(pDst);
74392 +
74393 + /* generate four 8-bit val's in 32-bit container */
74394 + val32 = (uint32_t) val;
74395 + val32 |= (val32 << 8);
74396 + val32 |= (val32 << 16);
74397 +
74398 + /* align destination to 32 */
74399 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
74400 + {
74401 + WRITE_UINT8(*p_Dst8, val);
74402 + p_Dst8++;
74403 + size--;
74404 + }
74405 +
74406 + /* 32-bit chunks */
74407 + p_Dst32 = (uint32_t*)(p_Dst8);
74408 + while (size >> 2) /* size >= 4 */
74409 + {
74410 + WRITE_UINT32(*p_Dst32, val32);
74411 + p_Dst32++;
74412 + size -= 4;
74413 + }
74414 +
74415 + /* complete the leftovers */
74416 + p_Dst8 = (uint8_t*)(p_Dst32);
74417 + while (size--)
74418 + {
74419 + WRITE_UINT8(*p_Dst8, val);
74420 + p_Dst8++;
74421 + }
74422 +
74423 + return pDst;
74424 +}
74425 +
74426 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
74427 +{
74428 + uint64_t val64;
74429 + uint64_t *pDst64;
74430 + uint8_t *p_Dst8;
74431 +
74432 + p_Dst8 = (uint8_t*)(pDst);
74433 +
74434 + /* generate four 8-bit val's in 32-bit container */
74435 + val64 = (uint64_t) val;
74436 + val64 |= (val64 << 8);
74437 + val64 |= (val64 << 16);
74438 + val64 |= (val64 << 24);
74439 + val64 |= (val64 << 32);
74440 +
74441 + /* align destination to 64 */
74442 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
74443 + {
74444 + *p_Dst8++ = val;
74445 + size--;
74446 + }
74447 +
74448 + /* 64-bit chunks */
74449 + pDst64 = (uint64_t*)(p_Dst8);
74450 + while (size >> 4) /* size >= 8 */
74451 + {
74452 + *pDst64++ = val64;
74453 + size -= 8;
74454 + }
74455 +
74456 + /* complete the leftovers */
74457 + p_Dst8 = (uint8_t*)(pDst64);
74458 + while (size--)
74459 + *p_Dst8++ = val;
74460 +
74461 + return pDst;
74462 +}
74463 +
74464 +void MemDisp(uint8_t *p, int size)
74465 +{
74466 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
74467 + uint8_t *p_Limit;
74468 +
74469 + if (space)
74470 + {
74471 + p_Limit = (p - space + 4);
74472 +
74473 + XX_Print("0x%08X: ", (p - space));
74474 +
74475 + while (space--)
74476 + {
74477 + XX_Print("--");
74478 + }
74479 + while (size && (p < p_Limit))
74480 + {
74481 + XX_Print("%02x", *(uint8_t*)p);
74482 + size--;
74483 + p++;
74484 + }
74485 +
74486 + XX_Print(" ");
74487 + p_Limit += 12;
74488 +
74489 + while ((size > 3) && (p < p_Limit))
74490 + {
74491 + XX_Print("%08x ", *(uint32_t*)p);
74492 + size -= 4;
74493 + p += 4;
74494 + }
74495 + XX_Print("\r\n");
74496 + }
74497 +
74498 + while (size > 15)
74499 + {
74500 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
74501 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
74502 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
74503 + size -= 16;
74504 + p += 16;
74505 + }
74506 +
74507 + if (size)
74508 + {
74509 + XX_Print("0x%08X: ", p);
74510 +
74511 + while (size > 3)
74512 + {
74513 + XX_Print("%08x ", *(uint32_t *)p);
74514 + size -= 4;
74515 + p += 4;
74516 + }
74517 + while (size)
74518 + {
74519 + XX_Print("%02x", *(uint8_t *)p);
74520 + size--;
74521 + p++;
74522 + }
74523 +
74524 + XX_Print("\r\n");
74525 + }
74526 +}
74527 --- /dev/null
74528 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
74529 @@ -0,0 +1,1155 @@
74530 +/*
74531 + * Copyright 2008-2012 Freescale Semiconductor Inc.
74532 + *
74533 + * Redistribution and use in source and binary forms, with or without
74534 + * modification, are permitted provided that the following conditions are met:
74535 + * * Redistributions of source code must retain the above copyright
74536 + * notice, this list of conditions and the following disclaimer.
74537 + * * Redistributions in binary form must reproduce the above copyright
74538 + * notice, this list of conditions and the following disclaimer in the
74539 + * documentation and/or other materials provided with the distribution.
74540 + * * Neither the name of Freescale Semiconductor nor the
74541 + * names of its contributors may be used to endorse or promote products
74542 + * derived from this software without specific prior written permission.
74543 + *
74544 + *
74545 + * ALTERNATIVELY, this software may be distributed under the terms of the
74546 + * GNU General Public License ("GPL") as published by the Free Software
74547 + * Foundation, either version 2 of that License or (at your option) any
74548 + * later version.
74549 + *
74550 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
74551 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
74552 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
74553 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
74554 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
74555 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
74556 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
74557 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
74558 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
74559 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74560 + */
74561 +
74562 +
74563 +#include "string_ext.h"
74564 +#include "error_ext.h"
74565 +#include "std_ext.h"
74566 +#include "part_ext.h"
74567 +#include "xx_ext.h"
74568 +
74569 +#include "mm.h"
74570 +
74571 +
74572 +
74573 +
74574 +/**********************************************************************
74575 + * MM internal routines set *
74576 + **********************************************************************/
74577 +
74578 +/****************************************************************
74579 + * Routine: CreateBusyBlock
74580 + *
74581 + * Description:
74582 + * Initializes a new busy block of "size" bytes and started
74583 + * rom "base" address. Each busy block has a name that
74584 + * specified the purpose of the memory allocation.
74585 + *
74586 + * Arguments:
74587 + * base - base address of the busy block
74588 + * size - size of the busy block
74589 + * name - name that specified the busy block
74590 + *
74591 + * Return value:
74592 + * A pointer to new created structure returned on success;
74593 + * Otherwise, NULL.
74594 + ****************************************************************/
74595 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
74596 +{
74597 + t_BusyBlock *p_BusyBlock;
74598 + uint32_t n;
74599 +
74600 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
74601 + if ( !p_BusyBlock )
74602 + {
74603 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74604 + return NULL;
74605 + }
74606 +
74607 + p_BusyBlock->base = base;
74608 + p_BusyBlock->end = base + size;
74609 +
74610 + n = strlen(name);
74611 + if (n >= MM_MAX_NAME_LEN)
74612 + n = MM_MAX_NAME_LEN - 1;
74613 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
74614 + p_BusyBlock->name[n] = '\0';
74615 + p_BusyBlock->p_Next = 0;
74616 +
74617 + return p_BusyBlock;
74618 +}
74619 +
74620 +/****************************************************************
74621 + * Routine: CreateNewBlock
74622 + *
74623 + * Description:
74624 + * Initializes a new memory block of "size" bytes and started
74625 + * from "base" address.
74626 + *
74627 + * Arguments:
74628 + * base - base address of the memory block
74629 + * size - size of the memory block
74630 + *
74631 + * Return value:
74632 + * A pointer to new created structure returned on success;
74633 + * Otherwise, NULL.
74634 + ****************************************************************/
74635 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
74636 +{
74637 + t_MemBlock *p_MemBlock;
74638 +
74639 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
74640 + if ( !p_MemBlock )
74641 + {
74642 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74643 + return NULL;
74644 + }
74645 +
74646 + p_MemBlock->base = base;
74647 + p_MemBlock->end = base+size;
74648 + p_MemBlock->p_Next = 0;
74649 +
74650 + return p_MemBlock;
74651 +}
74652 +
74653 +/****************************************************************
74654 + * Routine: CreateFreeBlock
74655 + *
74656 + * Description:
74657 + * Initializes a new free block of of "size" bytes and
74658 + * started from "base" address.
74659 + *
74660 + * Arguments:
74661 + * base - base address of the free block
74662 + * size - size of the free block
74663 + *
74664 + * Return value:
74665 + * A pointer to new created structure returned on success;
74666 + * Otherwise, NULL.
74667 + ****************************************************************/
74668 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
74669 +{
74670 + t_FreeBlock *p_FreeBlock;
74671 +
74672 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
74673 + if ( !p_FreeBlock )
74674 + {
74675 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74676 + return NULL;
74677 + }
74678 +
74679 + p_FreeBlock->base = base;
74680 + p_FreeBlock->end = base + size;
74681 + p_FreeBlock->p_Next = 0;
74682 +
74683 + return p_FreeBlock;
74684 +}
74685 +
74686 +/****************************************************************
74687 + * Routine: AddFree
74688 + *
74689 + * Description:
74690 + * Adds a new free block to the free lists. It updates each
74691 + * free list to include a new free block.
74692 + * Note, that all free block in each free list are ordered
74693 + * by their base address.
74694 + *
74695 + * Arguments:
74696 + * p_MM - pointer to the MM object
74697 + * base - base address of a given free block
74698 + * end - end address of a given free block
74699 + *
74700 + * Return value:
74701 + *
74702 + *
74703 + ****************************************************************/
74704 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
74705 +{
74706 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74707 + uint64_t alignment;
74708 + uint64_t alignBase;
74709 + int i;
74710 +
74711 + /* Updates free lists to include a just released block */
74712 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74713 + {
74714 + p_PrevB = p_NewB = 0;
74715 + p_CurrB = p_MM->freeBlocks[i];
74716 +
74717 + alignment = (uint64_t)(0x1 << i);
74718 + alignBase = MAKE_ALIGNED(base, alignment);
74719 +
74720 + /* Goes to the next free list if there is no block to free */
74721 + if (alignBase >= end)
74722 + continue;
74723 +
74724 + /* Looks for a free block that should be updated */
74725 + while ( p_CurrB )
74726 + {
74727 + if ( alignBase <= p_CurrB->end )
74728 + {
74729 + if ( end > p_CurrB->end )
74730 + {
74731 + t_FreeBlock *p_NextB;
74732 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
74733 + {
74734 + p_NextB = p_CurrB->p_Next;
74735 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74736 + XX_Free(p_NextB);
74737 + }
74738 +
74739 + p_NextB = p_CurrB->p_Next;
74740 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
74741 + {
74742 + p_CurrB->end = end;
74743 + }
74744 + else
74745 + {
74746 + p_CurrB->end = p_NextB->end;
74747 + p_CurrB->p_Next = p_NextB->p_Next;
74748 + XX_Free(p_NextB);
74749 + }
74750 + }
74751 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
74752 + {
74753 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74754 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74755 +
74756 + p_NewB->p_Next = p_CurrB;
74757 + if (p_PrevB)
74758 + p_PrevB->p_Next = p_NewB;
74759 + else
74760 + p_MM->freeBlocks[i] = p_NewB;
74761 + break;
74762 + }
74763 +
74764 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
74765 + {
74766 + p_CurrB->base = alignBase;
74767 + }
74768 +
74769 + /* if size of the free block is less then alignment
74770 + * deletes that free block from the free list. */
74771 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
74772 + {
74773 + if ( p_PrevB )
74774 + p_PrevB->p_Next = p_CurrB->p_Next;
74775 + else
74776 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74777 + XX_Free(p_CurrB);
74778 + p_CurrB = NULL;
74779 + }
74780 + break;
74781 + }
74782 + else
74783 + {
74784 + p_PrevB = p_CurrB;
74785 + p_CurrB = p_CurrB->p_Next;
74786 + }
74787 + }
74788 +
74789 + /* If no free block found to be updated, insert a new free block
74790 + * to the end of the free list.
74791 + */
74792 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
74793 + {
74794 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
74795 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74796 +
74797 + if (p_PrevB)
74798 + p_PrevB->p_Next = p_NewB;
74799 + else
74800 + p_MM->freeBlocks[i] = p_NewB;
74801 + }
74802 +
74803 + /* Update boundaries of the new free block */
74804 + if ((alignment == 1) && !p_NewB)
74805 + {
74806 + if ( p_CurrB && base > p_CurrB->base )
74807 + base = p_CurrB->base;
74808 + if ( p_CurrB && end < p_CurrB->end )
74809 + end = p_CurrB->end;
74810 + }
74811 + }
74812 +
74813 + return (E_OK);
74814 +}
74815 +
74816 +/****************************************************************
74817 + * Routine: CutFree
74818 + *
74819 + * Description:
74820 + * Cuts a free block from holdBase to holdEnd from the free lists.
74821 + * That is, it updates all free lists of the MM object do
74822 + * not include a block of memory from holdBase to holdEnd.
74823 + * For each free lists it seek for a free block that holds
74824 + * either holdBase or holdEnd. If such block is found it updates it.
74825 + *
74826 + * Arguments:
74827 + * p_MM - pointer to the MM object
74828 + * holdBase - base address of the allocated block
74829 + * holdEnd - end address of the allocated block
74830 + *
74831 + * Return value:
74832 + * E_OK is returned on success,
74833 + * otherwise returns an error code.
74834 + *
74835 + ****************************************************************/
74836 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
74837 +{
74838 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
74839 + uint64_t alignBase, base, end;
74840 + uint64_t alignment;
74841 + int i;
74842 +
74843 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
74844 + {
74845 + p_PrevB = p_NewB = 0;
74846 + p_CurrB = p_MM->freeBlocks[i];
74847 +
74848 + alignment = (uint64_t)(0x1 << i);
74849 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
74850 +
74851 + while ( p_CurrB )
74852 + {
74853 + base = p_CurrB->base;
74854 + end = p_CurrB->end;
74855 +
74856 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
74857 + {
74858 + if ( alignBase >= end ||
74859 + (alignBase < end && ((end-alignBase) < alignment)) )
74860 + {
74861 + if (p_PrevB)
74862 + p_PrevB->p_Next = p_CurrB->p_Next;
74863 + else
74864 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74865 + XX_Free(p_CurrB);
74866 + }
74867 + else
74868 + {
74869 + p_CurrB->base = alignBase;
74870 + }
74871 + break;
74872 + }
74873 + else if ( (holdBase > base) && (holdEnd <= end) )
74874 + {
74875 + if ( (holdBase-base) >= alignment )
74876 + {
74877 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74878 + {
74879 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
74880 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
74881 + p_NewB->p_Next = p_CurrB->p_Next;
74882 + p_CurrB->p_Next = p_NewB;
74883 + }
74884 + p_CurrB->end = holdBase;
74885 + }
74886 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
74887 + {
74888 + p_CurrB->base = alignBase;
74889 + }
74890 + else
74891 + {
74892 + if (p_PrevB)
74893 + p_PrevB->p_Next = p_CurrB->p_Next;
74894 + else
74895 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
74896 + XX_Free(p_CurrB);
74897 + }
74898 + break;
74899 + }
74900 + else
74901 + {
74902 + p_PrevB = p_CurrB;
74903 + p_CurrB = p_CurrB->p_Next;
74904 + }
74905 + }
74906 + }
74907 +
74908 + return (E_OK);
74909 +}
74910 +
74911 +/****************************************************************
74912 + * Routine: AddBusy
74913 + *
74914 + * Description:
74915 + * Adds a new busy block to the list of busy blocks. Note,
74916 + * that all busy blocks are ordered by their base address in
74917 + * the busy list.
74918 + *
74919 + * Arguments:
74920 + * MM - handler to the MM object
74921 + * p_NewBusyB - pointer to the a busy block
74922 + *
74923 + * Return value:
74924 + * None.
74925 + *
74926 + ****************************************************************/
74927 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
74928 +{
74929 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
74930 +
74931 + /* finds a place of a new busy block in the list of busy blocks */
74932 + p_PrevBusyB = 0;
74933 + p_CurrBusyB = p_MM->busyBlocks;
74934 +
74935 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
74936 + {
74937 + p_PrevBusyB = p_CurrBusyB;
74938 + p_CurrBusyB = p_CurrBusyB->p_Next;
74939 + }
74940 +
74941 + /* insert the new busy block into the list of busy blocks */
74942 + if ( p_CurrBusyB )
74943 + p_NewBusyB->p_Next = p_CurrBusyB;
74944 + if ( p_PrevBusyB )
74945 + p_PrevBusyB->p_Next = p_NewBusyB;
74946 + else
74947 + p_MM->busyBlocks = p_NewBusyB;
74948 +}
74949 +
74950 +/****************************************************************
74951 + * Routine: CutBusy
74952 + *
74953 + * Description:
74954 + * Cuts a block from base to end from the list of busy blocks.
74955 + * This is done by updating the list of busy blocks do not
74956 + * include a given block, that block is going to be free. If a
74957 + * given block is a part of some other busy block, so that
74958 + * busy block is updated. If there are number of busy blocks
74959 + * included in the given block, so all that blocks are removed
74960 + * from the busy list and the end blocks are updated.
74961 + * If the given block devides some block into two parts, a new
74962 + * busy block is added to the busy list.
74963 + *
74964 + * Arguments:
74965 + * p_MM - pointer to the MM object
74966 + * base - base address of a given busy block
74967 + * end - end address of a given busy block
74968 + *
74969 + * Return value:
74970 + * E_OK on success, E_NOMEMORY otherwise.
74971 + *
74972 + ****************************************************************/
74973 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
74974 +{
74975 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
74976 +
74977 + p_CurrB = p_MM->busyBlocks;
74978 + p_PrevB = p_NewB = 0;
74979 +
74980 + while ( p_CurrB )
74981 + {
74982 + if ( base < p_CurrB->end )
74983 + {
74984 + if ( end > p_CurrB->end )
74985 + {
74986 + t_BusyBlock *p_NextB;
74987 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
74988 + {
74989 + p_NextB = p_CurrB->p_Next;
74990 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
74991 + XX_Free(p_NextB);
74992 + }
74993 +
74994 + p_NextB = p_CurrB->p_Next;
74995 + if ( p_NextB && end > p_NextB->base )
74996 + {
74997 + p_NextB->base = end;
74998 + }
74999 + }
75000 +
75001 + if ( base <= p_CurrB->base )
75002 + {
75003 + if ( end < p_CurrB->end && end > p_CurrB->base )
75004 + {
75005 + p_CurrB->base = end;
75006 + }
75007 + else if ( end >= p_CurrB->end )
75008 + {
75009 + if ( p_PrevB )
75010 + p_PrevB->p_Next = p_CurrB->p_Next;
75011 + else
75012 + p_MM->busyBlocks = p_CurrB->p_Next;
75013 + XX_Free(p_CurrB);
75014 + }
75015 + }
75016 + else
75017 + {
75018 + if ( end < p_CurrB->end && end > p_CurrB->base )
75019 + {
75020 + if ((p_NewB = CreateBusyBlock(end,
75021 + p_CurrB->end-end,
75022 + p_CurrB->name)) == NULL)
75023 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75024 + p_NewB->p_Next = p_CurrB->p_Next;
75025 + p_CurrB->p_Next = p_NewB;
75026 + }
75027 + p_CurrB->end = base;
75028 + }
75029 + break;
75030 + }
75031 + else
75032 + {
75033 + p_PrevB = p_CurrB;
75034 + p_CurrB = p_CurrB->p_Next;
75035 + }
75036 + }
75037 +
75038 + return (E_OK);
75039 +}
75040 +
75041 +/****************************************************************
75042 + * Routine: MmGetGreaterAlignment
75043 + *
75044 + * Description:
75045 + * Allocates a block of memory according to the given size
75046 + * and the alignment. That routine is called from the MM_Get
75047 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
75048 + * In that case, it goes over free blocks of 64 byte align list
75049 + * and checks if it has the required size of bytes of the required
75050 + * alignment. If no blocks found returns ILLEGAL_BASE.
75051 + * After the block is found and data is allocated, it calls
75052 + * the internal CutFree routine to update all free lists
75053 + * do not include a just allocated block. Of course, each
75054 + * free list contains a free blocks with the same alignment.
75055 + * It is also creates a busy block that holds
75056 + * information about an allocated block.
75057 + *
75058 + * Arguments:
75059 + * MM - handle to the MM object
75060 + * size - size of the MM
75061 + * alignment - index as a power of two defines
75062 + * a required alignment that is greater then 64.
75063 + * name - the name that specifies an allocated block.
75064 + *
75065 + * Return value:
75066 + * base address of an allocated block.
75067 + * ILLEGAL_BASE if can't allocate a block
75068 + *
75069 + ****************************************************************/
75070 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
75071 +{
75072 + t_FreeBlock *p_FreeB;
75073 + t_BusyBlock *p_NewBusyB;
75074 + uint64_t holdBase, holdEnd, alignBase = 0;
75075 +
75076 + /* goes over free blocks of the 64 byte alignment list
75077 + and look for a block of the suitable size and
75078 + base address according to the alignment. */
75079 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
75080 +
75081 + while ( p_FreeB )
75082 + {
75083 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
75084 +
75085 + /* the block is found if the aligned base inside the block
75086 + * and has the anough size. */
75087 + if ( alignBase >= p_FreeB->base &&
75088 + alignBase < p_FreeB->end &&
75089 + size <= (p_FreeB->end - alignBase) )
75090 + break;
75091 + else
75092 + p_FreeB = p_FreeB->p_Next;
75093 + }
75094 +
75095 + /* If such block isn't found */
75096 + if ( !p_FreeB )
75097 + return (uint64_t)(ILLEGAL_BASE);
75098 +
75099 + holdBase = alignBase;
75100 + holdEnd = alignBase + size;
75101 +
75102 + /* init a new busy block */
75103 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75104 + return (uint64_t)(ILLEGAL_BASE);
75105 +
75106 + /* calls Update routine to update a lists of free blocks */
75107 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75108 + {
75109 + XX_Free(p_NewBusyB);
75110 + return (uint64_t)(ILLEGAL_BASE);
75111 + }
75112 +
75113 + /* insert the new busy block into the list of busy blocks */
75114 + AddBusy ( p_MM, p_NewBusyB );
75115 +
75116 + return (holdBase);
75117 +}
75118 +
75119 +
75120 +/**********************************************************************
75121 + * MM API routines set *
75122 + **********************************************************************/
75123 +
75124 +/*****************************************************************************/
75125 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
75126 +{
75127 + t_MM *p_MM;
75128 + uint64_t newBase, newSize;
75129 + int i;
75130 +
75131 + if (!size)
75132 + {
75133 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
75134 + }
75135 +
75136 + /* Initializes a new MM object */
75137 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
75138 + if (!p_MM)
75139 + {
75140 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75141 + }
75142 +
75143 + p_MM->h_Spinlock = XX_InitSpinlock();
75144 + if (!p_MM->h_Spinlock)
75145 + {
75146 + XX_Free(p_MM);
75147 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
75148 + }
75149 +
75150 + /* Initializes counter of free memory to total size */
75151 + p_MM->freeMemSize = size;
75152 +
75153 + /* A busy list is empty */
75154 + p_MM->busyBlocks = 0;
75155 +
75156 + /* Initializes a new memory block */
75157 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
75158 + {
75159 + MM_Free(p_MM);
75160 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75161 + }
75162 +
75163 + /* Initializes a new free block for each free list*/
75164 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75165 + {
75166 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
75167 + newSize = size - (newBase - base);
75168 +
75169 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
75170 + {
75171 + MM_Free(p_MM);
75172 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75173 + }
75174 + }
75175 +
75176 + *h_MM = p_MM;
75177 +
75178 + return (E_OK);
75179 +}
75180 +
75181 +/*****************************************************************************/
75182 +void MM_Free(t_Handle h_MM)
75183 +{
75184 + t_MM *p_MM = (t_MM *)h_MM;
75185 + t_MemBlock *p_MemBlock;
75186 + t_BusyBlock *p_BusyBlock;
75187 + t_FreeBlock *p_FreeBlock;
75188 + void *p_Block;
75189 + int i;
75190 +
75191 + ASSERT_COND(p_MM);
75192 +
75193 + /* release memory allocated for busy blocks */
75194 + p_BusyBlock = p_MM->busyBlocks;
75195 + while ( p_BusyBlock )
75196 + {
75197 + p_Block = p_BusyBlock;
75198 + p_BusyBlock = p_BusyBlock->p_Next;
75199 + XX_Free(p_Block);
75200 + }
75201 +
75202 + /* release memory allocated for free blocks */
75203 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75204 + {
75205 + p_FreeBlock = p_MM->freeBlocks[i];
75206 + while ( p_FreeBlock )
75207 + {
75208 + p_Block = p_FreeBlock;
75209 + p_FreeBlock = p_FreeBlock->p_Next;
75210 + XX_Free(p_Block);
75211 + }
75212 + }
75213 +
75214 + /* release memory allocated for memory blocks */
75215 + p_MemBlock = p_MM->memBlocks;
75216 + while ( p_MemBlock )
75217 + {
75218 + p_Block = p_MemBlock;
75219 + p_MemBlock = p_MemBlock->p_Next;
75220 + XX_Free(p_Block);
75221 + }
75222 +
75223 + if (p_MM->h_Spinlock)
75224 + XX_FreeSpinlock(p_MM->h_Spinlock);
75225 +
75226 + /* release memory allocated for MM object itself */
75227 + XX_Free(p_MM);
75228 +}
75229 +
75230 +/*****************************************************************************/
75231 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
75232 +{
75233 + t_MM *p_MM = (t_MM *)h_MM;
75234 + t_FreeBlock *p_FreeB;
75235 + t_BusyBlock *p_NewBusyB;
75236 + uint64_t holdBase, holdEnd, j, i = 0;
75237 + uint32_t intFlags;
75238 +
75239 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
75240 +
75241 + /* checks that alignment value is greater then zero */
75242 + if (alignment == 0)
75243 + {
75244 + alignment = 1;
75245 + }
75246 +
75247 + j = alignment;
75248 +
75249 + /* checks if alignment is a power of two, if it correct and if the
75250 + required size is multiple of the given alignment. */
75251 + while ((j & 0x1) == 0)
75252 + {
75253 + i++;
75254 + j = j >> 1;
75255 + }
75256 +
75257 + /* if the given alignment isn't power of two, returns an error */
75258 + if (j != 1)
75259 + {
75260 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
75261 + return (uint64_t)ILLEGAL_BASE;
75262 + }
75263 +
75264 + if (i > MM_MAX_ALIGNMENT)
75265 + {
75266 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
75267 + }
75268 +
75269 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75270 + /* look for a block of the size greater or equal to the required size. */
75271 + p_FreeB = p_MM->freeBlocks[i];
75272 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
75273 + p_FreeB = p_FreeB->p_Next;
75274 +
75275 + /* If such block is found */
75276 + if ( !p_FreeB )
75277 + {
75278 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75279 + return (uint64_t)(ILLEGAL_BASE);
75280 + }
75281 +
75282 + holdBase = p_FreeB->base;
75283 + holdEnd = holdBase + size;
75284 +
75285 + /* init a new busy block */
75286 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75287 + {
75288 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75289 + return (uint64_t)(ILLEGAL_BASE);
75290 + }
75291 +
75292 + /* calls Update routine to update a lists of free blocks */
75293 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
75294 + {
75295 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75296 + XX_Free(p_NewBusyB);
75297 + return (uint64_t)(ILLEGAL_BASE);
75298 + }
75299 +
75300 + /* Decreasing the allocated memory size from free memory size */
75301 + p_MM->freeMemSize -= size;
75302 +
75303 + /* insert the new busy block into the list of busy blocks */
75304 + AddBusy ( p_MM, p_NewBusyB );
75305 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75306 +
75307 + return (holdBase);
75308 +}
75309 +
75310 +/*****************************************************************************/
75311 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
75312 +{
75313 + t_MM *p_MM = (t_MM *)h_MM;
75314 + t_FreeBlock *p_FreeB;
75315 + t_BusyBlock *p_NewBusyB;
75316 + uint32_t intFlags;
75317 + bool blockIsFree = FALSE;
75318 +
75319 + ASSERT_COND(p_MM);
75320 +
75321 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75322 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
75323 + free list with alignment 1 */
75324 +
75325 + while ( p_FreeB )
75326 + {
75327 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
75328 + {
75329 + blockIsFree = TRUE;
75330 + break;
75331 + }
75332 + else
75333 + p_FreeB = p_FreeB->p_Next;
75334 + }
75335 +
75336 + if ( !blockIsFree )
75337 + {
75338 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75339 + return (uint64_t)(ILLEGAL_BASE);
75340 + }
75341 +
75342 + /* init a new busy block */
75343 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
75344 + {
75345 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75346 + return (uint64_t)(ILLEGAL_BASE);
75347 + }
75348 +
75349 + /* calls Update routine to update a lists of free blocks */
75350 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
75351 + {
75352 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75353 + XX_Free(p_NewBusyB);
75354 + return (uint64_t)(ILLEGAL_BASE);
75355 + }
75356 +
75357 + /* Decreasing the allocated memory size from free memory size */
75358 + p_MM->freeMemSize -= size;
75359 +
75360 + /* insert the new busy block into the list of busy blocks */
75361 + AddBusy ( p_MM, p_NewBusyB );
75362 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75363 +
75364 + return (base);
75365 +}
75366 +
75367 +/*****************************************************************************/
75368 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
75369 +{
75370 + t_MM *p_MM = (t_MM *)h_MM;
75371 + t_FreeBlock *p_FreeB;
75372 + t_BusyBlock *p_NewBusyB;
75373 + uint64_t holdBase, holdEnd, j = alignment, i=0;
75374 + uint32_t intFlags;
75375 +
75376 + ASSERT_COND(p_MM);
75377 +
75378 + /* checks if alignment is a power of two, if it correct and if the
75379 + required size is multiple of the given alignment. */
75380 + while ((j & 0x1) == 0)
75381 + {
75382 + i++;
75383 + j = j >> 1;
75384 + }
75385 +
75386 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
75387 + {
75388 + return (uint64_t)(ILLEGAL_BASE);
75389 + }
75390 +
75391 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75392 + p_FreeB = p_MM->freeBlocks[i];
75393 +
75394 + /* look for the first block that contains the minimum
75395 + base address. If the whole required size may be fit
75396 + into it, use that block, otherwise look for the next
75397 + block of size greater or equal to the required size. */
75398 + while ( p_FreeB && (min >= p_FreeB->end))
75399 + p_FreeB = p_FreeB->p_Next;
75400 +
75401 + /* If such block is found */
75402 + if ( !p_FreeB )
75403 + {
75404 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75405 + return (uint64_t)(ILLEGAL_BASE);
75406 + }
75407 +
75408 + /* if this block is large enough, use this block */
75409 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
75410 + if ((holdBase + size) <= p_FreeB->end )
75411 + {
75412 + holdEnd = holdBase + size;
75413 + }
75414 + else
75415 + {
75416 + p_FreeB = p_FreeB->p_Next;
75417 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
75418 + p_FreeB = p_FreeB->p_Next;
75419 +
75420 + /* If such block is found */
75421 + if ( !p_FreeB )
75422 + {
75423 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75424 + return (uint64_t)(ILLEGAL_BASE);
75425 + }
75426 +
75427 + holdBase = p_FreeB->base;
75428 + holdEnd = holdBase + size;
75429 + }
75430 +
75431 + /* init a new busy block */
75432 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
75433 + {
75434 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75435 + return (uint64_t)(ILLEGAL_BASE);
75436 + }
75437 +
75438 + /* calls Update routine to update a lists of free blocks */
75439 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
75440 + {
75441 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75442 + XX_Free(p_NewBusyB);
75443 + return (uint64_t)(ILLEGAL_BASE);
75444 + }
75445 +
75446 + /* Decreasing the allocated memory size from free memory size */
75447 + p_MM->freeMemSize -= size;
75448 +
75449 + /* insert the new busy block into the list of busy blocks */
75450 + AddBusy( p_MM, p_NewBusyB );
75451 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75452 +
75453 + return (holdBase);
75454 +}
75455 +
75456 +/*****************************************************************************/
75457 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
75458 +{
75459 + t_MM *p_MM = (t_MM *)h_MM;
75460 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
75461 + uint64_t size;
75462 + uint32_t intFlags;
75463 +
75464 + ASSERT_COND(p_MM);
75465 +
75466 + /* Look for a busy block that have the given base value.
75467 + * That block will be returned back to the memory.
75468 + */
75469 + p_PrevBusyB = 0;
75470 +
75471 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75472 + p_BusyB = p_MM->busyBlocks;
75473 + while ( p_BusyB && base != p_BusyB->base )
75474 + {
75475 + p_PrevBusyB = p_BusyB;
75476 + p_BusyB = p_BusyB->p_Next;
75477 + }
75478 +
75479 + if ( !p_BusyB )
75480 + {
75481 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75482 + return (uint64_t)(0);
75483 + }
75484 +
75485 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
75486 + {
75487 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75488 + return (uint64_t)(0);
75489 + }
75490 +
75491 + /* removes a busy block form the list of busy blocks */
75492 + if ( p_PrevBusyB )
75493 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
75494 + else
75495 + p_MM->busyBlocks = p_BusyB->p_Next;
75496 +
75497 + size = p_BusyB->end - p_BusyB->base;
75498 +
75499 + /* Adding the deallocated memory size to free memory size */
75500 + p_MM->freeMemSize += size;
75501 +
75502 + XX_Free(p_BusyB);
75503 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75504 +
75505 + return (size);
75506 +}
75507 +
75508 +/*****************************************************************************/
75509 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
75510 +{
75511 + t_MM *p_MM = (t_MM *)h_MM;
75512 + uint64_t end = base + size;
75513 + uint32_t intFlags;
75514 +
75515 + ASSERT_COND(p_MM);
75516 +
75517 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75518 +
75519 + if ( CutBusy( p_MM, base, end ) != E_OK )
75520 + {
75521 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75522 + return (uint64_t)(0);
75523 + }
75524 +
75525 + if ( AddFree ( p_MM, base, end ) != E_OK )
75526 + {
75527 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75528 + return (uint64_t)(0);
75529 + }
75530 +
75531 + /* Adding the deallocated memory size to free memory size */
75532 + p_MM->freeMemSize += size;
75533 +
75534 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75535 +
75536 + return (size);
75537 +}
75538 +
75539 +/*****************************************************************************/
75540 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
75541 +{
75542 + t_MM *p_MM = (t_MM *)h_MM;
75543 + t_MemBlock *p_MemB, *p_NewMemB;
75544 + t_Error errCode;
75545 + uint32_t intFlags;
75546 +
75547 + ASSERT_COND(p_MM);
75548 +
75549 + /* find a last block in the list of memory blocks to insert a new
75550 + * memory block
75551 + */
75552 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
75553 +
75554 + p_MemB = p_MM->memBlocks;
75555 + while ( p_MemB->p_Next )
75556 + {
75557 + if ( base >= p_MemB->base && base < p_MemB->end )
75558 + {
75559 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75560 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75561 + }
75562 + p_MemB = p_MemB->p_Next;
75563 + }
75564 + /* check for a last memory block */
75565 + if ( base >= p_MemB->base && base < p_MemB->end )
75566 + {
75567 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75568 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
75569 + }
75570 +
75571 + /* create a new memory block */
75572 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
75573 + {
75574 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75575 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
75576 + }
75577 +
75578 + /* append a new memory block to the end of the list of memory blocks */
75579 + p_MemB->p_Next = p_NewMemB;
75580 +
75581 + /* add a new free block to the free lists */
75582 + errCode = AddFree(p_MM, base, base+size);
75583 + if (errCode)
75584 + {
75585 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75586 + p_MemB->p_Next = 0;
75587 + XX_Free(p_NewMemB);
75588 + return ((t_Error)errCode);
75589 + }
75590 +
75591 + /* Adding the new block size to free memory size */
75592 + p_MM->freeMemSize += size;
75593 +
75594 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
75595 +
75596 + return (E_OK);
75597 +}
75598 +
75599 +/*****************************************************************************/
75600 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
75601 +{
75602 + t_MM *p_MM = (t_MM*)h_MM;
75603 + t_MemBlock *p_MemBlock;
75604 + int i;
75605 +
75606 + ASSERT_COND(p_MM);
75607 +
75608 + p_MemBlock = p_MM->memBlocks;
75609 + for (i=0; i < index; i++)
75610 + p_MemBlock = p_MemBlock->p_Next;
75611 +
75612 + if ( p_MemBlock )
75613 + return (p_MemBlock->base);
75614 + else
75615 + return (uint64_t)ILLEGAL_BASE;
75616 +}
75617 +
75618 +/*****************************************************************************/
75619 +uint64_t MM_GetBase(t_Handle h_MM)
75620 +{
75621 + t_MM *p_MM = (t_MM*)h_MM;
75622 + t_MemBlock *p_MemBlock;
75623 +
75624 + ASSERT_COND(p_MM);
75625 +
75626 + p_MemBlock = p_MM->memBlocks;
75627 + return p_MemBlock->base;
75628 +}
75629 +
75630 +/*****************************************************************************/
75631 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
75632 +{
75633 + t_MM *p_MM = (t_MM*)h_MM;
75634 + t_MemBlock *p_MemBlock;
75635 +
75636 + ASSERT_COND(p_MM);
75637 +
75638 + p_MemBlock = p_MM->memBlocks;
75639 +
75640 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
75641 + return TRUE;
75642 + else
75643 + return FALSE;
75644 +}
75645 +
75646 +/*****************************************************************************/
75647 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
75648 +{
75649 + t_MM *p_MM = (t_MM*)h_MM;
75650 +
75651 + ASSERT_COND(p_MM);
75652 +
75653 + return p_MM->freeMemSize;
75654 +}
75655 +
75656 +/*****************************************************************************/
75657 +void MM_Dump(t_Handle h_MM)
75658 +{
75659 + t_MM *p_MM = (t_MM *)h_MM;
75660 + t_FreeBlock *p_FreeB;
75661 + t_BusyBlock *p_BusyB;
75662 + int i;
75663 +
75664 + p_BusyB = p_MM->busyBlocks;
75665 + XX_Print("List of busy blocks:\n");
75666 + while (p_BusyB)
75667 + {
75668 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
75669 + p_BusyB = p_BusyB->p_Next;
75670 + }
75671 +
75672 + XX_Print("\nLists of free blocks according to alignment:\n");
75673 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
75674 + {
75675 + XX_Print("%d alignment:\n", (0x1 << i));
75676 + p_FreeB = p_MM->freeBlocks[i];
75677 + while (p_FreeB)
75678 + {
75679 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
75680 + p_FreeB = p_FreeB->p_Next;
75681 + }
75682 + XX_Print("\n");
75683 + }
75684 +}
75685 --- /dev/null
75686 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
75687 @@ -0,0 +1,105 @@
75688 +/*
75689 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75690 + *
75691 + * Redistribution and use in source and binary forms, with or without
75692 + * modification, are permitted provided that the following conditions are met:
75693 + * * Redistributions of source code must retain the above copyright
75694 + * notice, this list of conditions and the following disclaimer.
75695 + * * Redistributions in binary form must reproduce the above copyright
75696 + * notice, this list of conditions and the following disclaimer in the
75697 + * documentation and/or other materials provided with the distribution.
75698 + * * Neither the name of Freescale Semiconductor nor the
75699 + * names of its contributors may be used to endorse or promote products
75700 + * derived from this software without specific prior written permission.
75701 + *
75702 + *
75703 + * ALTERNATIVELY, this software may be distributed under the terms of the
75704 + * GNU General Public License ("GPL") as published by the Free Software
75705 + * Foundation, either version 2 of that License or (at your option) any
75706 + * later version.
75707 + *
75708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75718 + */
75719 +
75720 +
75721 +/****************************************************************
75722 + *
75723 + * File: mm.h
75724 + *
75725 + *
75726 + * Description:
75727 + * MM (Memory Management) object definitions.
75728 + * It also includes definitions of the Free Block, Busy Block
75729 + * and Memory Block structures used by the MM object.
75730 + *
75731 + ****************************************************************/
75732 +
75733 +#ifndef __MM_H
75734 +#define __MM_H
75735 +
75736 +
75737 +#include "mm_ext.h"
75738 +
75739 +#define __ERR_MODULE__ MODULE_MM
75740 +
75741 +
75742 +#define MAKE_ALIGNED(addr, align) \
75743 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
75744 +
75745 +
75746 +/* t_MemBlock data structure defines parameters of the Memory Block */
75747 +typedef struct t_MemBlock
75748 +{
75749 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
75750 +
75751 + uint64_t base; /* Base address of the memory block */
75752 + uint64_t end; /* End address of the memory block */
75753 +} t_MemBlock;
75754 +
75755 +
75756 +/* t_FreeBlock data structure defines parameters of the Free Block */
75757 +typedef struct t_FreeBlock
75758 +{
75759 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
75760 +
75761 + uint64_t base; /* Base address of the block */
75762 + uint64_t end; /* End address of the block */
75763 +} t_FreeBlock;
75764 +
75765 +
75766 +/* t_BusyBlock data structure defines parameters of the Busy Block */
75767 +typedef struct t_BusyBlock
75768 +{
75769 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
75770 +
75771 + uint64_t base; /* Base address of the block */
75772 + uint64_t end; /* End address of the block */
75773 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
75774 + something specified by the Name */
75775 +} t_BusyBlock;
75776 +
75777 +
75778 +/* t_MM data structure defines parameters of the MM object */
75779 +typedef struct t_MM
75780 +{
75781 + t_Handle h_Spinlock;
75782 +
75783 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
75784 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
75785 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
75786 + /* Alignment lists of free blocks (Free lists) */
75787 +
75788 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
75789 +} t_MM;
75790 +
75791 +
75792 +#endif /* __MM_H */
75793 --- /dev/null
75794 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
75795 @@ -0,0 +1,81 @@
75796 +/*
75797 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75798 + *
75799 + * Redistribution and use in source and binary forms, with or without
75800 + * modification, are permitted provided that the following conditions are met:
75801 + * * Redistributions of source code must retain the above copyright
75802 + * notice, this list of conditions and the following disclaimer.
75803 + * * Redistributions in binary form must reproduce the above copyright
75804 + * notice, this list of conditions and the following disclaimer in the
75805 + * documentation and/or other materials provided with the distribution.
75806 + * * Neither the name of Freescale Semiconductor nor the
75807 + * names of its contributors may be used to endorse or promote products
75808 + * derived from this software without specific prior written permission.
75809 + *
75810 + *
75811 + * ALTERNATIVELY, this software may be distributed under the terms of the
75812 + * GNU General Public License ("GPL") as published by the Free Software
75813 + * Foundation, either version 2 of that License or (at your option) any
75814 + * later version.
75815 + *
75816 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75817 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75818 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75819 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75820 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75821 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75822 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75823 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75824 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75825 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75826 + */
75827 +
75828 +
75829 +/*------------------------------------------------------*/
75830 +/* File: sprint.c */
75831 +/* */
75832 +/* Description: */
75833 +/* Debug routines (externals) */
75834 +/*------------------------------------------------------*/
75835 +#include "string_ext.h"
75836 +#include "stdlib_ext.h"
75837 +#include "stdarg_ext.h"
75838 +#include "sprint_ext.h"
75839 +#include "std_ext.h"
75840 +#include "xx_ext.h"
75841 +
75842 +
75843 +int Sprint(char * buf, const char *fmt, ...)
75844 +{
75845 + va_list args;
75846 + int i;
75847 +
75848 + va_start(args, fmt);
75849 + i=vsprintf(buf,fmt,args);
75850 + va_end(args);
75851 + return i;
75852 +}
75853 +
75854 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
75855 +{
75856 + va_list args;
75857 + int i;
75858 +
75859 + va_start(args, fmt);
75860 + i=vsnprintf(buf,size,fmt,args);
75861 + va_end(args);
75862 + return i;
75863 +}
75864 +
75865 +#ifndef NCSW_VXWORKS
75866 +int Sscan(const char * buf, const char * fmt, ...)
75867 +{
75868 + va_list args;
75869 + int i;
75870 +
75871 + va_start(args,fmt);
75872 + i = vsscanf(buf,fmt,args);
75873 + va_end(args);
75874 + return i;
75875 +}
75876 +#endif /* NCSW_VXWORKS */
75877 --- /dev/null
75878 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
75879 @@ -0,0 +1,57 @@
75880 +/*
75881 + * Copyright 2012 Freescale Semiconductor Inc.
75882 + *
75883 + * Redistribution and use in source and binary forms, with or without
75884 + * modification, are permitted provided that the following conditions are met:
75885 + * * Redistributions of source code must retain the above copyright
75886 + * notice, this list of conditions and the following disclaimer.
75887 + * * Redistributions in binary form must reproduce the above copyright
75888 + * notice, this list of conditions and the following disclaimer in the
75889 + * documentation and/or other materials provided with the distribution.
75890 + * * Neither the name of Freescale Semiconductor nor the
75891 + * names of its contributors may be used to endorse or promote products
75892 + * derived from this software without specific prior written permission.
75893 + *
75894 + *
75895 + * ALTERNATIVELY, this software may be distributed under the terms of the
75896 + * GNU General Public License ("GPL") as published by the Free Software
75897 + * Foundation, either version 2 of that License or (at your option) any
75898 + * later version.
75899 + *
75900 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75901 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75902 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75903 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75904 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75905 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75906 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75907 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75908 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75909 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75910 + */
75911 +
75912 +#ifndef __dflags_h
75913 +#define __dflags_h
75914 +
75915 +
75916 +#define NCSW_LINUX
75917 +
75918 +#define T4240
75919 +#define NCSW_PPC_CORE
75920 +
75921 +#define DEBUG_ERRORS 1
75922 +
75923 +#if defined(DEBUG)
75924 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75925 +
75926 +#define DEBUG_XX_MALLOC
75927 +#define DEBUG_MEM_LEAKS
75928 +
75929 +#else
75930 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75931 +#endif /* (DEBUG) */
75932 +
75933 +#define REPORT_EVENTS 1
75934 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75935 +
75936 +#endif /* __dflags_h */
75937 --- /dev/null
75938 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
75939 @@ -0,0 +1,56 @@
75940 +/*
75941 + * Copyright 2012 Freescale Semiconductor Inc.
75942 + *
75943 + * Redistribution and use in source and binary forms, with or without
75944 + * modification, are permitted provided that the following conditions are met:
75945 + * * Redistributions of source code must retain the above copyright
75946 + * notice, this list of conditions and the following disclaimer.
75947 + * * Redistributions in binary form must reproduce the above copyright
75948 + * notice, this list of conditions and the following disclaimer in the
75949 + * documentation and/or other materials provided with the distribution.
75950 + * * Neither the name of Freescale Semiconductor nor the
75951 + * names of its contributors may be used to endorse or promote products
75952 + * derived from this software without specific prior written permission.
75953 + *
75954 + *
75955 + * ALTERNATIVELY, this software may be distributed under the terms of the
75956 + * GNU General Public License ("GPL") as published by the Free Software
75957 + * Foundation, either version 2 of that License or (at your option) any
75958 + * later version.
75959 + *
75960 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75961 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75962 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75963 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75964 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75965 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75966 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75967 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75968 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75969 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75970 + */
75971 +
75972 +#ifndef __dflags_h
75973 +#define __dflags_h
75974 +
75975 +
75976 +#define NCSW_LINUX
75977 +
75978 +#define NCSW_PPC_CORE
75979 +
75980 +#define DEBUG_ERRORS 1
75981 +
75982 +#if defined(DEBUG)
75983 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
75984 +
75985 +#define DEBUG_XX_MALLOC
75986 +#define DEBUG_MEM_LEAKS
75987 +
75988 +#else
75989 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
75990 +#endif /* (DEBUG) */
75991 +
75992 +#define REPORT_EVENTS 1
75993 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
75994 +
75995 +#endif /* __dflags_h */
75996 --- /dev/null
75997 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
75998 @@ -0,0 +1,364 @@
75999 +/*
76000 + * Copyright 2008-2012 Freescale Semiconductor Inc.
76001 + *
76002 + * Redistribution and use in source and binary forms, with or without
76003 + * modification, are permitted provided that the following conditions are met:
76004 + * * Redistributions of source code must retain the above copyright
76005 + * notice, this list of conditions and the following disclaimer.
76006 + * * Redistributions in binary form must reproduce the above copyright
76007 + * notice, this list of conditions and the following disclaimer in the
76008 + * documentation and/or other materials provided with the distribution.
76009 + * * Neither the name of Freescale Semiconductor nor the
76010 + * names of its contributors may be used to endorse or promote products
76011 + * derived from this software without specific prior written permission.
76012 + *
76013 + *
76014 + * ALTERNATIVELY, this software may be distributed under the terms of the
76015 + * GNU General Public License ("GPL") as published by the Free Software
76016 + * Foundation, either version 2 of that License or (at your option) any
76017 + * later version.
76018 + *
76019 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76020 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76021 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76022 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76023 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76024 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76025 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76026 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76027 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76028 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76029 + */
76030 +
76031 +
76032 +/*------------------------------------------------------*/
76033 +/* */
76034 +/* File: crc_mac_addr_ext.h */
76035 +/* */
76036 +/* Description: */
76037 +/* Define a macro that calculate the crc value of */
76038 +/* an Ethernet MAC address (48 bitd address */
76039 +/*------------------------------------------------------*/
76040 +
76041 +#ifndef __crc_mac_addr_ext_h
76042 +#define __crc_mac_addr_ext_h
76043 +
76044 +#include "std_ext.h"
76045 +
76046 +
76047 +static uint32_t crc_table[256] =
76048 +{
76049 + 0x00000000,
76050 + 0x77073096,
76051 + 0xee0e612c,
76052 + 0x990951ba,
76053 + 0x076dc419,
76054 + 0x706af48f,
76055 + 0xe963a535,
76056 + 0x9e6495a3,
76057 + 0x0edb8832,
76058 + 0x79dcb8a4,
76059 + 0xe0d5e91e,
76060 + 0x97d2d988,
76061 + 0x09b64c2b,
76062 + 0x7eb17cbd,
76063 + 0xe7b82d07,
76064 + 0x90bf1d91,
76065 + 0x1db71064,
76066 + 0x6ab020f2,
76067 + 0xf3b97148,
76068 + 0x84be41de,
76069 + 0x1adad47d,
76070 + 0x6ddde4eb,
76071 + 0xf4d4b551,
76072 + 0x83d385c7,
76073 + 0x136c9856,
76074 + 0x646ba8c0,
76075 + 0xfd62f97a,
76076 + 0x8a65c9ec,
76077 + 0x14015c4f,
76078 + 0x63066cd9,
76079 + 0xfa0f3d63,
76080 + 0x8d080df5,
76081 + 0x3b6e20c8,
76082 + 0x4c69105e,
76083 + 0xd56041e4,
76084 + 0xa2677172,
76085 + 0x3c03e4d1,
76086 + 0x4b04d447,
76087 + 0xd20d85fd,
76088 + 0xa50ab56b,
76089 + 0x35b5a8fa,
76090 + 0x42b2986c,
76091 + 0xdbbbc9d6,
76092 + 0xacbcf940,
76093 + 0x32d86ce3,
76094 + 0x45df5c75,
76095 + 0xdcd60dcf,
76096 + 0xabd13d59,
76097 + 0x26d930ac,
76098 + 0x51de003a,
76099 + 0xc8d75180,
76100 + 0xbfd06116,
76101 + 0x21b4f4b5,
76102 + 0x56b3c423,
76103 + 0xcfba9599,
76104 + 0xb8bda50f,
76105 + 0x2802b89e,
76106 + 0x5f058808,
76107 + 0xc60cd9b2,
76108 + 0xb10be924,
76109 + 0x2f6f7c87,
76110 + 0x58684c11,
76111 + 0xc1611dab,
76112 + 0xb6662d3d,
76113 + 0x76dc4190,
76114 + 0x01db7106,
76115 + 0x98d220bc,
76116 + 0xefd5102a,
76117 + 0x71b18589,
76118 + 0x06b6b51f,
76119 + 0x9fbfe4a5,
76120 + 0xe8b8d433,
76121 + 0x7807c9a2,
76122 + 0x0f00f934,
76123 + 0x9609a88e,
76124 + 0xe10e9818,
76125 + 0x7f6a0dbb,
76126 + 0x086d3d2d,
76127 + 0x91646c97,
76128 + 0xe6635c01,
76129 + 0x6b6b51f4,
76130 + 0x1c6c6162,
76131 + 0x856530d8,
76132 + 0xf262004e,
76133 + 0x6c0695ed,
76134 + 0x1b01a57b,
76135 + 0x8208f4c1,
76136 + 0xf50fc457,
76137 + 0x65b0d9c6,
76138 + 0x12b7e950,
76139 + 0x8bbeb8ea,
76140 + 0xfcb9887c,
76141 + 0x62dd1ddf,
76142 + 0x15da2d49,
76143 + 0x8cd37cf3,
76144 + 0xfbd44c65,
76145 + 0x4db26158,
76146 + 0x3ab551ce,
76147 + 0xa3bc0074,
76148 + 0xd4bb30e2,
76149 + 0x4adfa541,
76150 + 0x3dd895d7,
76151 + 0xa4d1c46d,
76152 + 0xd3d6f4fb,
76153 + 0x4369e96a,
76154 + 0x346ed9fc,
76155 + 0xad678846,
76156 + 0xda60b8d0,
76157 + 0x44042d73,
76158 + 0x33031de5,
76159 + 0xaa0a4c5f,
76160 + 0xdd0d7cc9,
76161 + 0x5005713c,
76162 + 0x270241aa,
76163 + 0xbe0b1010,
76164 + 0xc90c2086,
76165 + 0x5768b525,
76166 + 0x206f85b3,
76167 + 0xb966d409,
76168 + 0xce61e49f,
76169 + 0x5edef90e,
76170 + 0x29d9c998,
76171 + 0xb0d09822,
76172 + 0xc7d7a8b4,
76173 + 0x59b33d17,
76174 + 0x2eb40d81,
76175 + 0xb7bd5c3b,
76176 + 0xc0ba6cad,
76177 + 0xedb88320,
76178 + 0x9abfb3b6,
76179 + 0x03b6e20c,
76180 + 0x74b1d29a,
76181 + 0xead54739,
76182 + 0x9dd277af,
76183 + 0x04db2615,
76184 + 0x73dc1683,
76185 + 0xe3630b12,
76186 + 0x94643b84,
76187 + 0x0d6d6a3e,
76188 + 0x7a6a5aa8,
76189 + 0xe40ecf0b,
76190 + 0x9309ff9d,
76191 + 0x0a00ae27,
76192 + 0x7d079eb1,
76193 + 0xf00f9344,
76194 + 0x8708a3d2,
76195 + 0x1e01f268,
76196 + 0x6906c2fe,
76197 + 0xf762575d,
76198 + 0x806567cb,
76199 + 0x196c3671,
76200 + 0x6e6b06e7,
76201 + 0xfed41b76,
76202 + 0x89d32be0,
76203 + 0x10da7a5a,
76204 + 0x67dd4acc,
76205 + 0xf9b9df6f,
76206 + 0x8ebeeff9,
76207 + 0x17b7be43,
76208 + 0x60b08ed5,
76209 + 0xd6d6a3e8,
76210 + 0xa1d1937e,
76211 + 0x38d8c2c4,
76212 + 0x4fdff252,
76213 + 0xd1bb67f1,
76214 + 0xa6bc5767,
76215 + 0x3fb506dd,
76216 + 0x48b2364b,
76217 + 0xd80d2bda,
76218 + 0xaf0a1b4c,
76219 + 0x36034af6,
76220 + 0x41047a60,
76221 + 0xdf60efc3,
76222 + 0xa867df55,
76223 + 0x316e8eef,
76224 + 0x4669be79,
76225 + 0xcb61b38c,
76226 + 0xbc66831a,
76227 + 0x256fd2a0,
76228 + 0x5268e236,
76229 + 0xcc0c7795,
76230 + 0xbb0b4703,
76231 + 0x220216b9,
76232 + 0x5505262f,
76233 + 0xc5ba3bbe,
76234 + 0xb2bd0b28,
76235 + 0x2bb45a92,
76236 + 0x5cb36a04,
76237 + 0xc2d7ffa7,
76238 + 0xb5d0cf31,
76239 + 0x2cd99e8b,
76240 + 0x5bdeae1d,
76241 + 0x9b64c2b0,
76242 + 0xec63f226,
76243 + 0x756aa39c,
76244 + 0x026d930a,
76245 + 0x9c0906a9,
76246 + 0xeb0e363f,
76247 + 0x72076785,
76248 + 0x05005713,
76249 + 0x95bf4a82,
76250 + 0xe2b87a14,
76251 + 0x7bb12bae,
76252 + 0x0cb61b38,
76253 + 0x92d28e9b,
76254 + 0xe5d5be0d,
76255 + 0x7cdcefb7,
76256 + 0x0bdbdf21,
76257 + 0x86d3d2d4,
76258 + 0xf1d4e242,
76259 + 0x68ddb3f8,
76260 + 0x1fda836e,
76261 + 0x81be16cd,
76262 + 0xf6b9265b,
76263 + 0x6fb077e1,
76264 + 0x18b74777,
76265 + 0x88085ae6,
76266 + 0xff0f6a70,
76267 + 0x66063bca,
76268 + 0x11010b5c,
76269 + 0x8f659eff,
76270 + 0xf862ae69,
76271 + 0x616bffd3,
76272 + 0x166ccf45,
76273 + 0xa00ae278,
76274 + 0xd70dd2ee,
76275 + 0x4e048354,
76276 + 0x3903b3c2,
76277 + 0xa7672661,
76278 + 0xd06016f7,
76279 + 0x4969474d,
76280 + 0x3e6e77db,
76281 + 0xaed16a4a,
76282 + 0xd9d65adc,
76283 + 0x40df0b66,
76284 + 0x37d83bf0,
76285 + 0xa9bcae53,
76286 + 0xdebb9ec5,
76287 + 0x47b2cf7f,
76288 + 0x30b5ffe9,
76289 + 0xbdbdf21c,
76290 + 0xcabac28a,
76291 + 0x53b39330,
76292 + 0x24b4a3a6,
76293 + 0xbad03605,
76294 + 0xcdd70693,
76295 + 0x54de5729,
76296 + 0x23d967bf,
76297 + 0xb3667a2e,
76298 + 0xc4614ab8,
76299 + 0x5d681b02,
76300 + 0x2a6f2b94,
76301 + 0xb40bbe37,
76302 + 0xc30c8ea1,
76303 + 0x5a05df1b,
76304 + 0x2d02ef8d
76305 +};
76306 +
76307 +
76308 +#define GET_MAC_ADDR_CRC(addr, crc) \
76309 +{ \
76310 + uint32_t i; \
76311 + uint8_t data; \
76312 + \
76313 + /* CRC calculation */ \
76314 + crc = 0xffffffff; \
76315 + for (i=0; i < 6; i++) \
76316 + { \
76317 + data = (uint8_t)(addr >> ((5-i)*8)); \
76318 + crc = crc^data; \
76319 + crc = crc_table[crc&0xff] ^ (crc>>8); \
76320 + } \
76321 +} \
76322 +
76323 +/* Define a macro for getting the mirrored value of */
76324 +/* a byte size number. (0x11010011 --> 0x11001011) */
76325 +/* Sometimes the mirrored value of the CRC is required */
76326 +static __inline__ uint8_t GetMirror(uint8_t n)
76327 +{
76328 + uint8_t mirror[16] =
76329 + {
76330 + 0x00,
76331 + 0x08,
76332 + 0x04,
76333 + 0x0c,
76334 + 0x02,
76335 + 0x0a,
76336 + 0x06,
76337 + 0x0e,
76338 + 0x01,
76339 + 0x09,
76340 + 0x05,
76341 + 0x0d,
76342 + 0x03,
76343 + 0x0b,
76344 + 0x07,
76345 + 0x0f
76346 + };
76347 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
76348 +}
76349 +
76350 +static __inline__ uint32_t GetMirror32(uint32_t n)
76351 +{
76352 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
76353 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
76354 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
76355 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
76356 +}
76357 +
76358 +#define MIRROR GetMirror
76359 +#define MIRROR_32 GetMirror32
76360 +
76361 +
76362 +#endif /* __crc_mac_addr_ext_h */
76363 --- /dev/null
76364 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
76365 @@ -0,0 +1,210 @@
76366 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76367 + * All rights reserved.
76368 + *
76369 + * Redistribution and use in source and binary forms, with or without
76370 + * modification, are permitted provided that the following conditions are met:
76371 + * * Redistributions of source code must retain the above copyright
76372 + * notice, this list of conditions and the following disclaimer.
76373 + * * Redistributions in binary form must reproduce the above copyright
76374 + * notice, this list of conditions and the following disclaimer in the
76375 + * documentation and/or other materials provided with the distribution.
76376 + * * Neither the name of Freescale Semiconductor nor the
76377 + * names of its contributors may be used to endorse or promote products
76378 + * derived from this software without specific prior written permission.
76379 + *
76380 + *
76381 + * ALTERNATIVELY, this software may be distributed under the terms of the
76382 + * GNU General Public License ("GPL") as published by the Free Software
76383 + * Foundation, either version 2 of that License or (at your option) any
76384 + * later version.
76385 + *
76386 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76387 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76388 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76389 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76390 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76391 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76392 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76393 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76394 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76395 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76396 + */
76397 +
76398 +
76399 +/**************************************************************************//**
76400 + @File dpaa_ext.h
76401 +
76402 + @Description DPAA Application Programming Interface.
76403 +*//***************************************************************************/
76404 +#ifndef __DPAA_EXT_H
76405 +#define __DPAA_EXT_H
76406 +
76407 +#include "std_ext.h"
76408 +#include "error_ext.h"
76409 +
76410 +
76411 +/**************************************************************************//**
76412 + @Group DPAA_grp Data Path Acceleration Architecture API
76413 +
76414 + @Description DPAA API functions, definitions and enums.
76415 +
76416 + @{
76417 +*//***************************************************************************/
76418 +
76419 +#if defined(__MWERKS__) && !defined(__GNUC__)
76420 +#pragma pack(push,1)
76421 +#endif /* defined(__MWERKS__) && ... */
76422 +
76423 +/**************************************************************************//**
76424 + @Description Frame descriptor
76425 +*//***************************************************************************/
76426 +typedef _Packed struct t_DpaaFD {
76427 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
76428 + volatile uint8_t liodn;
76429 + volatile uint8_t bpid;
76430 + volatile uint8_t elion;
76431 + volatile uint8_t addrh;
76432 + volatile uint32_t addrl;
76433 +#else
76434 + volatile uint32_t addrl;
76435 + volatile uint8_t addrh;
76436 + volatile uint8_t elion;
76437 + volatile uint8_t bpid;
76438 + volatile uint8_t liodn;
76439 + #endif
76440 + volatile uint32_t length; /**< Frame length */
76441 + volatile uint32_t status; /**< FD status */
76442 +} _PackedType t_DpaaFD;
76443 +
76444 +/**************************************************************************//**
76445 + @Description enum for defining frame format
76446 +*//***************************************************************************/
76447 +typedef enum e_DpaaFDFormatType {
76448 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
76449 + small length (9b OFFSET, 20b LENGTH) */
76450 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
76451 + (29b LENGTH ,No OFFSET) */
76452 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
76453 + and small length (9b OFFSET, 20b LENGTH) */
76454 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
76455 + big length (29b LENGTH ,No OFFSET) */
76456 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
76457 + No LENGTH or OFFSET) */
76458 + e_DPAA_FD_FORMAT_TYPE_DUMMY
76459 +} e_DpaaFDFormatType;
76460 +
76461 +/**************************************************************************//**
76462 + @Collection Frame descriptor macros
76463 +*//***************************************************************************/
76464 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
76465 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
76466 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
76467 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
76468 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
76469 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
76470 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
76471 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
76472 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
76473 +
76474 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
76475 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
76476 +#define DPAA_FD_GET_PHYS_ADDR(fd) ((physAddress_t)(((uint64_t)DPAA_FD_GET_ADDRH(fd) << 32) | (uint64_t)DPAA_FD_GET_ADDRL(fd))) /**< Macro to get FD ADDR field */
76477 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
76478 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
76479 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
76480 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
76481 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
76482 +
76483 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
76484 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
76485 +#define DPAA_FD_SET_ADDR(fd,val) \
76486 +do { \
76487 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76488 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
76489 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
76490 +} while (0) /**< Macro to set FD ADDR field */
76491 +#define DPAA_FD_SET_FORMAT(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_FORMAT_MASK) | (((val) << (31-2))& DPAA_FD_FORMAT_MASK))) /**< Macro to set FD FORMAT field */
76492 +#define DPAA_FD_SET_OFFSET(fd,val) (((t_DpaaFD *)fd)->length = ((((t_DpaaFD *)fd)->length & ~DPAA_FD_OFFSET_MASK) | (((val) << (31-11))& DPAA_FD_OFFSET_MASK) )) /**< Macro to set FD OFFSET field */
76493 +#define DPAA_FD_SET_LENGTH(fd,val) (((t_DpaaFD *)fd)->length = (((t_DpaaFD *)fd)->length & ~DPAA_FD_LENGTH_MASK) | ((val) & DPAA_FD_LENGTH_MASK)) /**< Macro to set FD LENGTH field */
76494 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
76495 +/* @} */
76496 +
76497 +/**************************************************************************//**
76498 + @Description Frame Scatter/Gather Table Entry
76499 +*//***************************************************************************/
76500 +typedef _Packed struct t_DpaaSGTE {
76501 + volatile uint32_t addrh; /**< Buffer Address high */
76502 + volatile uint32_t addrl; /**< Buffer Address low */
76503 + volatile uint32_t length; /**< Buffer length */
76504 + volatile uint32_t offset; /**< SGTE offset */
76505 +} _PackedType t_DpaaSGTE;
76506 +
76507 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
76508 +
76509 +/**************************************************************************//**
76510 + @Description Frame Scatter/Gather Table
76511 +*//***************************************************************************/
76512 +typedef _Packed struct t_DpaaSGT {
76513 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
76514 + /**< Structure that holds information about
76515 + a single S/G entry. */
76516 +} _PackedType t_DpaaSGT;
76517 +
76518 +/**************************************************************************//**
76519 + @Description Compound Frame Table
76520 +*//***************************************************************************/
76521 +typedef _Packed struct t_DpaaCompTbl {
76522 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
76523 + the compound-frame output buffer;
76524 + NOTE: this may point to a S/G table */
76525 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
76526 + the compound-frame input buffer;
76527 + NOTE: this may point to a S/G table */
76528 +} _PackedType t_DpaaCompTbl;
76529 +
76530 +/**************************************************************************//**
76531 + @Collection Frame Scatter/Gather Table Entry macros
76532 +*//***************************************************************************/
76533 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
76534 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
76535 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
76536 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
76537 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
76538 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
76539 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
76540 +
76541 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
76542 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
76543 +#define DPAA_SGTE_GET_PHYS_ADDR(sgte) ((physAddress_t)(((uint64_t)DPAA_SGTE_GET_ADDRH(sgte) << 32) | (uint64_t)DPAA_SGTE_GET_ADDRL(sgte))) /**< Macro to get FD ADDR field */
76544 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
76545 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
76546 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
76547 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
76548 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
76549 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
76550 +
76551 +#define DPAA_SGTE_SET_ADDRH(sgte,val) (((t_DpaaSGTE *)sgte)->addrh = ((((t_DpaaSGTE *)sgte)->addrh & ~DPAA_SGTE_ADDRH_MASK) | ((val) & DPAA_SGTE_ADDRH_MASK))) /**< Macro to set SGTE ADDRH field */
76552 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
76553 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
76554 +do { \
76555 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
76556 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
76557 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
76558 +} while (0) /**< Macro to set SGTE ADDR field */
76559 +#define DPAA_SGTE_SET_EXTENSION(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_E_MASK) | (((val) << (31-0))& DPAA_SGTE_E_MASK))) /**< Macro to set SGTE EXTENSION field */
76560 +#define DPAA_SGTE_SET_FINAL(sgte,val) (((t_DpaaSGTE *)sgte)->length = ((((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_F_MASK) | (((val) << (31-1))& DPAA_SGTE_F_MASK))) /**< Macro to set SGTE FINAL field */
76561 +#define DPAA_SGTE_SET_LENGTH(sgte,val) (((t_DpaaSGTE *)sgte)->length = (((t_DpaaSGTE *)sgte)->length & ~DPAA_SGTE_LENGTH_MASK) | ((val) & DPAA_SGTE_LENGTH_MASK)) /**< Macro to set SGTE LENGTH field */
76562 +#define DPAA_SGTE_SET_BPID(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_BPID_MASK) | (((val) << (31-15))& DPAA_SGTE_BPID_MASK))) /**< Macro to set SGTE BPID field */
76563 +#define DPAA_SGTE_SET_OFFSET(sgte,val) (((t_DpaaSGTE *)sgte)->offset = ((((t_DpaaSGTE *)sgte)->offset & ~DPAA_SGTE_OFFSET_MASK) | (((val) << (31-31))& DPAA_SGTE_OFFSET_MASK) )) /**< Macro to set SGTE OFFSET field */
76564 +/* @} */
76565 +
76566 +#if defined(__MWERKS__) && !defined(__GNUC__)
76567 +#pragma pack(pop)
76568 +#endif /* defined(__MWERKS__) && ... */
76569 +
76570 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
76571 +
76572 +/** @} */ /* end of DPAA_grp group */
76573 +
76574 +
76575 +#endif /* __DPAA_EXT_H */
76576 --- /dev/null
76577 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
76578 @@ -0,0 +1,1731 @@
76579 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
76580 + * All rights reserved.
76581 + *
76582 + * Redistribution and use in source and binary forms, with or without
76583 + * modification, are permitted provided that the following conditions are met:
76584 + * * Redistributions of source code must retain the above copyright
76585 + * notice, this list of conditions and the following disclaimer.
76586 + * * Redistributions in binary form must reproduce the above copyright
76587 + * notice, this list of conditions and the following disclaimer in the
76588 + * documentation and/or other materials provided with the distribution.
76589 + * * Neither the name of Freescale Semiconductor nor the
76590 + * names of its contributors may be used to endorse or promote products
76591 + * derived from this software without specific prior written permission.
76592 + *
76593 + *
76594 + * ALTERNATIVELY, this software may be distributed under the terms of the
76595 + * GNU General Public License ("GPL") as published by the Free Software
76596 + * Foundation, either version 2 of that License or (at your option) any
76597 + * later version.
76598 + *
76599 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76600 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76601 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76602 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76603 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76604 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76605 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76606 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76607 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76608 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76609 + */
76610 +
76611 +
76612 +/**************************************************************************//**
76613 + @File fm_ext.h
76614 +
76615 + @Description FM Application Programming Interface.
76616 +*//***************************************************************************/
76617 +#ifndef __FM_EXT
76618 +#define __FM_EXT
76619 +
76620 +#include "error_ext.h"
76621 +#include "std_ext.h"
76622 +#include "dpaa_ext.h"
76623 +#include "fsl_fman_sp.h"
76624 +
76625 +/**************************************************************************//**
76626 + @Group FM_grp Frame Manager API
76627 +
76628 + @Description FM API functions, definitions and enums.
76629 +
76630 + @{
76631 +*//***************************************************************************/
76632 +
76633 +/**************************************************************************//**
76634 + @Group FM_lib_grp FM library
76635 +
76636 + @Description FM API functions, definitions and enums.
76637 +
76638 + The FM module is the main driver module and is a mandatory module
76639 + for FM driver users. This module must be initialized first prior
76640 + to any other drivers modules.
76641 + The FM is a "singleton" module. It is responsible of the common
76642 + HW modules: FPM, DMA, common QMI and common BMI initializations and
76643 + run-time control routines. This module must be initialized always
76644 + when working with any of the FM modules.
76645 + NOTE - We assume that the FM library will be initialized only by core No. 0!
76646 +
76647 + @{
76648 +*//***************************************************************************/
76649 +
76650 +/**************************************************************************//**
76651 + @Description Enum for defining port types
76652 +*//***************************************************************************/
76653 +typedef enum e_FmPortType {
76654 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
76655 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
76656 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
76657 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
76658 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
76659 + e_FM_PORT_TYPE_DUMMY
76660 +} e_FmPortType;
76661 +
76662 +/**************************************************************************//**
76663 + @Collection General FM defines
76664 +*//***************************************************************************/
76665 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
76666 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
76667 +/* @} */
76668 +
76669 +
76670 +#if defined(__MWERKS__) && !defined(__GNUC__)
76671 +#pragma pack(push,1)
76672 +#endif /* defined(__MWERKS__) && ... */
76673 +
76674 +/**************************************************************************//**
76675 + @Description FM physical Address
76676 +*//***************************************************************************/
76677 +typedef _Packed struct t_FmPhysAddr {
76678 + volatile uint8_t high; /**< High part of the physical address */
76679 + volatile uint32_t low; /**< Low part of the physical address */
76680 +} _PackedType t_FmPhysAddr;
76681 +
76682 +/**************************************************************************//**
76683 + @Description Parse results memory layout
76684 +*//***************************************************************************/
76685 +typedef _Packed struct t_FmPrsResult {
76686 + volatile uint8_t lpid; /**< Logical port id */
76687 + volatile uint8_t shimr; /**< Shim header result */
76688 + volatile uint16_t l2r; /**< Layer 2 result */
76689 + volatile uint16_t l3r; /**< Layer 3 result */
76690 + volatile uint8_t l4r; /**< Layer 4 result */
76691 + volatile uint8_t cplan; /**< Classification plan id */
76692 + volatile uint16_t nxthdr; /**< Next Header */
76693 + volatile uint16_t cksum; /**< Running-sum */
76694 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
76695 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
76696 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
76697 + volatile uint8_t shim_off[2]; /**< Shim offset */
76698 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
76699 + volatile uint8_t eth_off; /**< ETH offset */
76700 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
76701 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
76702 + volatile uint8_t etype_off; /**< ETYPE offset */
76703 + volatile uint8_t pppoe_off; /**< PPP offset */
76704 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
76705 + volatile uint8_t ip_off[2]; /**< IP offset */
76706 + volatile uint8_t gre_off; /**< GRE offset */
76707 + volatile uint8_t l4_off; /**< Layer 4 offset */
76708 + volatile uint8_t nxthdr_off; /**< Parser end point */
76709 +} _PackedType t_FmPrsResult;
76710 +
76711 +/**************************************************************************//**
76712 + @Collection FM Parser results
76713 +*//***************************************************************************/
76714 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
76715 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
76716 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
76717 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
76718 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
76719 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
76720 +/* @} */
76721 +
76722 +/**************************************************************************//**
76723 + @Collection FM Frame descriptor macros
76724 +*//***************************************************************************/
76725 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
76726 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
76727 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
76728 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
76729 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
76730 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
76731 +
76732 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
76733 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
76734 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
76735 +
76736 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
76737 +
76738 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
76739 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
76740 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
76741 +
76742 +#ifdef FM_CAPWAP_SUPPORT
76743 +#define FM_FD_ERR_CRE 0x00200000
76744 +#define FM_FD_ERR_CHE 0x00100000
76745 +#endif /* FM_CAPWAP_SUPPORT */
76746 +
76747 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
76748 + error (SGMII and TBI modes), FIFO parity error. PHY
76749 + Sequence error, PHY error control character detected. */
76750 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
76751 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
76752 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
76753 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
76754 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
76755 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
76756 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
76757 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
76758 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
76759 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
76760 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
76761 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
76762 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
76763 +
76764 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76765 + FM_FD_ERR_LENGTH | \
76766 + FM_FD_ERR_DMA) /**< TX Error FD bits */
76767 +
76768 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
76769 + FM_FD_ERR_LENGTH | \
76770 + FM_FD_ERR_DMA | \
76771 + FM_FD_ERR_IPR | \
76772 + FM_FD_ERR_IPR_TO | \
76773 + FM_FD_ERR_IPR_NCSP | \
76774 + FM_FD_ERR_PHYSICAL | \
76775 + FM_FD_ERR_SIZE | \
76776 + FM_FD_ERR_CLS_DISCARD | \
76777 + FM_FD_ERR_COLOR_RED | \
76778 + FM_FD_ERR_COLOR_YELLOW | \
76779 + FM_FD_ERR_ILL_PLCR | \
76780 + FM_FD_ERR_PLCR_FRAME_LEN | \
76781 + FM_FD_ERR_EXTRACTION | \
76782 + FM_FD_ERR_NO_SCHEME | \
76783 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
76784 + FM_FD_ERR_PRS_TIMEOUT | \
76785 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
76786 + FM_FD_ERR_PRS_HDR_ERR | \
76787 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
76788 +
76789 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
76790 +/* @} */
76791 +
76792 +/**************************************************************************//**
76793 + @Description Context A
76794 +*//***************************************************************************/
76795 +typedef _Packed struct t_FmContextA {
76796 + volatile uint32_t command; /**< ContextA Command */
76797 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
76798 +} _PackedType t_FmContextA;
76799 +
76800 +/**************************************************************************//**
76801 + @Description Context B
76802 +*//***************************************************************************/
76803 +typedef uint32_t t_FmContextB;
76804 +
76805 +/**************************************************************************//**
76806 + @Collection Special Operation options
76807 +*//***************************************************************************/
76808 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
76809 +
76810 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
76811 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
76812 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
76813 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
76814 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
76815 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
76816 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
76817 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
76818 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
76819 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
76820 +/* @} */
76821 +
76822 +/**************************************************************************//**
76823 + @Collection Context A macros
76824 +*//***************************************************************************/
76825 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
76826 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
76827 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
76828 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
76829 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
76830 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
76831 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
76832 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
76833 +
76834 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
76835 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
76836 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
76837 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
76838 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
76839 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
76840 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
76841 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
76842 +
76843 +#define FM_CONTEXTA_SET_OVERRIDE(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_OVERRIDE_MASK) | (((uint32_t)(val) << (31-0)) & FM_CONTEXTA_OVERRIDE_MASK) ))
76844 +#define FM_CONTEXTA_SET_ICMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_ICMD_MASK) | (((val) << (31-1)) & FM_CONTEXTA_ICMD_MASK) ))
76845 +#define FM_CONTEXTA_SET_A1_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_VALID_MASK) | (((val) << (31-2)) & FM_CONTEXTA_A1_VALID_MASK) ))
76846 +#define FM_CONTEXTA_SET_A1(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_A1_MASK) | (((val) << (31-31)) & FM_CONTEXTA_A1_MASK) ))
76847 +#define FM_CONTEXTA_SET_MACCMD(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_MASK) ))
76848 +#define FM_CONTEXTA_SET_MACCMD_VALID(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_VALID_MASK) | (((val) << (31-8)) & FM_CONTEXTA_MACCMD_VALID_MASK) ))
76849 +#define FM_CONTEXTA_SET_MACCMD_SECURED(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SECURED_MASK) | (((val) << (31-11)) & FM_CONTEXTA_MACCMD_SECURED_MASK) ))
76850 +#define FM_CONTEXTA_SET_MACCMD_SECURE_CHANNEL(contextA,val) (((t_FmContextA *)contextA)->command = (uint32_t)((((t_FmContextA *)contextA)->command & ~FM_CONTEXTA_MACCMD_SC_MASK) | (((val) << (31-15)) & FM_CONTEXTA_MACCMD_SC_MASK) ))
76851 +/* @} */
76852 +
76853 +/**************************************************************************//**
76854 + @Collection Context B macros
76855 +*//***************************************************************************/
76856 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
76857 +
76858 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
76859 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
76860 +/* @} */
76861 +
76862 +#if defined(__MWERKS__) && !defined(__GNUC__)
76863 +#pragma pack(pop)
76864 +#endif /* defined(__MWERKS__) && ... */
76865 +
76866 +
76867 +/**************************************************************************//**
76868 + @Description FM Exceptions
76869 +*//***************************************************************************/
76870 +typedef enum e_FmExceptions {
76871 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
76872 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
76873 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
76874 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
76875 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
76876 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
76877 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
76878 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
76879 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
76880 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
76881 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
76882 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
76883 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
76884 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
76885 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
76886 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
76887 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
76888 +} e_FmExceptions;
76889 +
76890 +/**************************************************************************//**
76891 + @Description Enum for defining port DMA swap mode
76892 +*//***************************************************************************/
76893 +typedef enum e_FmDmaSwapOption {
76894 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
76895 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
76896 + in PowerPc Little Endian mode. */
76897 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
76898 + in Big Endian mode */
76899 +} e_FmDmaSwapOption;
76900 +
76901 +/**************************************************************************//**
76902 + @Description Enum for defining port DMA cache attributes
76903 +*//***************************************************************************/
76904 +typedef enum e_FmDmaCacheOption {
76905 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
76906 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
76907 +} e_FmDmaCacheOption;
76908 +
76909 +
76910 +/**************************************************************************//**
76911 + @Group FM_init_grp FM Initialization Unit
76912 +
76913 + @Description FM Initialization Unit
76914 +
76915 + Initialization Flow
76916 + Initialization of the FM Module will be carried out by the application
76917 + according to the following sequence:
76918 + - Calling the configuration routine with basic parameters.
76919 + - Calling the advance initialization routines to change driver's defaults.
76920 + - Calling the initialization routine.
76921 +
76922 + @{
76923 +*//***************************************************************************/
76924 +
76925 +/**************************************************************************//**
76926 + @Function t_FmExceptionsCallback
76927 +
76928 + @Description Exceptions user callback routine, will be called upon an
76929 + exception passing the exception identification.
76930 +
76931 + @Param[in] h_App - User's application descriptor.
76932 + @Param[in] exception - The exception.
76933 +*//***************************************************************************/
76934 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
76935 + e_FmExceptions exception);
76936 +
76937 +
76938 +/**************************************************************************//**
76939 + @Function t_FmBusErrorCallback
76940 +
76941 + @Description Bus error user callback routine, will be called upon a
76942 + bus error, passing parameters describing the errors and the owner.
76943 +
76944 + @Param[in] h_App - User's application descriptor.
76945 + @Param[in] portType - Port type (e_FmPortType)
76946 + @Param[in] portId - Port id - relative to type.
76947 + @Param[in] addr - Address that caused the error
76948 + @Param[in] tnum - Owner of error
76949 + @Param[in] liodn - Logical IO device number
76950 +*//***************************************************************************/
76951 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
76952 + e_FmPortType portType,
76953 + uint8_t portId,
76954 + uint64_t addr,
76955 + uint8_t tnum,
76956 + uint16_t liodn);
76957 +
76958 +/**************************************************************************//**
76959 + @Description A structure for defining buffer prefix area content.
76960 +*//***************************************************************************/
76961 +typedef struct t_FmBufferPrefixContent {
76962 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
76963 + of the external buffer; Note that the private-area will
76964 + start from the base of the buffer address. */
76965 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
76966 + User may use FM_PORT_GetBufferPrsResult() in order to
76967 + get the parser-result from a buffer. */
76968 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
76969 + User may use FM_PORT_GetBufferTimeStamp() in order to
76970 + get the parser-result from a buffer. */
76971 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
76972 + User may use FM_PORT_GetBufferHashResult() in order to
76973 + get the parser-result from a buffer. */
76974 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
76975 + AD, hash-result, key, etc. */
76976 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
76977 + other value for selecting a data alignment (must be a power of 2);
76978 + if write optimization is used, must be >= 16. */
76979 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
76980 + Note that this field impacts the size of the buffer-prefix
76981 + (i.e. it pushes the data offset);
76982 + This field is irrelevant if DPAA_VERSION==10 */
76983 +} t_FmBufferPrefixContent;
76984 +
76985 +/**************************************************************************//**
76986 + @Description A structure of information about each of the external
76987 + buffer pools used by a port or storage-profile.
76988 +*//***************************************************************************/
76989 +typedef struct t_FmExtPoolParams {
76990 + uint8_t id; /**< External buffer pool id */
76991 + uint16_t size; /**< External buffer pool buffer size */
76992 +} t_FmExtPoolParams;
76993 +
76994 +/**************************************************************************//**
76995 + @Description A structure for informing the driver about the external
76996 + buffer pools allocated in the BM and used by a port or a
76997 + storage-profile.
76998 +*//***************************************************************************/
76999 +typedef struct t_FmExtPools {
77000 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
77001 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
77002 + /**< Parameters for each port */
77003 +} t_FmExtPools;
77004 +
77005 +/**************************************************************************//**
77006 + @Description A structure for defining backup BM Pools.
77007 +*//***************************************************************************/
77008 +typedef struct t_FmBackupBmPools {
77009 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
77010 + must be smaller than the total number of
77011 + pools defined for the specified port.*/
77012 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
77013 + /**< numOfBackupPools pool id's, specifying which
77014 + pools should be used only as backup. Pool
77015 + id's specified here must be a subset of the
77016 + pools used by the specified port.*/
77017 +} t_FmBackupBmPools;
77018 +
77019 +/**************************************************************************//**
77020 + @Description A structure for defining BM pool depletion criteria
77021 +*//***************************************************************************/
77022 +typedef struct t_FmBufPoolDepletion {
77023 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
77024 + a number of pools (all together!) are depleted */
77025 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
77026 + pause frames transmission. */
77027 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
77028 + /**< For each pool, TRUE if it should be considered for
77029 + depletion (Note - this pool must be used by this port!). */
77030 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
77031 + a single-pool is depleted; */
77032 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
77033 + /**< For each pool, TRUE if it should be considered for
77034 + depletion (Note - this pool must be used by this port!) */
77035 +#if (DPAA_VERSION >= 11)
77036 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
77037 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
77038 +#endif /* (DPAA_VERSION >= 11) */
77039 +} t_FmBufPoolDepletion;
77040 +
77041 +/**************************************************************************//**
77042 + @Description A Structure for defining Ucode patch for loading.
77043 +*//***************************************************************************/
77044 +typedef struct t_FmFirmwareParams {
77045 + uint32_t size; /**< Size of uCode */
77046 + uint32_t *p_Code; /**< A pointer to the uCode */
77047 +} t_FmFirmwareParams;
77048 +
77049 +/**************************************************************************//**
77050 + @Description A Structure for defining FM initialization parameters
77051 +*//***************************************************************************/
77052 +typedef struct t_FmParams {
77053 + uint8_t fmId; /**< Index of the FM */
77054 + uint8_t guestId; /**< FM Partition Id */
77055 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
77056 + this field is optional when the FM runs in "guest-mode"
77057 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
77058 + use the memory-map instead of calling the IPC where possible;
77059 + NOTE that this should include ALL common registers of the FM including
77060 + the PCD registers area (i.e. until the VSP pages - 880KB). */
77061 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
77062 + to be used by the FM. */
77063 + uint16_t fmClkFreq; /**< In Mhz;
77064 + Relevant when FM not runs in "guest-mode". */
77065 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
77066 + when fmMacClkRatio = 0, ratio is 2:1
77067 + when fmMacClkRatio = 1, ratio is 1:1 */
77068 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
77069 + Relevant when FM not runs in "guest-mode". */
77070 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
77071 + Relevant when FM not runs in "guest-mode". */
77072 + t_Handle h_App; /**< A handle to an application layer object; This handle will
77073 + be passed by the driver upon calling the above callbacks;
77074 + Relevant when FM not runs in "guest-mode". */
77075 + int irq; /**< FM interrupt source for normal events;
77076 + Relevant when FM not runs in "guest-mode". */
77077 + int errIrq; /**< FM interrupt source for errors;
77078 + Relevant when FM not runs in "guest-mode". */
77079 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
77080 + Relevant when FM not runs in "guest-mode". */
77081 +
77082 +#if (DPAA_VERSION >= 11)
77083 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
77084 + i.e. up to 24KB, depending on the specific chip. */
77085 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
77086 + NOTE: this parameter relevant only when working with multiple partitions. */
77087 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
77088 + NOTE: this parameter relevant only when working with multiple partitions. */
77089 +#endif /* (DPAA_VERSION >= 11) */
77090 +} t_FmParams;
77091 +
77092 +
77093 +/**************************************************************************//**
77094 + @Function FM_Config
77095 +
77096 + @Description Creates the FM module and returns its handle (descriptor).
77097 + This descriptor must be passed as first parameter to all other
77098 + FM function calls.
77099 +
77100 + No actual initialization or configuration of FM hardware is
77101 + done by this routine. All FM parameters get default values that
77102 + may be changed by calling one or more of the advance config routines.
77103 +
77104 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
77105 +
77106 + @Return A handle to the FM object, or NULL for Failure.
77107 +*//***************************************************************************/
77108 +t_Handle FM_Config(t_FmParams *p_FmParams);
77109 +
77110 +/**************************************************************************//**
77111 + @Function FM_Init
77112 +
77113 + @Description Initializes the FM module by defining the software structure
77114 + and configuring the hardware registers.
77115 +
77116 + @Param[in] h_Fm - FM module descriptor
77117 +
77118 + @Return E_OK on success; Error code otherwise.
77119 +*//***************************************************************************/
77120 +t_Error FM_Init(t_Handle h_Fm);
77121 +
77122 +/**************************************************************************//**
77123 + @Function FM_Free
77124 +
77125 + @Description Frees all resources that were assigned to FM module.
77126 +
77127 + Calling this routine invalidates the descriptor.
77128 +
77129 + @Param[in] h_Fm - FM module descriptor
77130 +
77131 + @Return E_OK on success; Error code otherwise.
77132 +*//***************************************************************************/
77133 +t_Error FM_Free(t_Handle h_Fm);
77134 +
77135 +
77136 +/**************************************************************************//**
77137 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
77138 +
77139 + @Description Advanced configuration routines are optional routines that may
77140 + be called in order to change the default driver settings.
77141 +
77142 + Note: Advanced configuration routines are not available for guest partition.
77143 + @{
77144 +*//***************************************************************************/
77145 +
77146 +/**************************************************************************//**
77147 + @Description Enum for selecting DMA debug mode
77148 +*//***************************************************************************/
77149 +typedef enum e_FmDmaDbgCntMode {
77150 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
77151 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
77152 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
77153 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
77154 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
77155 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
77156 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
77157 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
77158 +} e_FmDmaDbgCntMode;
77159 +
77160 +/**************************************************************************//**
77161 + @Description Enum for selecting DMA Cache Override
77162 +*//***************************************************************************/
77163 +typedef enum e_FmDmaCacheOverride {
77164 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
77165 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
77166 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
77167 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
77168 +} e_FmDmaCacheOverride;
77169 +
77170 +/**************************************************************************//**
77171 + @Description Enum for selecting DMA External Bus Priority
77172 +*//***************************************************************************/
77173 +typedef enum e_FmDmaExtBusPri {
77174 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
77175 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
77176 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
77177 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
77178 +} e_FmDmaExtBusPri;
77179 +
77180 +/**************************************************************************//**
77181 + @Description Enum for choosing the field that will be output on AID
77182 +*//***************************************************************************/
77183 +typedef enum e_FmDmaAidMode {
77184 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
77185 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
77186 +} e_FmDmaAidMode;
77187 +
77188 +/**************************************************************************//**
77189 + @Description Enum for selecting FPM Catastrophic error behavior
77190 +*//***************************************************************************/
77191 +typedef enum e_FmCatastrophicErr {
77192 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
77193 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
77194 +} e_FmCatastrophicErr;
77195 +
77196 +/**************************************************************************//**
77197 + @Description Enum for selecting FPM DMA Error behavior
77198 +*//***************************************************************************/
77199 +typedef enum e_FmDmaErr {
77200 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
77201 + error (e_FmCatastrophicErr)*/
77202 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
77203 +} e_FmDmaErr;
77204 +
77205 +/**************************************************************************//**
77206 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
77207 +*//***************************************************************************/
77208 +typedef enum e_FmDmaEmergencyLevel {
77209 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
77210 + e_FM_DMA_EM_SOS /**< SOS emergency */
77211 +} e_FmDmaEmergencyLevel;
77212 +
77213 +/**************************************************************************//**
77214 + @Collection Enum for selecting DMA Emergency options
77215 +*//***************************************************************************/
77216 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
77217 +
77218 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
77219 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
77220 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
77221 +/* @} */
77222 +
77223 +/**************************************************************************//**
77224 + @Description A structure for defining DMA emergency level
77225 +*//***************************************************************************/
77226 +typedef struct t_FmDmaEmergency {
77227 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
77228 + should be enabled */
77229 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
77230 +} t_FmDmaEmergency;
77231 +
77232 +/**************************************************************************//*
77233 + @Description structure for defining FM threshold
77234 +*//***************************************************************************/
77235 +typedef struct t_FmThresholds {
77236 + uint8_t dispLimit; /**< The number of times a frames may
77237 + be passed in the FM before assumed to
77238 + be looping. */
77239 + uint8_t prsDispTh; /**< This is the number pf packets that may be
77240 + queued in the parser dispatch queue*/
77241 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
77242 + queued in the policer dispatch queue*/
77243 + uint8_t kgDispTh; /**< This is the number pf packets that may be
77244 + queued in the keygen dispatch queue*/
77245 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
77246 + queued in the BMI dispatch queue*/
77247 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
77248 + queued in the QMI enqueue dispatch queue*/
77249 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
77250 + queued in the QMI dequeue dispatch queue*/
77251 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
77252 + queued in fmCtl1 dispatch queue*/
77253 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
77254 + queued in fmCtl2 dispatch queue*/
77255 +} t_FmThresholds;
77256 +
77257 +/**************************************************************************//*
77258 + @Description structure for defining DMA thresholds
77259 +*//***************************************************************************/
77260 +typedef struct t_FmDmaThresholds {
77261 + uint8_t assertEmergency; /**< When this value is reached,
77262 + assert emergency (Threshold)*/
77263 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
77264 + until this value is reached (Hystheresis) */
77265 +} t_FmDmaThresholds;
77266 +
77267 +/**************************************************************************//**
77268 + @Function t_FmResetOnInitOverrideCallback
77269 +
77270 + @Description FMan specific reset on init user callback routine,
77271 + will be used to override the standard FMan reset on init procedure
77272 +
77273 + @Param[in] h_Fm - FMan handler
77274 +*//***************************************************************************/
77275 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
77276 +
77277 +/**************************************************************************//**
77278 + @Function FM_ConfigResetOnInit
77279 +
77280 + @Description Define whether to reset the FM before initialization.
77281 + Change the default configuration [DEFAULT_resetOnInit].
77282 +
77283 + @Param[in] h_Fm A handle to an FM Module.
77284 + @Param[in] enable When TRUE, FM will be reset before any initialization.
77285 +
77286 + @Return E_OK on success; Error code otherwise.
77287 +
77288 + @Cautions Allowed only following FM_Config() and before FM_Init().
77289 + This routine should NOT be called from guest-partition
77290 + (i.e. guestId != NCSW_MASTER_ID)
77291 +*//***************************************************************************/
77292 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
77293 +
77294 +/**************************************************************************//**
77295 + @Function FM_ConfigResetOnInitOverrideCallback
77296 +
77297 + @Description Define a special reset of FM before initialization.
77298 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
77299 +
77300 + @Param[in] h_Fm A handle to an FM Module.
77301 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
77302 +
77303 + @Return E_OK on success; Error code otherwise.
77304 +
77305 + @Cautions Allowed only following FM_Config() and before FM_Init().
77306 + This routine should NOT be called from guest-partition
77307 + (i.e. guestId != NCSW_MASTER_ID)
77308 +*//***************************************************************************/
77309 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
77310 +
77311 +/**************************************************************************//**
77312 + @Function FM_ConfigTotalFifoSize
77313 +
77314 + @Description Define Total FIFO size for the whole FM.
77315 + Calling this routine changes the total Fifo size in the internal driver
77316 + data base from its default configuration [DEFAULT_totalFifoSize]
77317 +
77318 + @Param[in] h_Fm A handle to an FM Module.
77319 + @Param[in] totalFifoSize The selected new value.
77320 +
77321 + @Return E_OK on success; Error code otherwise.
77322 +
77323 + @Cautions Allowed only following FM_Config() and before FM_Init().
77324 + This routine should NOT be called from guest-partition
77325 + (i.e. guestId != NCSW_MASTER_ID)
77326 +*//***************************************************************************/
77327 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
77328 +
77329 + /**************************************************************************//**
77330 + @Function FM_ConfigDmaCacheOverride
77331 +
77332 + @Description Define cache override mode.
77333 + Calling this routine changes the cache override mode
77334 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
77335 +
77336 + @Param[in] h_Fm A handle to an FM Module.
77337 + @Param[in] cacheOverride The selected new value.
77338 +
77339 + @Return E_OK on success; Error code otherwise.
77340 +
77341 + @Cautions Allowed only following FM_Config() and before FM_Init().
77342 + This routine should NOT be called from guest-partition
77343 + (i.e. guestId != NCSW_MASTER_ID)
77344 +*//***************************************************************************/
77345 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
77346 +
77347 +/**************************************************************************//**
77348 + @Function FM_ConfigDmaAidOverride
77349 +
77350 + @Description Define DMA AID override mode.
77351 + Calling this routine changes the AID override mode
77352 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
77353 +
77354 + @Param[in] h_Fm A handle to an FM Module.
77355 + @Param[in] aidOverride The selected new value.
77356 +
77357 + @Return E_OK on success; Error code otherwise.
77358 +
77359 + @Cautions Allowed only following FM_Config() and before FM_Init().
77360 + This routine should NOT be called from guest-partition
77361 + (i.e. guestId != NCSW_MASTER_ID)
77362 +*//***************************************************************************/
77363 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
77364 +
77365 +/**************************************************************************//**
77366 + @Function FM_ConfigDmaAidMode
77367 +
77368 + @Description Define DMA AID mode.
77369 + Calling this routine changes the AID mode in the internal
77370 + driver data base from its default configuration [DEFAULT_aidMode]
77371 +
77372 + @Param[in] h_Fm A handle to an FM Module.
77373 + @Param[in] aidMode The selected new value.
77374 +
77375 + @Return E_OK on success; Error code otherwise.
77376 +
77377 + @Cautions Allowed only following FM_Config() and before FM_Init().
77378 + This routine should NOT be called from guest-partition
77379 + (i.e. guestId != NCSW_MASTER_ID)
77380 +*//***************************************************************************/
77381 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
77382 +
77383 +/**************************************************************************//**
77384 + @Function FM_ConfigDmaAxiDbgNumOfBeats
77385 +
77386 + @Description Define DMA AXI number of beats.
77387 + Calling this routine changes the AXI number of beats in the internal
77388 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
77389 +
77390 + @Param[in] h_Fm A handle to an FM Module.
77391 + @Param[in] axiDbgNumOfBeats The selected new value.
77392 +
77393 + @Return E_OK on success; Error code otherwise.
77394 +
77395 + @Cautions Allowed only following FM_Config() and before FM_Init().
77396 + This routine should NOT be called from guest-partition
77397 + (i.e. guestId != NCSW_MASTER_ID)
77398 +*//***************************************************************************/
77399 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
77400 +
77401 +/**************************************************************************//**
77402 + @Function FM_ConfigDmaCamNumOfEntries
77403 +
77404 + @Description Define number of CAM entries.
77405 + Calling this routine changes the number of CAM entries in the internal
77406 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
77407 +
77408 + @Param[in] h_Fm A handle to an FM Module.
77409 + @Param[in] numOfEntries The selected new value.
77410 +
77411 + @Return E_OK on success; Error code otherwise.
77412 +
77413 + @Cautions Allowed only following FM_Config() and before FM_Init().
77414 + This routine should NOT be called from guest-partition
77415 + (i.e. guestId != NCSW_MASTER_ID)
77416 +*//***************************************************************************/
77417 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
77418 +
77419 +/**************************************************************************//**
77420 + @Function FM_ConfigEnableCounters
77421 +
77422 + @Description Obsolete, always return E_OK.
77423 +
77424 + @Param[in] h_Fm A handle to an FM Module.
77425 +
77426 + @Return E_OK on success; Error code otherwise.
77427 +*//***************************************************************************/
77428 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
77429 +
77430 +/**************************************************************************//**
77431 + @Function FM_ConfigDmaDbgCounter
77432 +
77433 + @Description Define DMA debug counter.
77434 + Calling this routine changes the number of the DMA debug counter in the internal
77435 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
77436 +
77437 + @Param[in] h_Fm A handle to an FM Module.
77438 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
77439 +
77440 + @Return E_OK on success; Error code otherwise.
77441 +
77442 + @Cautions Allowed only following FM_Config() and before FM_Init().
77443 + This routine should NOT be called from guest-partition
77444 + (i.e. guestId != NCSW_MASTER_ID)
77445 +*//***************************************************************************/
77446 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
77447 +
77448 +/**************************************************************************//**
77449 + @Function FM_ConfigDmaStopOnBusErr
77450 +
77451 + @Description Define bus error behavior.
77452 + Calling this routine changes the bus error behavior definition
77453 + in the internal driver data base from its default
77454 + configuration [DEFAULT_dmaStopOnBusError].
77455 +
77456 + @Param[in] h_Fm A handle to an FM Module.
77457 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
77458 +
77459 + @Return E_OK on success; Error code otherwise.
77460 +
77461 + @Cautions Allowed only following FM_Config() and before FM_Init().
77462 + Only if bus error is enabled.
77463 + This routine should NOT be called from guest-partition
77464 + (i.e. guestId != NCSW_MASTER_ID)
77465 +*//***************************************************************************/
77466 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
77467 +
77468 +/**************************************************************************//**
77469 + @Function FM_ConfigDmaEmergency
77470 +
77471 + @Description Define DMA emergency.
77472 + Calling this routine changes the DMA emergency definition
77473 + in the internal driver data base from its default
77474 + configuration where's it's disabled.
77475 +
77476 + @Param[in] h_Fm A handle to an FM Module.
77477 + @Param[in] p_Emergency An OR mask of all required options.
77478 +
77479 + @Return E_OK on success; Error code otherwise.
77480 +
77481 + @Cautions Allowed only following FM_Config() and before FM_Init().
77482 + This routine should NOT be called from guest-partition
77483 + (i.e. guestId != NCSW_MASTER_ID)
77484 +*//***************************************************************************/
77485 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
77486 +
77487 +/**************************************************************************//**
77488 + @Function FM_ConfigDmaErr
77489 +
77490 + @Description DMA error treatment.
77491 + Calling this routine changes the DMA error treatment
77492 + in the internal driver data base from its default
77493 + configuration [DEFAULT_dmaErr].
77494 +
77495 + @Param[in] h_Fm A handle to an FM Module.
77496 + @Param[in] dmaErr The selected new choice.
77497 +
77498 + @Return E_OK on success; Error code otherwise.
77499 +
77500 + @Cautions Allowed only following FM_Config() and before FM_Init().
77501 + This routine should NOT be called from guest-partition
77502 + (i.e. guestId != NCSW_MASTER_ID)
77503 +*//***************************************************************************/
77504 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
77505 +
77506 +/**************************************************************************//**
77507 + @Function FM_ConfigCatastrophicErr
77508 +
77509 + @Description Define FM behavior on catastrophic error.
77510 + Calling this routine changes the FM behavior on catastrophic
77511 + error in the internal driver data base from its default
77512 + [DEFAULT_catastrophicErr].
77513 +
77514 + @Param[in] h_Fm A handle to an FM Module.
77515 + @Param[in] catastrophicErr The selected new choice.
77516 +
77517 + @Return E_OK on success; Error code otherwise.
77518 +
77519 + @Cautions Allowed only following FM_Config() and before FM_Init().
77520 + This routine should NOT be called from guest-partition
77521 + (i.e. guestId != NCSW_MASTER_ID)
77522 +*//***************************************************************************/
77523 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
77524 +
77525 +/**************************************************************************//**
77526 + @Function FM_ConfigEnableMuramTestMode
77527 +
77528 + @Description Enable MURAM test mode.
77529 + Calling this routine changes the internal driver data base
77530 + from its default selection of test mode where it's disabled.
77531 + This routine is only avaiable on old FM revisions (FMan v2).
77532 +
77533 + @Param[in] h_Fm A handle to an FM Module.
77534 +
77535 + @Return E_OK on success; Error code otherwise.
77536 +
77537 + @Cautions Allowed only following FM_Config() and before FM_Init().
77538 + This routine should NOT be called from guest-partition
77539 + (i.e. guestId != NCSW_MASTER_ID)
77540 +*//***************************************************************************/
77541 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
77542 +
77543 +/**************************************************************************//**
77544 + @Function FM_ConfigEnableIramTestMode
77545 +
77546 + @Description Enable IRAM test mode.
77547 + Calling this routine changes the internal driver data base
77548 + from its default selection of test mode where it's disabled.
77549 + This routine is only avaiable on old FM revisions (FMan v2).
77550 +
77551 + @Param[in] h_Fm A handle to an FM Module.
77552 +
77553 + @Return E_OK on success; Error code otherwise.
77554 +
77555 + @Cautions Allowed only following FM_Config() and before FM_Init().
77556 + This routine should NOT be called from guest-partition
77557 + (i.e. guestId != NCSW_MASTER_ID)
77558 +*//***************************************************************************/
77559 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
77560 +
77561 +/**************************************************************************//**
77562 + @Function FM_ConfigHaltOnExternalActivation
77563 +
77564 + @Description Define FM behavior on external halt activation.
77565 + Calling this routine changes the FM behavior on external halt
77566 + activation in the internal driver data base from its default
77567 + [DEFAULT_haltOnExternalActivation].
77568 +
77569 + @Param[in] h_Fm A handle to an FM Module.
77570 + @Param[in] enable TRUE to enable halt on external halt
77571 + activation.
77572 +
77573 + @Return E_OK on success; Error code otherwise.
77574 +
77575 + @Cautions Allowed only following FM_Config() and before FM_Init().
77576 + This routine should NOT be called from guest-partition
77577 + (i.e. guestId != NCSW_MASTER_ID)
77578 +*//***************************************************************************/
77579 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
77580 +
77581 +/**************************************************************************//**
77582 + @Function FM_ConfigHaltOnUnrecoverableEccError
77583 +
77584 + @Description Define FM behavior on external halt activation.
77585 + Calling this routine changes the FM behavior on unrecoverable
77586 + ECC error in the internal driver data base from its default
77587 + [DEFAULT_haltOnUnrecoverableEccError].
77588 + This routine is only avaiable on old FM revisions (FMan v2).
77589 +
77590 + @Param[in] h_Fm A handle to an FM Module.
77591 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
77592 +
77593 + @Return E_OK on success; Error code otherwise.
77594 +
77595 + @Cautions Allowed only following FM_Config() and before FM_Init().
77596 + This routine should NOT be called from guest-partition
77597 + (i.e. guestId != NCSW_MASTER_ID)
77598 +*//***************************************************************************/
77599 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
77600 +
77601 +/**************************************************************************//**
77602 + @Function FM_ConfigException
77603 +
77604 + @Description Define FM exceptions.
77605 + Calling this routine changes the exceptions defaults in the
77606 + internal driver data base where all exceptions are enabled.
77607 +
77608 + @Param[in] h_Fm A handle to an FM Module.
77609 + @Param[in] exception The exception to be selected.
77610 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77611 +
77612 + @Return E_OK on success; Error code otherwise.
77613 +
77614 + @Cautions Allowed only following FM_Config() and before FM_Init().
77615 + This routine should NOT be called from guest-partition
77616 + (i.e. guestId != NCSW_MASTER_ID)
77617 +*//***************************************************************************/
77618 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77619 +
77620 +/**************************************************************************//**
77621 + @Function FM_ConfigExternalEccRamsEnable
77622 +
77623 + @Description Select external ECC enabling.
77624 + Calling this routine changes the ECC enabling control in the internal
77625 + driver data base from its default [DEFAULT_externalEccRamsEnable].
77626 + When this option is enabled Rams ECC enabling is not effected
77627 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
77628 +
77629 + @Param[in] h_Fm A handle to an FM Module.
77630 + @Param[in] enable TRUE to enable this option.
77631 +
77632 + @Return E_OK on success; Error code otherwise.
77633 +
77634 + @Cautions Allowed only following FM_Config() and before FM_Init().
77635 + This routine should NOT be called from guest-partition
77636 + (i.e. guestId != NCSW_MASTER_ID)
77637 +*//***************************************************************************/
77638 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
77639 +
77640 +/**************************************************************************//**
77641 + @Function FM_ConfigTnumAgingPeriod
77642 +
77643 + @Description Define Tnum aging period.
77644 + Calling this routine changes the Tnum aging of dequeue TNUMs
77645 + in the QMI in the internal driver data base from its default
77646 + [DEFAULT_tnumAgingPeriod].
77647 +
77648 + @Param[in] h_Fm A handle to an FM Module.
77649 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
77650 + Note that period is recalculated in units of
77651 + 64 FM clocks. Driver will pick the closest
77652 + possible period.
77653 +
77654 + @Return E_OK on success; Error code otherwise.
77655 +
77656 + @Cautions Allowed only following FM_Config() and before FM_Init().
77657 + This routine should NOT be called from guest-partition
77658 + (i.e. guestId != NCSW_MASTER_ID)
77659 + NOTE that if some MAC is configured for PFC, '0' value is NOT
77660 + allowed.
77661 +*//***************************************************************************/
77662 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
77663 +
77664 +/**************************************************************************//*
77665 + @Function FM_ConfigDmaEmergencySmoother
77666 +
77667 + @Description Define DMA emergency smoother.
77668 + Calling this routine changes the definition of the minimum
77669 + amount of DATA beats transferred on the AXI READ and WRITE
77670 + ports before lowering the emergency level.
77671 + By default smoother is disabled.
77672 +
77673 + @Param[in] h_Fm A handle to an FM Module.
77674 + @Param[in] emergencyCnt emergency switching counter.
77675 +
77676 + @Return E_OK on success; Error code otherwise.
77677 +
77678 + @Cautions Allowed only following FM_Config() and before FM_Init().
77679 + This routine should NOT be called from guest-partition
77680 + (i.e. guestId != NCSW_MASTER_ID)
77681 +*//***************************************************************************/
77682 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
77683 +
77684 +/**************************************************************************//*
77685 + @Function FM_ConfigThresholds
77686 +
77687 + @Description Calling this routine changes the internal driver data base
77688 + from its default FM threshold configuration:
77689 + dispLimit: [DEFAULT_dispLimit]
77690 + prsDispTh: [DEFAULT_prsDispTh]
77691 + plcrDispTh: [DEFAULT_plcrDispTh]
77692 + kgDispTh: [DEFAULT_kgDispTh]
77693 + bmiDispTh: [DEFAULT_bmiDispTh]
77694 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
77695 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
77696 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
77697 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
77698 +
77699 +
77700 + @Param[in] h_Fm A handle to an FM Module.
77701 + @Param[in] p_FmThresholds A structure of threshold parameters.
77702 +
77703 + @Return E_OK on success; Error code otherwise.
77704 +
77705 + @Cautions Allowed only following FM_Config() and before FM_Init().
77706 + This routine should NOT be called from guest-partition
77707 + (i.e. guestId != NCSW_MASTER_ID)
77708 +*//***************************************************************************/
77709 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
77710 +
77711 +/**************************************************************************//*
77712 + @Function FM_ConfigDmaSosEmergencyThreshold
77713 +
77714 + @Description Calling this routine changes the internal driver data base
77715 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
77716 +
77717 + @Param[in] h_Fm A handle to an FM Module.
77718 + @Param[in] dmaSosEmergency The selected new value.
77719 +
77720 + @Return E_OK on success; Error code otherwise.
77721 +
77722 + @Cautions Allowed only following FM_Config() and before FM_Init().
77723 + This routine should NOT be called from guest-partition
77724 + (i.e. guestId != NCSW_MASTER_ID)
77725 +*//***************************************************************************/
77726 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
77727 +
77728 +/**************************************************************************//*
77729 + @Function FM_ConfigDmaWriteBufThresholds
77730 +
77731 + @Description Calling this routine changes the internal driver data base
77732 + from its default configuration of DMA write buffer threshold
77733 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
77734 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
77735 + This routine is only avaiable on old FM revisions (FMan v2).
77736 +
77737 + @Param[in] h_Fm A handle to an FM Module.
77738 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77739 + When 'assertEmergency' value is reached, emergency is asserted,
77740 + then it is held until 'clearEmergency' value is reached.
77741 +
77742 + @Return E_OK on success; Error code otherwise.
77743 +
77744 + @Cautions Allowed only following FM_Config() and before FM_Init().
77745 + This routine should NOT be called from guest-partition
77746 + (i.e. guestId != NCSW_MASTER_ID)
77747 +*//***************************************************************************/
77748 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77749 +
77750 + /**************************************************************************//*
77751 + @Function FM_ConfigDmaCommQThresholds
77752 +
77753 + @Description Calling this routine changes the internal driver data base
77754 + from its default configuration of DMA command queue threshold
77755 + assertEmergency: [DEFAULT_dmaCommQLow]
77756 + clearEmergency: [DEFAULT_dmaCommQHigh]
77757 +
77758 + @Param[in] h_Fm A handle to an FM Module.
77759 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77760 + When 'assertEmergency' value is reached, emergency is asserted,
77761 + then it is held until 'clearEmergency' value is reached..
77762 +
77763 + @Return E_OK on success; Error code otherwise.
77764 +
77765 + @Cautions Allowed only following FM_Config() and before FM_Init().
77766 + This routine should NOT be called from guest-partition
77767 + (i.e. guestId != NCSW_MASTER_ID)
77768 +*//***************************************************************************/
77769 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77770 +
77771 +/**************************************************************************//*
77772 + @Function FM_ConfigDmaReadBufThresholds
77773 +
77774 + @Description Calling this routine changes the internal driver data base
77775 + from its default configuration of DMA read buffer threshold
77776 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
77777 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
77778 + This routine is only avaiable on old FM revisions (FMan v2).
77779 +
77780 + @Param[in] h_Fm A handle to an FM Module.
77781 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
77782 + When 'assertEmergency' value is reached, emergency is asserted,
77783 + then it is held until 'clearEmergency' value is reached..
77784 +
77785 + @Return E_OK on success; Error code otherwise.
77786 +
77787 + @Cautions Allowed only following FM_Config() and before FM_Init().
77788 + This routine should NOT be called from guest-partition
77789 + (i.e. guestId != NCSW_MASTER_ID)
77790 +*//***************************************************************************/
77791 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
77792 +
77793 +/**************************************************************************//*
77794 + @Function FM_ConfigDmaWatchdog
77795 +
77796 + @Description Calling this routine changes the internal driver data base
77797 + from its default watchdog configuration, which is disabled
77798 + [DEFAULT_dmaWatchdog].
77799 +
77800 + @Param[in] h_Fm A handle to an FM Module.
77801 + @Param[in] watchDogValue The selected new value - in microseconds.
77802 +
77803 + @Return E_OK on success; Error code otherwise.
77804 +
77805 + @Cautions Allowed only following FM_Config() and before FM_Init().
77806 + This routine should NOT be called from guest-partition
77807 + (i.e. guestId != NCSW_MASTER_ID)
77808 +*//***************************************************************************/
77809 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
77810 +
77811 +/** @} */ /* end of FM_advanced_init_grp group */
77812 +/** @} */ /* end of FM_init_grp group */
77813 +
77814 +
77815 +/**************************************************************************//**
77816 + @Group FM_runtime_control_grp FM Runtime Control Unit
77817 +
77818 + @Description FM Runtime control unit API functions, definitions and enums.
77819 + The FM driver provides a set of control routines.
77820 + These routines may only be called after the module was fully
77821 + initialized (both configuration and initialization routines were
77822 + called). They are typically used to get information from hardware
77823 + (status, counters/statistics, revision etc.), to modify a current
77824 + state or to force/enable a required action. Run-time control may
77825 + be called whenever necessary and as many times as needed.
77826 + @{
77827 +*//***************************************************************************/
77828 +
77829 +/**************************************************************************//**
77830 + @Collection General FM defines.
77831 +*//***************************************************************************/
77832 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
77833 + FM_MAX_NUM_OF_1G_RX_PORTS + \
77834 + FM_MAX_NUM_OF_10G_RX_PORTS + \
77835 + FM_MAX_NUM_OF_1G_TX_PORTS + \
77836 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
77837 +/* @} */
77838 +
77839 +/**************************************************************************//*
77840 + @Description A Structure for Port bandwidth requirement. Port is identified
77841 + by type and relative id.
77842 +*//***************************************************************************/
77843 +typedef struct t_FmPortBandwidth {
77844 + e_FmPortType type; /**< FM port type */
77845 + uint8_t relativePortId; /**< Type relative port id */
77846 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
77847 +} t_FmPortBandwidth;
77848 +
77849 +/**************************************************************************//*
77850 + @Description A Structure containing an array of Port bandwidth requirements.
77851 + The user should state the ports requiring bandwidth in terms of
77852 + percentage - i.e. all port's bandwidths in the array must add
77853 + up to 100.
77854 +*//***************************************************************************/
77855 +typedef struct t_FmPortsBandwidthParams {
77856 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
77857 + number of valid entries in the array below */
77858 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
77859 + /**< for each port, it's bandwidth (all port's
77860 + bandwidths must add up to 100.*/
77861 +} t_FmPortsBandwidthParams;
77862 +
77863 +/**************************************************************************//**
77864 + @Description DMA Emergency control on MURAM
77865 +*//***************************************************************************/
77866 +typedef enum e_FmDmaMuramPort {
77867 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
77868 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
77869 +} e_FmDmaMuramPort;
77870 +
77871 +/**************************************************************************//**
77872 + @Description Enum for defining FM counters
77873 +*//***************************************************************************/
77874 +typedef enum e_FmCounters {
77875 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
77876 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
77877 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
77878 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
77879 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
77880 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
77881 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
77882 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
77883 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
77884 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
77885 +} e_FmCounters;
77886 +
77887 +/**************************************************************************//**
77888 + @Description A Structure for returning FM revision information
77889 +*//***************************************************************************/
77890 +typedef struct t_FmRevisionInfo {
77891 + uint8_t majorRev; /**< Major revision */
77892 + uint8_t minorRev; /**< Minor revision */
77893 +} t_FmRevisionInfo;
77894 +
77895 +/**************************************************************************//**
77896 + @Description A Structure for returning FM ctrl code revision information
77897 +*//***************************************************************************/
77898 +typedef struct t_FmCtrlCodeRevisionInfo {
77899 + uint16_t packageRev; /**< Package revision */
77900 + uint8_t majorRev; /**< Major revision */
77901 + uint8_t minorRev; /**< Minor revision */
77902 +} t_FmCtrlCodeRevisionInfo;
77903 +
77904 +/**************************************************************************//**
77905 + @Description A Structure for defining DMA status
77906 +*//***************************************************************************/
77907 +typedef struct t_FmDmaStatus {
77908 + bool cmqNotEmpty; /**< Command queue is not empty */
77909 + bool busError; /**< Bus error occurred */
77910 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
77911 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
77912 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
77913 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
77914 +} t_FmDmaStatus;
77915 +
77916 +/**************************************************************************//**
77917 + @Description A Structure for obtaining FM controller monitor values
77918 +*//***************************************************************************/
77919 +typedef struct t_FmCtrlMon {
77920 + uint8_t percentCnt[2]; /**< Percentage value */
77921 +} t_FmCtrlMon;
77922 +
77923 +
77924 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
77925 +/**************************************************************************//**
77926 + @Function FM_DumpRegs
77927 +
77928 + @Description Dumps all FM registers
77929 +
77930 + @Param[in] h_Fm A handle to an FM Module.
77931 +
77932 + @Return E_OK on success;
77933 +
77934 + @Cautions Allowed only following FM_Init().
77935 +*//***************************************************************************/
77936 +t_Error FM_DumpRegs(t_Handle h_Fm);
77937 +#endif /* (defined(DEBUG_ERRORS) && ... */
77938 +
77939 +/**************************************************************************//**
77940 + @Function FM_SetException
77941 +
77942 + @Description Calling this routine enables/disables the specified exception.
77943 +
77944 + @Param[in] h_Fm A handle to an FM Module.
77945 + @Param[in] exception The exception to be selected.
77946 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
77947 +
77948 + @Return E_OK on success; Error code otherwise.
77949 +
77950 + @Cautions Allowed only following FM_Init().
77951 + This routine should NOT be called from guest-partition
77952 + (i.e. guestId != NCSW_MASTER_ID)
77953 +*//***************************************************************************/
77954 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
77955 +
77956 +/**************************************************************************//**
77957 + @Function FM_EnableRamsEcc
77958 +
77959 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77960 + MURAM, Parser, Keygen, Policer, etc.
77961 + Note:
77962 + If FM_ConfigExternalEccRamsEnable was called to enable external
77963 + setting of ECC, this routine effects IRAM ECC only.
77964 + This routine is also called by the driver if an ECC exception is
77965 + enabled.
77966 +
77967 + @Param[in] h_Fm A handle to an FM Module.
77968 +
77969 + @Return E_OK on success; Error code otherwise.
77970 +
77971 + @Cautions Allowed only following FM_Config() and before FM_Init().
77972 + This routine should NOT be called from guest-partition
77973 + (i.e. guestId != NCSW_MASTER_ID)
77974 +*//***************************************************************************/
77975 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
77976 +
77977 +/**************************************************************************//**
77978 + @Function FM_DisableRamsEcc
77979 +
77980 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
77981 + MURAM, Parser, Keygen, Policer, etc.
77982 + Note:
77983 + If FM_ConfigExternalEccRamsEnable was called to enable external
77984 + setting of ECC, this routine effects IRAM ECC only.
77985 + In opposed to FM_EnableRamsEcc, this routine must be called
77986 + explicitly to disable all Rams ECC.
77987 +
77988 + @Param[in] h_Fm A handle to an FM Module.
77989 +
77990 + @Return E_OK on success; Error code otherwise.
77991 +
77992 + @Cautions Allowed only following FM_Config() and before FM_Init().
77993 + This routine should NOT be called from guest-partition
77994 + (i.e. guestId != NCSW_MASTER_ID)
77995 +*//***************************************************************************/
77996 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
77997 +
77998 +/**************************************************************************//**
77999 + @Function FM_GetRevision
78000 +
78001 + @Description Returns the FM revision
78002 +
78003 + @Param[in] h_Fm A handle to an FM Module.
78004 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
78005 +
78006 + @Return E_OK on success; Error code otherwise.
78007 +
78008 + @Cautions Allowed only following FM_Init().
78009 +*//***************************************************************************/
78010 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
78011 +
78012 +/**************************************************************************//**
78013 + @Function FM_GetFmanCtrlCodeRevision
78014 +
78015 + @Description Returns the Fman controller code revision
78016 +
78017 + @Param[in] h_Fm A handle to an FM Module.
78018 + @Param[out] p_RevisionInfo A structure of revision information parameters.
78019 +
78020 + @Return E_OK on success; Error code otherwise.
78021 +
78022 + @Cautions Allowed only following FM_Init().
78023 +*//***************************************************************************/
78024 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
78025 +
78026 +/**************************************************************************//**
78027 + @Function FM_GetCounter
78028 +
78029 + @Description Reads one of the FM counters.
78030 +
78031 + @Param[in] h_Fm A handle to an FM Module.
78032 + @Param[in] counter The requested counter.
78033 +
78034 + @Return Counter's current value.
78035 +
78036 + @Cautions Allowed only following FM_Init().
78037 + Note that it is user's responsibility to call this routine only
78038 + for enabled counters, and there will be no indication if a
78039 + disabled counter is accessed.
78040 +*//***************************************************************************/
78041 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
78042 +
78043 +/**************************************************************************//**
78044 + @Function FM_ModifyCounter
78045 +
78046 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
78047 +
78048 + @Param[in] h_Fm A handle to an FM Module.
78049 + @Param[in] counter The requested counter.
78050 + @Param[in] val The requested value to be written into the counter.
78051 +
78052 + @Return E_OK on success; Error code otherwise.
78053 +
78054 + @Cautions Allowed only following FM_Init().
78055 + This routine should NOT be called from guest-partition
78056 + (i.e. guestId != NCSW_MASTER_ID)
78057 +*//***************************************************************************/
78058 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
78059 +
78060 +/**************************************************************************//**
78061 + @Function FM_Resume
78062 +
78063 + @Description Release FM after halt FM command or after unrecoverable ECC error.
78064 +
78065 + @Param[in] h_Fm A handle to an FM Module.
78066 +
78067 + @Return E_OK on success; Error code otherwise.
78068 +
78069 + @Cautions Allowed only following FM_Init().
78070 + This routine should NOT be called from guest-partition
78071 + (i.e. guestId != NCSW_MASTER_ID)
78072 +*//***************************************************************************/
78073 +void FM_Resume(t_Handle h_Fm);
78074 +
78075 +/**************************************************************************//**
78076 + @Function FM_SetDmaEmergency
78077 +
78078 + @Description Manual emergency set
78079 +
78080 + @Param[in] h_Fm A handle to an FM Module.
78081 + @Param[in] muramPort MURAM direction select.
78082 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
78083 +
78084 + @Return None.
78085 +
78086 + @Cautions Allowed only following FM_Init().
78087 + This routine should NOT be called from guest-partition
78088 + (i.e. guestId != NCSW_MASTER_ID)
78089 +*//***************************************************************************/
78090 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
78091 +
78092 +/**************************************************************************//**
78093 + @Function FM_SetDmaExtBusPri
78094 +
78095 + @Description Set the DMA external bus priority
78096 +
78097 + @Param[in] h_Fm A handle to an FM Module.
78098 + @Param[in] pri External bus priority select
78099 +
78100 + @Return None.
78101 +
78102 + @Cautions Allowed only following FM_Init().
78103 + This routine should NOT be called from guest-partition
78104 + (i.e. guestId != NCSW_MASTER_ID)
78105 +*//***************************************************************************/
78106 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
78107 +
78108 +/**************************************************************************//**
78109 + @Function FM_GetDmaStatus
78110 +
78111 + @Description Reads the DMA current status
78112 +
78113 + @Param[in] h_Fm A handle to an FM Module.
78114 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
78115 +
78116 + @Cautions Allowed only following FM_Init().
78117 +*//***************************************************************************/
78118 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
78119 +
78120 +/**************************************************************************//**
78121 + @Function FM_ErrorIsr
78122 +
78123 + @Description FM interrupt-service-routine for errors.
78124 +
78125 + @Param[in] h_Fm A handle to an FM Module.
78126 +
78127 + @Return E_OK on success; E_EMPTY if no errors found in register, other
78128 + error code otherwise.
78129 +
78130 + @Cautions Allowed only following FM_Init().
78131 + This routine should NOT be called from guest-partition
78132 + (i.e. guestId != NCSW_MASTER_ID)
78133 +*//***************************************************************************/
78134 +t_Error FM_ErrorIsr(t_Handle h_Fm);
78135 +
78136 +/**************************************************************************//**
78137 + @Function FM_EventIsr
78138 +
78139 + @Description FM interrupt-service-routine for normal events.
78140 +
78141 + @Param[in] h_Fm A handle to an FM Module.
78142 +
78143 + @Cautions Allowed only following FM_Init().
78144 + This routine should NOT be called from guest-partition
78145 + (i.e. guestId != NCSW_MASTER_ID)
78146 +*//***************************************************************************/
78147 +void FM_EventIsr(t_Handle h_Fm);
78148 +
78149 +/**************************************************************************//**
78150 + @Function FM_GetSpecialOperationCoding
78151 +
78152 + @Description Return a specific coding according to the input mask.
78153 +
78154 + @Param[in] h_Fm A handle to an FM Module.
78155 + @Param[in] spOper special operation mask.
78156 + @Param[out] p_SpOperCoding special operation code.
78157 +
78158 + @Return E_OK on success; Error code otherwise.
78159 +
78160 + @Cautions Allowed only following FM_Init().
78161 +*//***************************************************************************/
78162 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
78163 + fmSpecialOperations_t spOper,
78164 + uint8_t *p_SpOperCoding);
78165 +
78166 +/**************************************************************************//**
78167 + @Function FM_CtrlMonStart
78168 +
78169 + @Description Start monitoring utilization of all available FM controllers.
78170 +
78171 + In order to obtain FM controllers utilization the following sequence
78172 + should be used:
78173 + -# FM_CtrlMonStart()
78174 + -# FM_CtrlMonStop()
78175 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78176 +
78177 + @Param[in] h_Fm A handle to an FM Module.
78178 +
78179 + @Return E_OK on success; Error code otherwise.
78180 +
78181 + @Cautions Allowed only following FM_Init().
78182 + This routine should NOT be called from guest-partition
78183 + (i.e. guestId != NCSW_MASTER_ID).
78184 +*//***************************************************************************/
78185 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
78186 +
78187 +/**************************************************************************//**
78188 + @Function FM_CtrlMonStop
78189 +
78190 + @Description Stop monitoring utilization of all available FM controllers.
78191 +
78192 + In order to obtain FM controllers utilization the following sequence
78193 + should be used:
78194 + -# FM_CtrlMonStart()
78195 + -# FM_CtrlMonStop()
78196 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78197 +
78198 + @Param[in] h_Fm A handle to an FM Module.
78199 +
78200 + @Return E_OK on success; Error code otherwise.
78201 +
78202 + @Cautions Allowed only following FM_Init().
78203 + This routine should NOT be called from guest-partition
78204 + (i.e. guestId != NCSW_MASTER_ID).
78205 +*//***************************************************************************/
78206 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
78207 +
78208 +/**************************************************************************//**
78209 + @Function FM_CtrlMonGetCounters
78210 +
78211 + @Description Obtain FM controller utilization parameters.
78212 +
78213 + In order to obtain FM controllers utilization the following sequence
78214 + should be used:
78215 + -# FM_CtrlMonStart()
78216 + -# FM_CtrlMonStop()
78217 + -# FM_CtrlMonGetCounters() - issued for each FM controller
78218 +
78219 + @Param[in] h_Fm A handle to an FM Module.
78220 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
78221 + are requested.
78222 + @Param[in] p_Mon Pointer to utilization results structure.
78223 +
78224 + @Return E_OK on success; Error code otherwise.
78225 +
78226 + @Cautions Allowed only following FM_Init().
78227 + This routine should NOT be called from guest-partition
78228 + (i.e. guestId != NCSW_MASTER_ID).
78229 +*//***************************************************************************/
78230 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
78231 +
78232 +
78233 +/**************************************************************************//*
78234 + @Function FM_ForceIntr
78235 +
78236 + @Description Causes an interrupt event on the requested source.
78237 +
78238 + @Param[in] h_Fm A handle to an FM Module.
78239 + @Param[in] exception An exception to be forced.
78240 +
78241 + @Return E_OK on success; Error code if the exception is not enabled,
78242 + or is not able to create interrupt.
78243 +
78244 + @Cautions Allowed only following FM_Init().
78245 + This routine should NOT be called from guest-partition
78246 + (i.e. guestId != NCSW_MASTER_ID)
78247 +*//***************************************************************************/
78248 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
78249 +
78250 +/**************************************************************************//*
78251 + @Function FM_SetPortsBandwidth
78252 +
78253 + @Description Sets relative weights between ports when accessing common resources.
78254 +
78255 + @Param[in] h_Fm A handle to an FM Module.
78256 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
78257 + total must equal 100.
78258 +
78259 + @Return E_OK on success; Error code otherwise.
78260 +
78261 + @Cautions Allowed only following FM_Init().
78262 + This routine should NOT be called from guest-partition
78263 + (i.e. guestId != NCSW_MASTER_ID)
78264 +*//***************************************************************************/
78265 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
78266 +
78267 +/**************************************************************************//*
78268 + @Function FM_GetMuramHandle
78269 +
78270 + @Description Gets the corresponding MURAM handle
78271 +
78272 + @Param[in] h_Fm A handle to an FM Module.
78273 +
78274 + @Return MURAM handle; NULL otherwise.
78275 +
78276 + @Cautions Allowed only following FM_Init().
78277 + This routine should NOT be called from guest-partition
78278 + (i.e. guestId != NCSW_MASTER_ID)
78279 +*//***************************************************************************/
78280 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
78281 +
78282 +/** @} */ /* end of FM_runtime_control_grp group */
78283 +/** @} */ /* end of FM_lib_grp group */
78284 +/** @} */ /* end of FM_grp group */
78285 +
78286 +
78287 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
78288 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
78289 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
78290 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
78291 +typedef t_FmExtPools t_FmPortExtPools;
78292 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
78293 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
78294 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
78295 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
78296 +
78297 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
78298 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
78299 +
78300 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
78301 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
78302 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
78303 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
78304 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
78305 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
78306 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
78307 +
78308 +
78309 +#endif /* __FM_EXT */
78310 --- /dev/null
78311 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
78312 @@ -0,0 +1,887 @@
78313 +/*
78314 + * Copyright 2008-2012 Freescale Semiconductor Inc.
78315 + *
78316 + * Redistribution and use in source and binary forms, with or without
78317 + * modification, are permitted provided that the following conditions are met:
78318 + * * Redistributions of source code must retain the above copyright
78319 + * notice, this list of conditions and the following disclaimer.
78320 + * * Redistributions in binary form must reproduce the above copyright
78321 + * notice, this list of conditions and the following disclaimer in the
78322 + * documentation and/or other materials provided with the distribution.
78323 + * * Neither the name of Freescale Semiconductor nor the
78324 + * names of its contributors may be used to endorse or promote products
78325 + * derived from this software without specific prior written permission.
78326 + *
78327 + *
78328 + * ALTERNATIVELY, this software may be distributed under the terms of the
78329 + * GNU General Public License ("GPL") as published by the Free Software
78330 + * Foundation, either version 2 of that License or (at your option) any
78331 + * later version.
78332 + *
78333 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78334 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78335 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78336 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78337 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78338 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78339 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78340 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78341 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78342 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78343 + */
78344 +
78345 +
78346 +/**************************************************************************//**
78347 + @File fm_mac_ext.h
78348 +
78349 + @Description FM MAC ...
78350 +*//***************************************************************************/
78351 +#ifndef __FM_MAC_EXT_H
78352 +#define __FM_MAC_EXT_H
78353 +
78354 +#include "std_ext.h"
78355 +#include "enet_ext.h"
78356 +
78357 +
78358 +/**************************************************************************//**
78359 +
78360 + @Group FM_grp Frame Manager API
78361 +
78362 + @Description FM API functions, definitions and enums
78363 +
78364 + @{
78365 +*//***************************************************************************/
78366 +
78367 +/**************************************************************************//**
78368 + @Group FM_mac_grp FM MAC
78369 +
78370 + @Description FM MAC API functions, definitions and enums
78371 +
78372 + @{
78373 +*//***************************************************************************/
78374 +
78375 +#define FM_MAC_NO_PFC 0xff
78376 +
78377 +
78378 +/**************************************************************************//**
78379 + @Description FM MAC Exceptions
78380 +*//***************************************************************************/
78381 +typedef enum e_FmMacExceptions {
78382 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
78383 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
78384 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
78385 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
78386 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
78387 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
78388 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
78389 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
78390 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
78391 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
78392 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
78393 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
78394 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
78395 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
78396 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
78397 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
78398 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
78399 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
78400 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
78401 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
78402 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
78403 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
78404 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
78405 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
78406 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
78407 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
78408 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
78409 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
78410 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
78411 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
78412 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
78413 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
78414 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
78415 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
78416 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
78417 + not supported on T4240/B4860 rev1 chips */
78418 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
78419 + /**< mEMAC Magic Packet Indication Interrupt */
78420 +} e_FmMacExceptions;
78421 +
78422 +/**************************************************************************//**
78423 + @Description TM MAC statistics level
78424 +*//***************************************************************************/
78425 +typedef enum e_FmMacStatisticsLevel {
78426 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
78427 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
78428 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
78429 +} e_FmMacStatisticsLevel;
78430 +
78431 +
78432 +#if (DPAA_VERSION >= 11)
78433 +/**************************************************************************//**
78434 + @Description Priority Flow Control Parameters
78435 +*//***************************************************************************/
78436 +typedef struct t_FmMacPfcParams {
78437 + bool pfcEnable; /**< Enable/Disable PFC */
78438 +
78439 + uint16_t pauseQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES]; /**< Pause Quanta per priority to be sent in a pause frame. Each quanta represents a 512 bit-times*/
78440 +
78441 + uint16_t pauseThresholdQuanta[FM_MAX_NUM_OF_PFC_PRIORITIES];/**< Pause threshold per priority, when timer passes this threshold time a PFC frames is sent again if the port is still congested or BM pool in depletion*/
78442 +
78443 +
78444 +} t_FmMacPfcParams;
78445 +#endif /* (DPAA_VERSION >= 11) */
78446 +
78447 +/**************************************************************************//**
78448 + @Function t_FmMacExceptionCallback
78449 +
78450 + @Description Fm Mac Exception Callback from FM MAC to the user
78451 +
78452 + @Param[in] h_App - Handle to the upper layer handler
78453 +
78454 + @Param[in] exceptions - The exception that occurred
78455 +
78456 + @Return void.
78457 +*//***************************************************************************/
78458 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
78459 +
78460 +
78461 +/**************************************************************************//**
78462 + @Description TM MAC statistics rfc3635
78463 +*//***************************************************************************/
78464 +typedef struct t_FmMacStatistics {
78465 +/* RMON */
78466 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
78467 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
78468 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
78469 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
78470 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
78471 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
78472 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
78473 +/* */
78474 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
78475 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
78476 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
78477 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
78478 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
78479 + This count does not include range length errors */
78480 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
78481 + a valid FCS and otherwise well formed */
78482 +/* Pause */
78483 + uint64_t teStatPause; /**< Pause MAC Control received */
78484 + uint64_t reStatPause; /**< Pause MAC Control sent */
78485 +/* MIB II */
78486 + uint64_t ifInOctets; /**< Total number of byte received. */
78487 + uint64_t ifInPkts; /**< Total number of packets received.*/
78488 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
78489 + NOTE: this counter is not supported on dTSEC MAC */
78490 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
78491 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
78492 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
78493 + uint64_t ifInErrors; /**< Number of frames received with error:
78494 + - FIFO Overflow Error
78495 + - CRC Error
78496 + - Frame Too Long Error
78497 + - Alignment Error
78498 + - The dedicated Error Code (0xfe, not a code error) was received */
78499 + uint64_t ifOutOctets; /**< Total number of byte sent. */
78500 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
78501 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
78502 + NOTE: this counter is not supported on dTSEC MAC */
78503 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
78504 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
78505 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
78506 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
78507 + - FIFO Overflow Error
78508 + - FIFO Underflow Error
78509 + - Other */
78510 +} t_FmMacStatistics;
78511 +
78512 +/**************************************************************************//**
78513 + @Description FM MAC Frame Size Counters
78514 +*//***************************************************************************/
78515 +typedef struct t_FmMacFrameSizeCounters {
78516 +
78517 + uint64_t count_pkts_64; /**< 64 byte frame counter */
78518 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
78519 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
78520 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
78521 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
78522 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
78523 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
78524 +} t_FmMacFrameSizeCounters;
78525 +
78526 +/**************************************************************************//**
78527 + @Group FM_mac_init_grp FM MAC Initialization Unit
78528 +
78529 + @Description FM MAC Initialization Unit
78530 +
78531 + @{
78532 +*//***************************************************************************/
78533 +
78534 +/**************************************************************************//**
78535 + @Description FM MAC config input
78536 +*//***************************************************************************/
78537 +typedef struct t_FmMacParams {
78538 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
78539 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
78540 + uint8_t macId; /**< MAC ID;
78541 + numbering of dTSEC and 1G-mEMAC:
78542 + 0 - FM_MAX_NUM_OF_1G_MACS;
78543 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
78544 + 0 - FM_MAX_NUM_OF_10G_MACS */
78545 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
78546 + Note that the speed should indicate the maximum rate that
78547 + this MAC should support rather than the actual speed;
78548 + i.e. user should use the FM_MAC_AdjustLink() routine to
78549 + provide accurate speed;
78550 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
78551 + automatic mode, where actual speed/duplex mode information
78552 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
78553 + function should be used to switch to manual RGMII speed/duplex mode
78554 + configuration if RGMII PHY doesn't support in-band status signaling;
78555 + In addition, in mEMAC, in case where user is using the higher MACs
78556 + (i.e. the MACs that should support 10G), user should pass here
78557 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
78558 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
78559 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
78560 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
78561 + mdio-irq, or for polling */
78562 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
78563 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
78564 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78565 + be passed by the driver upon calling the above callbacks */
78566 +} t_FmMacParams;
78567 +
78568 +
78569 +/**************************************************************************//**
78570 + @Function FM_MAC_Config
78571 +
78572 + @Description Creates descriptor for the FM MAC module.
78573 +
78574 + The routine returns a handle (descriptor) to the FM MAC object.
78575 + This descriptor must be passed as first parameter to all other
78576 + FM MAC function calls.
78577 +
78578 + No actual initialization or configuration of FM MAC hardware is
78579 + done by this routine.
78580 +
78581 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
78582 +
78583 + @Retval Handle to FM MAC object, or NULL for Failure.
78584 +*//***************************************************************************/
78585 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
78586 +
78587 +/**************************************************************************//**
78588 + @Function FM_MAC_Init
78589 +
78590 + @Description Initializes the FM MAC module
78591 +
78592 + @Param[in] h_FmMac - FM module descriptor
78593 +
78594 + @Return E_OK on success; Error code otherwise.
78595 +*//***************************************************************************/
78596 +t_Error FM_MAC_Init(t_Handle h_FmMac);
78597 +
78598 +/**************************************************************************//**
78599 + @Function FM_Free
78600 +
78601 + @Description Frees all resources that were assigned to FM MAC module.
78602 +
78603 + Calling this routine invalidates the descriptor.
78604 +
78605 + @Param[in] h_FmMac - FM module descriptor
78606 +
78607 + @Return E_OK on success; Error code otherwise.
78608 +*//***************************************************************************/
78609 +t_Error FM_MAC_Free(t_Handle h_FmMac);
78610 +
78611 +
78612 +/**************************************************************************//**
78613 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
78614 +
78615 + @Description Configuration functions used to change default values.
78616 +
78617 + @{
78618 +*//***************************************************************************/
78619 +
78620 +/**************************************************************************//**
78621 + @Function FM_MAC_ConfigResetOnInit
78622 +
78623 + @Description Tell the driver whether to reset the FM MAC before initialization or
78624 + not. It changes the default configuration [DEFAULT_resetOnInit].
78625 +
78626 + @Param[in] h_FmMac A handle to a FM MAC Module.
78627 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78628 +
78629 + @Return E_OK on success; Error code otherwise.
78630 +
78631 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78632 +*//***************************************************************************/
78633 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
78634 +
78635 +/**************************************************************************//**
78636 + @Function FM_MAC_ConfigLoopback
78637 +
78638 + @Description Enable/Disable internal loopback mode
78639 +
78640 + @Param[in] h_FmMac A handle to a FM MAC Module.
78641 + @Param[in] enable TRUE to enable or FALSE to disable.
78642 +
78643 + @Return E_OK on success; Error code otherwise.
78644 +
78645 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78646 +*//***************************************************************************/
78647 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
78648 +
78649 +/**************************************************************************//**
78650 + @Function FM_MAC_ConfigMaxFrameLength
78651 +
78652 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
78653 +
78654 + @Param[in] h_FmMac A handle to a FM MAC Module.
78655 + @Param[in] newVal MAX Frame length
78656 +
78657 + @Return E_OK on success; Error code otherwise.
78658 +
78659 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78660 +*//***************************************************************************/
78661 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
78662 +
78663 +/**************************************************************************//**
78664 + @Function FM_MAC_ConfigWan
78665 +
78666 + @Description ENABLE WAN mode in 10G-MAC
78667 +
78668 + @Param[in] h_FmMac A handle to a FM MAC Module.
78669 + @Param[in] enable TRUE to enable or FALSE to disable.
78670 +
78671 + @Return E_OK on success; Error code otherwise.
78672 +
78673 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78674 +*//***************************************************************************/
78675 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
78676 +
78677 +/**************************************************************************//**
78678 + @Function FM_MAC_ConfigPadAndCrc
78679 +
78680 + @Description Config PAD and CRC mode
78681 +
78682 + @Param[in] h_FmMac A handle to a FM MAC Module.
78683 + @Param[in] enable TRUE to enable or FALSE to disable.
78684 +
78685 + @Return E_OK on success; Error code otherwise.
78686 +
78687 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78688 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
78689 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
78690 + added automatically by HW).
78691 +*//***************************************************************************/
78692 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
78693 +
78694 +/**************************************************************************//**
78695 + @Function FM_MAC_ConfigHalfDuplex
78696 +
78697 + @Description Config Half Duplex Mode
78698 +
78699 + @Param[in] h_FmMac A handle to a FM MAC Module.
78700 + @Param[in] enable TRUE to enable or FALSE to disable.
78701 +
78702 + @Return E_OK on success; Error code otherwise.
78703 +
78704 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78705 +*//***************************************************************************/
78706 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
78707 +
78708 +/**************************************************************************//**
78709 + @Function FM_MAC_ConfigTbiPhyAddr
78710 +
78711 + @Description Configures the address of internal TBI PHY.
78712 +
78713 + @Param[in] h_FmMac A handle to a FM MAC Module.
78714 + @Param[in] newVal TBI PHY address (1-31).
78715 +
78716 + @Return E_OK on success; Error code otherwise.
78717 +
78718 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78719 +*//***************************************************************************/
78720 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
78721 +
78722 +/**************************************************************************//**
78723 + @Function FM_MAC_ConfigLengthCheck
78724 +
78725 + @Description Configure the frame length checking.
78726 +
78727 + @Param[in] h_FmMac A handle to a FM MAC Module.
78728 + @Param[in] enable TRUE to enable or FALSE to disable.
78729 +
78730 + @Return E_OK on success; Error code otherwise.
78731 +
78732 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78733 +*//***************************************************************************/
78734 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
78735 +
78736 +/**************************************************************************//**
78737 + @Function FM_MAC_ConfigException
78738 +
78739 + @Description Change Exception selection from default
78740 +
78741 + @Param[in] h_FmMac A handle to a FM MAC Module.
78742 + @Param[in] ex Type of the desired exceptions
78743 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
78744 +
78745 + @Return E_OK on success; Error code otherwise.
78746 +
78747 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
78748 +*//***************************************************************************/
78749 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78750 +
78751 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
78752 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
78753 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
78754 +/** @} */ /* end of FM_mac_advanced_init_grp group */
78755 +/** @} */ /* end of FM_mac_init_grp group */
78756 +
78757 +
78758 +/**************************************************************************//**
78759 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
78760 +
78761 + @Description FM MAC Runtime control unit API functions, definitions and enums.
78762 +
78763 + @{
78764 +*//***************************************************************************/
78765 +
78766 +/**************************************************************************//**
78767 + @Function FM_MAC_Enable
78768 +
78769 + @Description Enable the MAC
78770 +
78771 + @Param[in] h_FmMac A handle to a FM MAC Module.
78772 + @Param[in] mode Mode of operation (RX, TX, Both)
78773 +
78774 + @Return E_OK on success; Error code otherwise.
78775 +
78776 + @Cautions Allowed only following FM_MAC_Init().
78777 +*//***************************************************************************/
78778 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
78779 +
78780 +/**************************************************************************//**
78781 + @Function FM_MAC_Disable
78782 +
78783 + @Description DISABLE the MAC
78784 +
78785 + @Param[in] h_FmMac A handle to a FM MAC Module.
78786 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
78787 +
78788 + @Return E_OK on success; Error code otherwise.
78789 +
78790 + @Cautions Allowed only following FM_MAC_Init().
78791 +*//***************************************************************************/
78792 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
78793 +
78794 +/**************************************************************************//**
78795 + @Function FM_MAC_Resume
78796 +
78797 + @Description Re-init the MAC after suspend
78798 +
78799 + @Param[in] h_FmMac A handle to a FM MAC Module.
78800 +
78801 + @Return E_OK on success; Error code otherwise.
78802 +
78803 + @Cautions Allowed only following FM_MAC_Init().
78804 +*//***************************************************************************/
78805 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
78806 +
78807 +/**************************************************************************//**
78808 + @Function FM_MAC_Enable1588TimeStamp
78809 +
78810 + @Description Enables the TSU operation.
78811 +
78812 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78813 +
78814 + @Return E_OK on success; Error code otherwise.
78815 +
78816 + @Cautions Allowed only following FM_MAC_Init().
78817 +*//***************************************************************************/
78818 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
78819 +
78820 +/**************************************************************************//**
78821 + @Function FM_MAC_Disable1588TimeStamp
78822 +
78823 + @Description Disables the TSU operation.
78824 +
78825 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
78826 +
78827 + @Return E_OK on success; Error code otherwise.
78828 +
78829 + @Cautions Allowed only following FM_MAC_Init().
78830 +*//***************************************************************************/
78831 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
78832 +
78833 +/**************************************************************************//**
78834 + @Function FM_MAC_SetTxAutoPauseFrames
78835 +
78836 + @Description Enable/Disable transmission of Pause-Frames.
78837 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
78838 +
78839 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78840 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78841 + Each quanta represents a 512 bit-times; Note that '0'
78842 + as an input here will be used as disabling the
78843 + transmission of the pause-frames.
78844 +
78845 + @Return E_OK on success; Error code otherwise.
78846 +
78847 + @Cautions Allowed only following FM_MAC_Init().
78848 +*//***************************************************************************/
78849 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
78850 + uint16_t pauseTime);
78851 +
78852 + /**************************************************************************//**
78853 + @Function FM_MAC_SetTxPauseFrames
78854 +
78855 + @Description Enable/Disable transmission of Pause-Frames.
78856 + The routine changes the default configuration:
78857 + pause-time - [DEFAULT_TX_PAUSE_TIME]
78858 + threshold-time - [0]
78859 +
78860 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78861 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
78862 + to indicate legacy pause support (i.e. no PFC).
78863 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
78864 + Each quanta represents a 512 bit-times;
78865 + Note that '0' as an input here will be used as disabling the
78866 + transmission of the pause-frames.
78867 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
78868 + if the situation causing a pause frame to be sent didn't finish when the timer
78869 + reached the threshold quanta, the MAC will retransmit the pause frame.
78870 + Each quanta represents a 512 bit-times.
78871 +
78872 + @Return E_OK on success; Error code otherwise.
78873 +
78874 + @Cautions Allowed only following FM_MAC_Init().
78875 + In order for PFC to work properly the user must configure
78876 + TNUM-aging in the tx-port it is recommended that pre-fetch and
78877 + rate limit in the tx port should be disabled;
78878 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
78879 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
78880 + in the 'priority' field.
78881 +*//***************************************************************************/
78882 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
78883 + uint8_t priority,
78884 + uint16_t pauseTime,
78885 + uint16_t threshTime);
78886 +
78887 +/**************************************************************************//**
78888 + @Function FM_MAC_SetRxIgnorePauseFrames
78889 +
78890 + @Description Enable/Disable ignoring of Pause-Frames.
78891 +
78892 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78893 + @Param[in] en - boolean indicates whether to ignore the incoming pause
78894 + frames or not.
78895 +
78896 + @Return E_OK on success; Error code otherwise.
78897 +
78898 + @Cautions Allowed only following FM_MAC_Init().
78899 +*//***************************************************************************/
78900 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
78901 +
78902 +/**************************************************************************//**
78903 + @Function FM_MAC_SetWakeOnLan
78904 +
78905 + @Description Enable/Disable Wake On Lan support
78906 +
78907 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78908 + @Param[in] en - boolean indicates whether to enable Wake On Lan
78909 + support or not.
78910 +
78911 + @Return E_OK on success; Error code otherwise.
78912 +
78913 + @Cautions Allowed only following FM_MAC_Init().
78914 +*//***************************************************************************/
78915 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
78916 +
78917 +/**************************************************************************//**
78918 + @Function FM_MAC_ResetCounters
78919 +
78920 + @Description reset all statistics counters
78921 +
78922 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78923 +
78924 + @Return E_OK on success; Error code otherwise.
78925 +
78926 + @Cautions Allowed only following FM_MAC_Init().
78927 +*//***************************************************************************/
78928 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
78929 +
78930 +/**************************************************************************//**
78931 + @Function FM_MAC_SetException
78932 +
78933 + @Description Enable/Disable a specific Exception
78934 +
78935 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78936 + @Param[in] ex - Type of the desired exceptions
78937 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
78938 +
78939 +
78940 + @Return E_OK on success; Error code otherwise.
78941 +
78942 + @Cautions Allowed only following FM_MAC_Init().
78943 +*//***************************************************************************/
78944 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
78945 +
78946 +/**************************************************************************//**
78947 + @Function FM_MAC_SetStatistics
78948 +
78949 + @Description Define Statistics level.
78950 + Where applicable, the routine also enables the MIB counters
78951 + overflow interrupt in order to keep counters accurate
78952 + and account for overflows.
78953 + This routine is relevant only for dTSEC.
78954 +
78955 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78956 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
78957 + reduce performance. Partial statistics provides only special
78958 + event counters (errors etc.). If selected, regular counters (such as
78959 + byte/packet) will be invalid and will return -1.
78960 +
78961 + @Return E_OK on success; Error code otherwise.
78962 +
78963 + @Cautions Allowed only following FM_MAC_Init().
78964 +*//***************************************************************************/
78965 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
78966 +
78967 +/**************************************************************************//**
78968 + @Function FM_MAC_GetStatistics
78969 +
78970 + @Description get all statistics counters
78971 +
78972 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78973 + @Param[in] p_Statistics - Structure with statistics
78974 +
78975 + @Return E_OK on success; Error code otherwise.
78976 +
78977 + @Cautions Allowed only following FM_Init().
78978 +*//***************************************************************************/
78979 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
78980 +
78981 +/**************************************************************************//**
78982 + @Function FM_MAC_GetFrameSizeCounters
78983 +
78984 + @Description get MAC statistics counters for different frame size
78985 +
78986 + @Param[in] h_FmMac - A handle to a FM MAC Module.
78987 + @Param[in] p_FrameSizeCounters - Structure with counters
78988 + @Param[in] type - Type of counters to be read
78989 +
78990 + @Return E_OK on success; Error code otherwise.
78991 +
78992 + @Cautions Allowed only following FM_Init().
78993 +*//***************************************************************************/
78994 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
78995 +
78996 +/**************************************************************************//**
78997 + @Function FM_MAC_ModifyMacAddr
78998 +
78999 + @Description Replace the main MAC Address
79000 +
79001 + @Param[in] h_FmMac - A handle to a FM Module.
79002 + @Param[in] p_EnetAddr - Ethernet Mac address
79003 +
79004 + @Return E_OK on success; Error code otherwise.
79005 +
79006 + @Cautions Allowed only after FM_MAC_Init().
79007 +*//***************************************************************************/
79008 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79009 +
79010 +/**************************************************************************//**
79011 + @Function FM_MAC_AddHashMacAddr
79012 +
79013 + @Description Add an Address to the hash table. This is for filter purpose only.
79014 +
79015 + @Param[in] h_FmMac - A handle to a FM Module.
79016 + @Param[in] p_EnetAddr - Ethernet Mac address
79017 +
79018 + @Return E_OK on success; Error code otherwise.
79019 +
79020 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
79021 + @Cautions Some address need to be filterd out in upper FM blocks.
79022 +*//***************************************************************************/
79023 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79024 +
79025 +/**************************************************************************//**
79026 + @Function FM_MAC_RemoveHashMacAddr
79027 +
79028 + @Description Delete an Address to the hash table. This is for filter purpose only.
79029 +
79030 + @Param[in] h_FmMac - A handle to a FM Module.
79031 + @Param[in] p_EnetAddr - Ethernet Mac address
79032 +
79033 + @Return E_OK on success; Error code otherwise.
79034 +
79035 + @Cautions Allowed only following FM_MAC_Init().
79036 +*//***************************************************************************/
79037 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79038 +
79039 +/**************************************************************************//**
79040 + @Function FM_MAC_AddExactMatchMacAddr
79041 +
79042 + @Description Add a unicast or multicast mac address for exact-match filtering
79043 + (8 on dTSEC, 2 for 10G-MAC)
79044 +
79045 + @Param[in] h_FmMac - A handle to a FM Module.
79046 + @Param[in] p_EnetAddr - MAC Address to ADD
79047 +
79048 + @Return E_OK on success; Error code otherwise.
79049 +
79050 + @Cautions Allowed only after FM_MAC_Init().
79051 +*//***************************************************************************/
79052 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79053 +
79054 +/**************************************************************************//**
79055 + @Function FM_MAC_RemovelExactMatchMacAddr
79056 +
79057 + @Description Remove a uni cast or multi cast mac address.
79058 +
79059 + @Param[in] h_FmMac - A handle to a FM Module.
79060 + @Param[in] p_EnetAddr - MAC Address to remove
79061 +
79062 + @Return E_OK on success; Error code otherwise..
79063 +
79064 + @Cautions Allowed only after FM_MAC_Init().
79065 +*//***************************************************************************/
79066 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
79067 +
79068 +/**************************************************************************//**
79069 + @Function FM_MAC_SetPromiscuous
79070 +
79071 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
79072 +
79073 + @Param[in] h_FmMac - A handle to a FM MAC Module.
79074 + @Param[in] enable - TRUE to enable or FALSE to disable.
79075 +
79076 + @Return E_OK on success; Error code otherwise.
79077 +
79078 + @Cautions Allowed only after FM_MAC_Init().
79079 +*//***************************************************************************/
79080 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
79081 +
79082 +/**************************************************************************//**
79083 + @Function FM_MAC_AdjustLink
79084 +
79085 + @Description Adjusts the Ethernet link with new speed/duplex setup.
79086 + This routine is relevant for dTSEC and mEMAC.
79087 + In case of mEMAC, this routine is also used for manual
79088 + re-configuration of RGMII speed and duplex mode for
79089 + RGMII PHYs not supporting in-band status information
79090 + to MAC.
79091 +
79092 + @Param[in] h_FmMac - A handle to a FM Module.
79093 + @Param[in] speed - Ethernet speed.
79094 + @Param[in] fullDuplex - TRUE for full-duplex mode;
79095 + FALSE for half-duplex mode.
79096 +
79097 + @Return E_OK on success; Error code otherwise.
79098 +*//***************************************************************************/
79099 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
79100 +
79101 +/**************************************************************************//**
79102 + @Function FM_MAC_RestartAutoneg
79103 +
79104 + @Description Restarts the auto-negotiation process.
79105 + When auto-negotiation process is invoked under traffic the
79106 + auto-negotiation process between the internal SGMII PHY and the
79107 + external PHY does not always complete successfully. Calling this
79108 + function will restart the auto-negotiation process that will end
79109 + successfully. It is recommended to call this function after issuing
79110 + auto-negotiation restart command to the Eth Phy.
79111 + This routine is relevant only for dTSEC.
79112 +
79113 + @Param[in] h_FmMac - A handle to a FM Module.
79114 +
79115 + @Return E_OK on success; Error code otherwise.
79116 +*//***************************************************************************/
79117 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
79118 +
79119 +/**************************************************************************//**
79120 + @Function FM_MAC_GetId
79121 +
79122 + @Description Return the MAC ID
79123 +
79124 + @Param[in] h_FmMac - A handle to a FM Module.
79125 + @Param[out] p_MacId - MAC ID of device
79126 +
79127 + @Return E_OK on success; Error code otherwise.
79128 +
79129 + @Cautions Allowed only after FM_MAC_Init().
79130 +*//***************************************************************************/
79131 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
79132 +
79133 +/**************************************************************************//**
79134 + @Function FM_MAC_GetVesrion
79135 +
79136 + @Description Return Mac HW chip version
79137 +
79138 + @Param[in] h_FmMac - A handle to a FM Module.
79139 + @Param[out] p_MacVresion - Mac version as defined by the chip
79140 +
79141 + @Return E_OK on success; Error code otherwise.
79142 +
79143 + @Cautions Allowed only after FM_MAC_Init().
79144 +*//***************************************************************************/
79145 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
79146 +
79147 +/**************************************************************************//**
79148 + @Function FM_MAC_MII_WritePhyReg
79149 +
79150 + @Description Write data into Phy Register
79151 +
79152 + @Param[in] h_FmMac - A handle to a FM Module.
79153 + @Param[in] phyAddr - Phy Address on the MII bus
79154 + @Param[in] reg - Register Number.
79155 + @Param[in] data - Data to write.
79156 +
79157 + @Return E_OK on success; Error code otherwise.
79158 +
79159 + @Cautions Allowed only after FM_MAC_Init().
79160 +*//***************************************************************************/
79161 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
79162 +
79163 +/**************************************************************************//**
79164 + @Function FM_MAC_MII_ReadPhyReg
79165 +
79166 + @Description Read data from Phy Register
79167 +
79168 + @Param[in] h_FmMac - A handle to a FM Module.
79169 + @Param[in] phyAddr - Phy Address on the MII bus
79170 + @Param[in] reg - Register Number.
79171 + @Param[out] p_Data - Data from PHY.
79172 +
79173 + @Return E_OK on success; Error code otherwise.
79174 +
79175 + @Cautions Allowed only after FM_MAC_Init().
79176 +*//***************************************************************************/
79177 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
79178 +
79179 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79180 +/**************************************************************************//**
79181 + @Function FM_MAC_DumpRegs
79182 +
79183 + @Description Dump internal registers
79184 +
79185 + @Param[in] h_FmMac - A handle to a FM Module.
79186 +
79187 + @Return E_OK on success; Error code otherwise.
79188 +
79189 + @Cautions Allowed only after FM_MAC_Init().
79190 +*//***************************************************************************/
79191 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
79192 +#endif /* (defined(DEBUG_ERRORS) && ... */
79193 +
79194 +/** @} */ /* end of FM_mac_runtime_control_grp group */
79195 +/** @} */ /* end of FM_mac_grp group */
79196 +/** @} */ /* end of FM_grp group */
79197 +
79198 +
79199 +#endif /* __FM_MAC_EXT_H */
79200 --- /dev/null
79201 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
79202 @@ -0,0 +1,1271 @@
79203 +/*
79204 + * Copyright 2008-2015 Freescale Semiconductor Inc.
79205 + *
79206 + * Redistribution and use in source and binary forms, with or without
79207 + * modification, are permitted provided that the following conditions are met:
79208 + * * Redistributions of source code must retain the above copyright
79209 + * notice, this list of conditions and the following disclaimer.
79210 + * * Redistributions in binary form must reproduce the above copyright
79211 + * notice, this list of conditions and the following disclaimer in the
79212 + * documentation and/or other materials provided with the distribution.
79213 + * * Neither the name of Freescale Semiconductor nor the
79214 + * names of its contributors may be used to endorse or promote products
79215 + * derived from this software without specific prior written permission.
79216 + *
79217 + *
79218 + * ALTERNATIVELY, this software may be distributed under the terms of the
79219 + * GNU General Public License ("GPL") as published by the Free Software
79220 + * Foundation, either version 2 of that License or (at your option) any
79221 + * later version.
79222 + *
79223 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
79224 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
79225 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
79226 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
79227 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79228 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
79229 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
79230 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
79231 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
79232 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
79233 + */
79234 +
79235 +/**************************************************************************//**
79236 + @File fm_macsec_ext.h
79237 +
79238 + @Description FM MACSEC ...
79239 +*//***************************************************************************/
79240 +#ifndef __FM_MACSEC_EXT_H
79241 +#define __FM_MACSEC_EXT_H
79242 +
79243 +#include "std_ext.h"
79244 +
79245 +
79246 +/**************************************************************************//**
79247 + @Group FM_grp Frame Manager API
79248 +
79249 + @Description FM API functions, definitions and enums
79250 +
79251 + @{
79252 +*//***************************************************************************/
79253 +
79254 +/**************************************************************************//**
79255 + @Group FM_MACSEC_grp FM MACSEC
79256 +
79257 + @Description FM MACSEC API functions, definitions and enums
79258 +
79259 + @{
79260 +*//***************************************************************************/
79261 +
79262 +/**************************************************************************//**
79263 + @Description MACSEC Exceptions
79264 +*//***************************************************************************/
79265 +typedef enum e_FmMacsecExceptions {
79266 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
79267 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
79268 +} e_FmMacsecExceptions;
79269 +
79270 +
79271 +/**************************************************************************//**
79272 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
79273 +
79274 + @Description FM MACSEC Initialization Unit
79275 +
79276 + @{
79277 +*//***************************************************************************/
79278 +
79279 +/**************************************************************************//**
79280 + @Function t_FmMacsecExceptionsCallback
79281 +
79282 + @Description Exceptions user callback routine, will be called upon an
79283 + exception passing the exception identification.
79284 +
79285 + @Param[in] h_App A handle to an application layer object; This handle
79286 + will be passed by the driver upon calling this callback.
79287 + @Param[in] exception The exception.
79288 +*//***************************************************************************/
79289 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
79290 + e_FmMacsecExceptions exception);
79291 +
79292 +
79293 +/**************************************************************************//**
79294 + @Description FM MACSEC config input
79295 +*//***************************************************************************/
79296 +typedef struct t_FmMacsecParams {
79297 + t_Handle h_Fm; /**< A handle to the FM object related to */
79298 + bool guestMode; /**< Partition-id */
79299 + union {
79300 + struct {
79301 + uint8_t fmMacId; /**< FM MAC id */
79302 + } guestParams;
79303 +
79304 + struct {
79305 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
79306 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
79307 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
79308 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79309 + be passed by the driver upon calling the above callbacks */
79310 + } nonGuestParams;
79311 + };
79312 +} t_FmMacsecParams;
79313 +
79314 +/**************************************************************************//**
79315 + @Function FM_MACSEC_Config
79316 +
79317 + @Description Creates descriptor for the FM MACSEC module;
79318 +
79319 + The routine returns a handle (descriptor) to the FM MACSEC object;
79320 + This descriptor must be passed as first parameter to all other
79321 + FM MACSEC function calls;
79322 +
79323 + No actual initialization or configuration of FM MACSEC hardware is
79324 + done by this routine.
79325 +
79326 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
79327 +
79328 + @Retval Handle to FM MACSEC object, or NULL for Failure.
79329 +*//***************************************************************************/
79330 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
79331 +
79332 +/**************************************************************************//**
79333 + @Function FM_MACSEC_Init
79334 +
79335 + @Description Initializes the FM MACSEC module.
79336 +
79337 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79338 +
79339 + @Return E_OK on success; Error code otherwise.
79340 +*//***************************************************************************/
79341 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
79342 +
79343 +/**************************************************************************//**
79344 + @Function FM_MACSEC_Free
79345 +
79346 + @Description Frees all resources that were assigned to FM MACSEC module;
79347 +
79348 + Calling this routine invalidates the descriptor.
79349 +
79350 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79351 +
79352 + @Return E_OK on success; Error code otherwise.
79353 +*//***************************************************************************/
79354 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
79355 +
79356 +
79357 +/**************************************************************************//**
79358 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
79359 +
79360 + @Description Configuration functions used to change default values.
79361 +
79362 + @{
79363 +*//***************************************************************************/
79364 +
79365 +/**************************************************************************//**
79366 + @Description enum for unknown sci frame treatment
79367 +*//***************************************************************************/
79368 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
79369 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
79370 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
79371 + Controlled port - Check or Disable mode */
79372 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
79373 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED /**< If C bit set deliver on uncontrolled port and discard on controlled port,
79374 + else discard on uncontrolled port and deliver on controlled port
79375 + Controlled port - Check or Disable mode */
79376 +} e_FmMacsecUnknownSciFrameTreatment;
79377 +
79378 +/**************************************************************************//**
79379 + @Description enum for untag frame treatment
79380 +*//***************************************************************************/
79381 +typedef enum e_FmMacsecUntagFrameTreatment {
79382 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
79383 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
79384 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
79385 +} e_FmMacsecUntagFrameTreatment;
79386 +
79387 +/**************************************************************************//**
79388 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
79389 +
79390 + @Description Change the treatment for received frames with unknown sci from its default
79391 + configuration [DEFAULT_unknownSciFrameTreatment].
79392 +
79393 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79394 + @Param[in] treatMode The selected mode.
79395 +
79396 + @Return E_OK on success; Error code otherwise.
79397 +
79398 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79399 +*//***************************************************************************/
79400 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
79401 +
79402 +/**************************************************************************//**
79403 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
79404 +
79405 + @Description Change the treatment for received frames with invalid tags or
79406 + a zero value PN or an invalid ICV from its default configuration
79407 + [DEFAULT_invalidTagsFrameTreatment].
79408 +
79409 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79410 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79411 + In both cases discard on the controlled port;
79412 + this provide Strict, Check or Disable mode.
79413 +
79414 + @Return E_OK on success; Error code otherwise.
79415 +
79416 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79417 +*//***************************************************************************/
79418 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79419 +
79420 +/**************************************************************************//**
79421 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
79422 +
79423 + @Description Change the treatment for received frames with the Encryption bit
79424 + set and the Changed Text bit clear from its default configuration
79425 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
79426 +
79427 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79428 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
79429 + In both cases discard on the controlled port;
79430 + this provide Strict, Check or Disable mode.
79431 +
79432 + @Return E_OK on success; Error code otherwise.
79433 +
79434 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79435 +*//***************************************************************************/
79436 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
79437 +
79438 +/**************************************************************************//**
79439 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
79440 +
79441 + @Description Change the treatment for received frames with the Encryption bit
79442 + clear and the Changed Text bit set from its default configuration
79443 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
79444 +
79445 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79446 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79447 + In both cases discard on the controlled port;
79448 + this provide Strict, Check or Disable mode.
79449 +
79450 + @Return E_OK on success; Error code otherwise.
79451 +
79452 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79453 +*//***************************************************************************/
79454 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79455 +
79456 +/**************************************************************************//**
79457 + @Function FM_MACSEC_ConfigUntagFrameTreatment
79458 +
79459 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
79460 + from its default configuration [DEFAULT_untagFrameTreatment].
79461 +
79462 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79463 + @Param[in] treatMode The selected mode.
79464 +
79465 + @Return E_OK on success; Error code otherwise.
79466 +
79467 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79468 +*//***************************************************************************/
79469 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
79470 +
79471 +/**************************************************************************//**
79472 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
79473 +
79474 + @Description Change the treatment for received frames with only SCB bit set
79475 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
79476 +
79477 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79478 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
79479 + In both cases discard on the controlled port;
79480 + this provide Strict, Check or Disable mode.
79481 +
79482 + @Return E_OK on success; Error code otherwise.
79483 +
79484 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79485 +*//***************************************************************************/
79486 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
79487 +
79488 +/**************************************************************************//**
79489 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
79490 +
79491 + @Description It's provide the ability to configure a PN exhaustion threshold;
79492 + When the NextPn crosses this value an interrupt event
79493 + is asserted to warn that the active SA should re-key.
79494 +
79495 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79496 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
79497 + is asserted to re-key.
79498 +
79499 + @Return E_OK on success; Error code otherwise.
79500 +
79501 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79502 +*//***************************************************************************/
79503 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
79504 +
79505 +/**************************************************************************//**
79506 + @Function FM_MACSEC_ConfigKeysUnreadable
79507 +
79508 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
79509 + Can not be cleared unless hard reset.
79510 +
79511 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79512 +
79513 + @Return E_OK on success; Error code otherwise.
79514 +
79515 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79516 +*//***************************************************************************/
79517 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
79518 +
79519 +/**************************************************************************//**
79520 + @Function FM_MACSEC_ConfigSectagWithoutSCI
79521 +
79522 + @Description Promise that all generated Sectag will be without SCI included.
79523 +
79524 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79525 +
79526 + @Return E_OK on success; Error code otherwise.
79527 +
79528 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79529 +*//***************************************************************************/
79530 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
79531 +
79532 +/**************************************************************************//**
79533 + @Function FM_MACSEC_ConfigException
79534 +
79535 + @Description Calling this routine changes the internal driver data base
79536 + from its default selection of exceptions enablement;
79537 + By default all exceptions are enabled.
79538 +
79539 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79540 + @Param[in] exception The exception to be selected.
79541 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79542 +
79543 + @Return E_OK on success; Error code otherwise.
79544 +
79545 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
79546 +*//***************************************************************************/
79547 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79548 +
79549 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
79550 +/** @} */ /* end of FM_MACSEC_init_grp group */
79551 +
79552 +
79553 +/**************************************************************************//**
79554 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
79555 +
79556 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
79557 +
79558 + @{
79559 +*//***************************************************************************/
79560 +
79561 +/**************************************************************************//**
79562 + @Function FM_MACSEC_GetRevision
79563 +
79564 + @Description Return MACSEC HW chip revision
79565 +
79566 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79567 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
79568 +
79569 + @Return E_OK on success; Error code otherwise.
79570 +
79571 + @Cautions Allowed only after FM_MACSEC_Init().
79572 +*//***************************************************************************/
79573 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
79574 +
79575 +/**************************************************************************//**
79576 + @Function FM_MACSEC_Enable
79577 +
79578 + @Description This routine should be called after MACSEC is initialized for enabling all
79579 + MACSEC engines according to their existing configuration.
79580 +
79581 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79582 +
79583 + @Return E_OK on success; Error code otherwise.
79584 +
79585 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
79586 +*//***************************************************************************/
79587 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
79588 +
79589 +/**************************************************************************//**
79590 + @Function FM_MACSEC_Disable
79591 +
79592 + @Description This routine may be called when MACSEC is enabled in order to
79593 + disable all MACSEC engines; The MACSEC is working in bypass mode.
79594 +
79595 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79596 +
79597 + @Return E_OK on success; Error code otherwise.
79598 +
79599 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
79600 +*//***************************************************************************/
79601 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
79602 +
79603 +/**************************************************************************//**
79604 + @Function FM_MACSEC_SetException
79605 +
79606 + @Description Calling this routine enables/disables the specified exception.
79607 +
79608 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79609 + @Param[in] exception The exception to be selected.
79610 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79611 +
79612 + @Return E_OK on success; Error code otherwise.
79613 +
79614 + @Cautions Allowed only following FM_MACSEC_Init().
79615 +*//***************************************************************************/
79616 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
79617 +
79618 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79619 +/**************************************************************************//**
79620 + @Function FM_MACSEC_DumpRegs
79621 +
79622 + @Description Dump internal registers.
79623 +
79624 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
79625 +
79626 + @Return E_OK on success; Error code otherwise.
79627 +
79628 + @Cautions Allowed only after FM_MACSEC_Init().
79629 +*//***************************************************************************/
79630 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
79631 +#endif /* (defined(DEBUG_ERRORS) && ... */
79632 +
79633 +#ifdef VERIFICATION_SUPPORT
79634 +/********************* VERIFICATION ONLY ********************************/
79635 +/**************************************************************************//**
79636 + @Function FM_MACSEC_BackdoorSet
79637 +
79638 + @Description Set register of the MACSEC memory map
79639 +
79640 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79641 + @Param[out] offset Register offset.
79642 + @Param[out] value Value to write.
79643 +
79644 +
79645 + @Return None
79646 +
79647 + @Cautions Allowed only following FM_MACSEC_Init().
79648 +*//***************************************************************************/
79649 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
79650 +
79651 +/**************************************************************************//**
79652 + @Function FM_MACSEC_BackdoorGet
79653 +
79654 + @Description Read from register of the MACSEC memory map.
79655 +
79656 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
79657 + @Param[out] offset Register offset.
79658 +
79659 + @Return Value read
79660 +
79661 + @Cautions Allowed only following FM_MACSEC_Init().
79662 +*//***************************************************************************/
79663 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
79664 +#endif /* VERIFICATION_SUPPORT */
79665 +
79666 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
79667 +
79668 +
79669 +/**************************************************************************//**
79670 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
79671 +
79672 + @Description FM-MACSEC SecY API functions, definitions and enums
79673 +
79674 + @{
79675 +*//***************************************************************************/
79676 +
79677 +typedef uint8_t macsecSAKey_t[32];
79678 +typedef uint64_t macsecSCI_t;
79679 +typedef uint8_t macsecAN_t;
79680 +
79681 +/**************************************************************************//**
79682 +@Description MACSEC SECY Cipher Suite
79683 +*//***************************************************************************/
79684 +typedef enum e_FmMacsecSecYCipherSuite {
79685 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
79686 +#if (DPAA_VERSION >= 11)
79687 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
79688 +#endif /* (DPAA_VERSION >= 11) */
79689 +} e_FmMacsecSecYCipherSuite;
79690 +
79691 +/**************************************************************************//**
79692 + @Description MACSEC SECY Exceptions
79693 +*//***************************************************************************/
79694 +typedef enum e_FmMacsecSecYExceptions {
79695 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
79696 +} e_FmMacsecSecYExceptions;
79697 +
79698 +/**************************************************************************//**
79699 + @Description MACSEC SECY Events
79700 +*//***************************************************************************/
79701 +typedef enum e_FmMacsecSecYEvents {
79702 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
79703 +} e_FmMacsecSecYEvents;
79704 +
79705 +/**************************************************************************//**
79706 + @Collection MACSEC SECY Frame Discarded Descriptor error
79707 +*//***************************************************************************/
79708 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
79709 +
79710 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
79711 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
79712 +/* @} */
79713 +
79714 +/**************************************************************************//**
79715 + @Function t_FmMacsecSecYExceptionsCallback
79716 +
79717 + @Description Exceptions user callback routine, will be called upon an
79718 + exception passing the exception identification.
79719 +
79720 + @Param[in] h_App A handle to an application layer object; This handle
79721 + will be passed by the driver upon calling this callback.
79722 + @Param[in] exception The exception.
79723 +*//***************************************************************************/
79724 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
79725 + e_FmMacsecSecYExceptions exception);
79726 +
79727 +/**************************************************************************//**
79728 + @Function t_FmMacsecSecYEventsCallback
79729 +
79730 + @Description Events user callback routine, will be called upon an
79731 + event passing the event identification.
79732 +
79733 + @Param[in] h_App A handle to an application layer object; This handle
79734 + will be passed by the driver upon calling this callback.
79735 + @Param[in] event The event.
79736 +*//***************************************************************************/
79737 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
79738 + e_FmMacsecSecYEvents event);
79739 +
79740 +/**************************************************************************//**
79741 + @Description RFC2863 MIB
79742 +*//***************************************************************************/
79743 +typedef struct t_MIBStatistics {
79744 + uint64_t ifInOctets; /**< Total number of byte received */
79745 + uint64_t ifInPkts; /**< Total number of packets received */
79746 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
79747 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
79748 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
79749 + - InPktsNoTag,
79750 + - InPktsLate,
79751 + - InPktsOverrun */
79752 + uint64_t ifInErrors; /**< Number of frames received with error:
79753 + - InPktsBadTag,
79754 + - InPktsNoSCI,
79755 + - InPktsNotUsingSA
79756 + - InPktsNotValid */
79757 + uint64_t ifOutOctets; /**< Total number of byte sent */
79758 + uint64_t ifOutPkts; /**< Total number of packets sent */
79759 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
79760 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
79761 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
79762 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
79763 + - FIFO Overflow Error
79764 + - FIFO Underflow Error
79765 + - Other */
79766 +} t_MIBStatistics;
79767 +
79768 +/**************************************************************************//**
79769 + @Description MACSEC SecY Rx SA Statistics
79770 +*//***************************************************************************/
79771 +typedef struct t_FmMacsecSecYRxSaStatistics {
79772 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79773 + frame validation frame validation with the validateFrame not set to disable */
79774 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79775 + validation with the validateFrame set to check */
79776 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79777 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79778 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79779 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79780 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79781 + with validateFrame not in the strict mode and the C bit is cleared */
79782 +} t_FmMacsecSecYRxSaStatistics;
79783 +
79784 +/**************************************************************************//**
79785 + @Description MACSEC SecY Tx SA Statistics
79786 +*//***************************************************************************/
79787 +typedef struct t_FmMacsecSecYTxSaStatistics {
79788 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79789 + be transmitted, which were integrity protected */
79790 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79791 + be transmitted, which were confidentiality protected */
79792 +} t_FmMacsecSecYTxSaStatistics;
79793 +
79794 +/**************************************************************************//**
79795 + @Description MACSEC SecY Rx SC Statistics
79796 +*//***************************************************************************/
79797 +typedef struct t_FmMacsecSecYRxScStatistics {
79798 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79799 + that are not validated with the validateFrame set to disable */
79800 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
79801 + that have their PN smaller than the lowest_PN with the validateFrame set to
79802 + disable or replayProtect disabled */
79803 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
79804 + that have their PN smaller than the lowest_PN with the validateFrame set to
79805 + Check or Strict and replayProtect enabled */
79806 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
79807 + frame validation frame validation with the validateFrame not set to disable */
79808 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
79809 + validation with the validateFrame set to check */
79810 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
79811 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
79812 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
79813 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
79814 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
79815 + with validateFrame not in the strict mode and the C bit is cleared */
79816 +} t_FmMacsecSecYRxScStatistics;
79817 +
79818 +/**************************************************************************//**
79819 + @Description MACSEC SecY Tx SC Statistics
79820 +*//***************************************************************************/
79821 +typedef struct t_FmMacsecSecYTxScStatistics {
79822 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
79823 + be transmitted, which were integrity protected */
79824 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
79825 + be transmitted, which were confidentiality protected */
79826 +} t_FmMacsecSecYTxScStatistics;
79827 +
79828 +/**************************************************************************//**
79829 + @Description MACSEC SecY Statistics
79830 +*//***************************************************************************/
79831 +typedef struct t_FmMacsecSecYStatistics {
79832 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
79833 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
79834 +/* Frame verification statistics */
79835 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
79836 + (SecTAG) with validateFrames which is not in the strict mode */
79837 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
79838 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
79839 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
79840 + SecTAG or a zero value PN or an invalid ICV */
79841 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
79842 + condition : validateFrames is not in the strict mode and the
79843 + C bit in the SecTAG is not set */
79844 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
79845 + information with the condition : validateFrames is in the strict mode
79846 + or the C bit in the SecTAG is set */
79847 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
79848 + received packets exceeded the cryptographic performance capabilities */
79849 +/* Frame validation statistics */
79850 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
79851 + resolved SCI that were integrity protected but not encrypted */
79852 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
79853 + resolved SCI that were integrity protected and encrypted */
79854 +/* Frame generation statistics */
79855 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
79856 + be transmitted, with protectFrame false */
79857 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
79858 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
79859 +/* Frame protection statistics */
79860 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
79861 + integrity protected but not encrypted */
79862 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
79863 + both integrity protected and encrypted */
79864 +} t_FmMacsecSecYStatistics;
79865 +
79866 +
79867 +/**************************************************************************//**
79868 + @Description MACSEC SecY SC Params
79869 +*//***************************************************************************/
79870 +typedef struct t_FmMacsecSecYSCParams {
79871 + macsecSCI_t sci; /**< The secure channel identification of the SC */
79872 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
79873 +} t_FmMacsecSecYSCParams;
79874 +
79875 +/**************************************************************************//**
79876 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
79877 +
79878 + @Description FM-MACSEC SecY Initialization Unit
79879 +
79880 + @{
79881 +*//***************************************************************************/
79882 +
79883 +/**************************************************************************//**
79884 + @Description enum for validate frames
79885 +*//***************************************************************************/
79886 +typedef enum e_FmMacsecValidFrameBehavior {
79887 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
79888 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
79889 + without filtering out invalid frames */
79890 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
79891 + out those invalid frames */
79892 +} e_FmMacsecValidFrameBehavior;
79893 +
79894 +/**************************************************************************//**
79895 + @Description enum for sci insertion
79896 +*//***************************************************************************/
79897 +typedef enum e_FmMacsecSciInsertionMode {
79898 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
79899 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
79900 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
79901 +} e_FmMacsecSciInsertionMode;
79902 +
79903 +/**************************************************************************//**
79904 + @Description FM MACSEC SecY config input
79905 +*//***************************************************************************/
79906 +typedef struct t_FmMacsecSecYParams {
79907 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
79908 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
79909 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
79910 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
79911 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
79912 + t_Handle h_App; /**< A handle to an application layer object; This handle will
79913 + be passed by the driver upon calling the above callbacks */
79914 +} t_FmMacsecSecYParams;
79915 +
79916 +/**************************************************************************//**
79917 + @Function FM_MACSEC_SECY_Config
79918 +
79919 + @Description Creates descriptor for the FM MACSEC SECY module;
79920 +
79921 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
79922 + This descriptor must be passed as first parameter to all other
79923 + FM MACSEC SECY function calls;
79924 + No actual initialization or configuration of FM MACSEC SecY hardware is
79925 + done by this routine.
79926 +
79927 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
79928 +
79929 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
79930 +*//***************************************************************************/
79931 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
79932 +
79933 +/**************************************************************************//**
79934 + @Function FM_MACSEC_SECY_Init
79935 +
79936 + @Description Initializes the FM MACSEC SECY module.
79937 +
79938 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79939 +
79940 + @Return E_OK on success; Error code otherwise.
79941 +*//***************************************************************************/
79942 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
79943 +
79944 +/**************************************************************************//**
79945 + @Function FM_MACSEC_SECY_Free
79946 +
79947 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
79948 +
79949 + Calling this routine invalidates the descriptor.
79950 +
79951 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79952 +
79953 + @Return E_OK on success; Error code otherwise.
79954 +*//***************************************************************************/
79955 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
79956 +
79957 +/**************************************************************************//**
79958 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
79959 +
79960 + @Description Configuration functions used to change default values.
79961 +
79962 + @{
79963 +*//***************************************************************************/
79964 +
79965 +/**************************************************************************//**
79966 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
79967 +
79968 + @Description Calling this routine changes the SCI-insertion-mode in the
79969 + internal driver data base from its default configuration
79970 + [DEFAULT_sciInsertionMode]
79971 +
79972 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79973 + @Param[in] sciInsertionMode Sci insertion mode
79974 +
79975 + @Return E_OK on success; Error code otherwise.
79976 +
79977 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79978 +
79979 +*//***************************************************************************/
79980 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
79981 +
79982 +/**************************************************************************//**
79983 + @Function FM_MACSEC_SECY_ConfigProtectFrames
79984 +
79985 + @Description Calling this routine changes the protect-frame mode in the
79986 + internal driver data base from its default configuration
79987 + [DEFAULT_protectFrames]
79988 +
79989 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
79990 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
79991 +
79992 + @Return E_OK on success; Error code otherwise.
79993 +
79994 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
79995 +
79996 +*//***************************************************************************/
79997 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
79998 +
79999 +/**************************************************************************//**
80000 + @Function FM_MACSEC_SECY_ConfigReplayWindow
80001 +
80002 + @Description Calling this routine changes the replay-window settings in the
80003 + internal driver data base from its default configuration
80004 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
80005 +
80006 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80007 + @Param[in] replayProtect; Replay protection function mode
80008 + @Param[in] replayWindow; The size of the replay window
80009 +
80010 + @Return E_OK on success; Error code otherwise.
80011 +
80012 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80013 +
80014 +*//***************************************************************************/
80015 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
80016 +
80017 +/**************************************************************************//**
80018 + @Function FM_MACSEC_SECY_ConfigValidationMode
80019 +
80020 + @Description Calling this routine changes the frame-validation-behavior mode
80021 + in the internal driver data base from its default configuration
80022 + [DEFAULT_validateFrames]
80023 +
80024 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80025 + @Param[in] validateFrames Validation function mode
80026 +
80027 + @Return E_OK on success; Error code otherwise.
80028 +
80029 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80030 +
80031 +*//***************************************************************************/
80032 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
80033 +
80034 +/**************************************************************************//**
80035 + @Function FM_MACSEC_SECY_ConfigConfidentiality
80036 +
80037 + @Description Calling this routine changes the confidentiality settings in the
80038 + internal driver data base from its default configuration
80039 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
80040 +
80041 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80042 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
80043 + FALSE - no confidentiality protection, only integrity protection
80044 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
80045 + common values are 0, 30, and 50
80046 +
80047 + @Return E_OK on success; Error code otherwise.
80048 +
80049 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80050 +
80051 +*//***************************************************************************/
80052 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
80053 +
80054 +/**************************************************************************//**
80055 + @Function FM_MACSEC_SECY_ConfigPointToPoint
80056 +
80057 + @Description configure this SecY to work in point-to-point mode, means that
80058 + it will have only one rx sc;
80059 +
80060 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80061 +
80062 + @Return E_OK on success; Error code otherwise.
80063 +
80064 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
80065 + Can be called only once in a system; only the first secY that will call this
80066 + routine will be able to operate in Point-To-Point mode.
80067 +*//***************************************************************************/
80068 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
80069 +
80070 +/**************************************************************************//**
80071 + @Function FM_MACSEC_SECY_ConfigException
80072 +
80073 + @Description Calling this routine changes the internal driver data base
80074 + from its default selection of exceptions enablement;
80075 + By default all exceptions are enabled.
80076 +
80077 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80078 + @Param[in] exception The exception to be selected.
80079 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80080 +
80081 + @Return E_OK on success; Error code otherwise.
80082 +
80083 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80084 +*//***************************************************************************/
80085 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
80086 +
80087 +/**************************************************************************//**
80088 + @Function FM_MACSEC_SECY_ConfigEvent
80089 +
80090 + @Description Calling this routine changes the internal driver data base
80091 + from its default selection of events enablement;
80092 + By default all events are enabled.
80093 +
80094 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80095 + @Param[in] event The event to be selected.
80096 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80097 +
80098 + @Return E_OK on success; Error code otherwise.
80099 +
80100 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80101 +*//***************************************************************************/
80102 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80103 +
80104 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
80105 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
80106 +
80107 +
80108 +/**************************************************************************//**
80109 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
80110 +
80111 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
80112 +
80113 + @{
80114 +*//***************************************************************************/
80115 +
80116 +/**************************************************************************//**
80117 + @Function FM_MACSEC_SECY_CreateRxSc
80118 +
80119 + @Description Create a receive secure channel.
80120 +
80121 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80122 + @Param[in] scParams secure channel params.
80123 +
80124 + @Return E_OK on success; Error code otherwise.
80125 +
80126 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80127 +*//***************************************************************************/
80128 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
80129 +
80130 +/**************************************************************************//**
80131 + @Function FM_MACSEC_SECY_DeleteRxSc
80132 +
80133 + @Description Deleting an initialized secure channel.
80134 +
80135 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80136 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80137 +
80138 + @Return E_OK on success; Error code otherwise.
80139 +
80140 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80141 +*//***************************************************************************/
80142 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
80143 +
80144 +/**************************************************************************//**
80145 + @Function FM_MACSEC_SECY_CreateRxSa
80146 +
80147 + @Description Create a receive secure association for the secure channel;
80148 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
80149 +
80150 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80151 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80152 + @Param[in] an association number represent the SA.
80153 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
80154 + @Param[in] key the desired key for this SA.
80155 +
80156 + @Return E_OK on success; Error code otherwise.
80157 +
80158 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80159 +*//***************************************************************************/
80160 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
80161 +
80162 +/**************************************************************************//**
80163 + @Function FM_MACSEC_SECY_DeleteRxSa
80164 +
80165 + @Description Deleting an initialized secure association.
80166 +
80167 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80168 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80169 + @Param[in] an association number represent the SA.
80170 +
80171 + @Return E_OK on success; Error code otherwise.
80172 +
80173 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80174 +*//***************************************************************************/
80175 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80176 +
80177 +/**************************************************************************//**
80178 + @Function FM_MACSEC_SECY_RxSaEnableReceive
80179 +
80180 + @Description Enabling the SA to receive frames.
80181 +
80182 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80183 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80184 + @Param[in] an association number represent the SA.
80185 +
80186 + @Return E_OK on success; Error code otherwise.
80187 +
80188 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80189 +*//***************************************************************************/
80190 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80191 +
80192 +/**************************************************************************//**
80193 + @Function FM_MACSEC_SECY_RxSaDisableReceive
80194 +
80195 + @Description Disabling the SA from receive frames.
80196 +
80197 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80198 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80199 + @Param[in] an association number represent the SA.
80200 +
80201 + @Return E_OK on success; Error code otherwise.
80202 +
80203 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80204 +*//***************************************************************************/
80205 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
80206 +
80207 +/**************************************************************************//**
80208 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
80209 +
80210 + @Description Update the next packet number expected on RX;
80211 + The value of nextPN shall be set to the greater of its existing value and the
80212 + supplied of updtNextPN (802.1AE-2006 10.7.15).
80213 +
80214 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80215 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80216 + @Param[in] an association number represent the SA.
80217 + @Param[in] updtNextPN the next PN value for a received frame.
80218 +
80219 + @Return E_OK on success; Error code otherwise.
80220 +
80221 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80222 +*//***************************************************************************/
80223 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
80224 +
80225 +/**************************************************************************//**
80226 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
80227 +
80228 + @Description Update the lowest packet number expected on RX;
80229 + The value of lowestPN shall be set to the greater of its existing value and the
80230 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
80231 +
80232 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80233 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80234 + @Param[in] an association number represent the SA.
80235 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
80236 +
80237 + @Return E_OK on success; Error code otherwise.
80238 +
80239 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80240 +*//***************************************************************************/
80241 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
80242 +
80243 +/**************************************************************************//**
80244 + @Function FM_MACSEC_SECY_RxSaModifyKey
80245 +
80246 + @Description Modify the current key of the SA with a new one.
80247 +
80248 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80249 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80250 + @Param[in] an association number represent the SA.
80251 + @Param[in] key new key to replace the current key.
80252 +
80253 + @Return E_OK on success; Error code otherwise.
80254 +
80255 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
80256 +*//***************************************************************************/
80257 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
80258 +
80259 +/**************************************************************************//**
80260 + @Function FM_MACSEC_SECY_CreateTxSa
80261 +
80262 + @Description Create a transmit secure association for the secure channel;
80263 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
80264 + Only one SA can be active at a time.
80265 +
80266 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80267 + @Param[in] an association number represent the SA.
80268 + @Param[in] key the desired key for this SA.
80269 +
80270 + @Return E_OK on success; Error code otherwise.
80271 +
80272 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80273 +*//***************************************************************************/
80274 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
80275 +
80276 +/**************************************************************************//**
80277 + @Function FM_MACSEC_SECY_DeleteTxSa
80278 +
80279 + @Description Deleting an initialized secure association.
80280 +
80281 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80282 + @Param[in] an association number represent the SA.
80283 +
80284 + @Return E_OK on success; Error code otherwise.
80285 +
80286 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80287 +*//***************************************************************************/
80288 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
80289 +
80290 +/**************************************************************************//**
80291 + @Function FM_MACSEC_SECY_TxSaModifyKey
80292 +
80293 + @Description Modify the key of the inactive SA with a new one.
80294 +
80295 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80296 + @Param[in] nextActiveAn association number represent the next SA to be activated.
80297 + @Param[in] key new key to replace the current key.
80298 +
80299 + @Return E_OK on success; Error code otherwise.
80300 +
80301 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80302 +*//***************************************************************************/
80303 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
80304 +
80305 +/**************************************************************************//**
80306 + @Function FM_MACSEC_SECY_TxSaSetActive
80307 +
80308 + @Description Set this SA to the active SA to be used on TX for SC;
80309 + only one SA can be active at a time.
80310 +
80311 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80312 + @Param[in] an association number represent the SA.
80313 +
80314 + @Return E_OK on success; Error code otherwise.
80315 +
80316 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80317 +*//***************************************************************************/
80318 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
80319 +
80320 +/**************************************************************************//**
80321 + @Function FM_MACSEC_SECY_TxSaGetActive
80322 +
80323 + @Description Get the active SA that being used for TX.
80324 +
80325 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80326 + @Param[out] p_An the active an.
80327 +
80328 + @Return E_OK on success; Error code otherwise.
80329 +
80330 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80331 +*//***************************************************************************/
80332 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
80333 +
80334 +/**************************************************************************//**
80335 + @Function FM_MACSEC_SECY_GetStatistics
80336 +
80337 + @Description get all statistics counters.
80338 +
80339 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80340 + @Param[in] p_Statistics Structure with statistics.
80341 +
80342 + @Return E_OK on success; Error code otherwise.
80343 +
80344 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80345 +*//***************************************************************************/
80346 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
80347 +
80348 +/**************************************************************************//**
80349 + @Function FM_MACSEC_SECY_RxScGetStatistics
80350 +
80351 + @Description get all statistics counters.
80352 +
80353 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80354 + @Param[in] h_Sc Rx Sc handle.
80355 + @Param[in] p_Statistics Structure with statistics.
80356 +
80357 + @Return E_OK on success; Error code otherwise.
80358 +
80359 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80360 +*//***************************************************************************/
80361 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
80362 +
80363 +/**************************************************************************//**
80364 + @Function FM_MACSEC_SECY_RxSaGetStatistics
80365 +
80366 + @Description get all statistics counters
80367 +
80368 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80369 + @Param[in] h_Sc Rx Sc handle.
80370 + @Param[in] an association number represent the SA.
80371 + @Param[in] p_Statistics Structure with statistics.
80372 +
80373 + @Return E_OK on success; Error code otherwise.
80374 +
80375 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80376 +*//***************************************************************************/
80377 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
80378 +
80379 +/**************************************************************************//**
80380 + @Function FM_MACSEC_SECY_TxScGetStatistics
80381 +
80382 + @Description get all statistics counters.
80383 +
80384 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80385 + @Param[in] p_Statistics Structure with statistics.
80386 +
80387 + @Return E_OK on success; Error code otherwise.
80388 +
80389 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80390 +*//***************************************************************************/
80391 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
80392 +
80393 +/**************************************************************************//**
80394 + @Function FM_MACSEC_SECY_TxSaGetStatistics
80395 +
80396 + @Description get all statistics counters.
80397 +
80398 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80399 + @Param[in] an association number represent the SA.
80400 + @Param[in] p_Statistics Structure with statistics.
80401 +
80402 + @Return E_OK on success; Error code otherwise.
80403 +
80404 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80405 +*//***************************************************************************/
80406 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
80407 +
80408 +/**************************************************************************//**
80409 + @Function FM_MACSEC_SECY_SetException
80410 +
80411 + @Description Calling this routine enables/disables the specified exception.
80412 +
80413 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80414 + @Param[in] exception The exception to be selected.
80415 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80416 +
80417 + @Return E_OK on success; Error code otherwise.
80418 +
80419 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80420 +*//***************************************************************************/
80421 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
80422 +
80423 +/**************************************************************************//**
80424 + @Function FM_MACSEC_SECY_SetEvent
80425 +
80426 + @Description Calling this routine enables/disables the specified event.
80427 +
80428 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80429 + @Param[in] event The event to be selected.
80430 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80431 +
80432 + @Return E_OK on success; Error code otherwise.
80433 +
80434 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
80435 +*//***************************************************************************/
80436 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
80437 +
80438 +/**************************************************************************//**
80439 + @Function FM_MACSEC_SECY_GetRxScPhysId
80440 +
80441 + @Description return the physical id of the Secure Channel.
80442 +
80443 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80444 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
80445 + @Param[out] p_ScPhysId the SC physical id.
80446 +
80447 + @Return E_OK on success; Error code otherwise.
80448 +
80449 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
80450 +*//***************************************************************************/
80451 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
80452 +
80453 +/**************************************************************************//**
80454 + @Function FM_MACSEC_SECY_GetTxScPhysId
80455 +
80456 + @Description return the physical id of the Secure Channel.
80457 +
80458 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
80459 + @Param[out] p_ScPhysId the SC physical id.
80460 +
80461 + @Return E_OK on success; Error code otherwise.
80462 +
80463 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
80464 +*//***************************************************************************/
80465 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
80466 +
80467 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
80468 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
80469 +/** @} */ /* end of FM_MACSEC_grp group */
80470 +/** @} */ /* end of FM_grp group */
80471 +
80472 +
80473 +#endif /* __FM_MACSEC_EXT_H */
80474 --- /dev/null
80475 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
80476 @@ -0,0 +1,170 @@
80477 +/*
80478 + * Copyright 2008-2012 Freescale Semiconductor Inc.
80479 + *
80480 + * Redistribution and use in source and binary forms, with or without
80481 + * modification, are permitted provided that the following conditions are met:
80482 + * * Redistributions of source code must retain the above copyright
80483 + * notice, this list of conditions and the following disclaimer.
80484 + * * Redistributions in binary form must reproduce the above copyright
80485 + * notice, this list of conditions and the following disclaimer in the
80486 + * documentation and/or other materials provided with the distribution.
80487 + * * Neither the name of Freescale Semiconductor nor the
80488 + * names of its contributors may be used to endorse or promote products
80489 + * derived from this software without specific prior written permission.
80490 + *
80491 + *
80492 + * ALTERNATIVELY, this software may be distributed under the terms of the
80493 + * GNU General Public License ("GPL") as published by the Free Software
80494 + * Foundation, either version 2 of that License or (at your option) any
80495 + * later version.
80496 + *
80497 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80498 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80499 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80500 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80501 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80502 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80503 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80504 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80505 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80506 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80507 + */
80508 +
80509 +
80510 +/**************************************************************************//**
80511 + @File fm_muram_ext.h
80512 +
80513 + @Description FM MURAM Application Programming Interface.
80514 +*//***************************************************************************/
80515 +#ifndef __FM_MURAM_EXT
80516 +#define __FM_MURAM_EXT
80517 +
80518 +#include "error_ext.h"
80519 +#include "std_ext.h"
80520 +
80521 +
80522 +/**************************************************************************//**
80523 +
80524 + @Group FM_grp Frame Manager API
80525 +
80526 + @Description FM API functions, definitions and enums
80527 +
80528 + @{
80529 +*//***************************************************************************/
80530 +
80531 +/**************************************************************************//**
80532 + @Group FM_muram_grp FM MURAM
80533 +
80534 + @Description FM MURAM API functions, definitions and enums
80535 +
80536 + @{
80537 +*//***************************************************************************/
80538 +
80539 +/**************************************************************************//**
80540 + @Group FM_muram_init_grp FM MURAM Initialization Unit
80541 +
80542 + @Description FM MURAM initialization API functions, definitions and enums
80543 +
80544 + @{
80545 +*//***************************************************************************/
80546 +
80547 +/**************************************************************************//**
80548 + @Function FM_MURAM_ConfigAndInit
80549 +
80550 + @Description Creates partition in the MURAM.
80551 +
80552 + The routine returns a handle (descriptor) to the MURAM partition.
80553 + This descriptor must be passed as first parameter to all other
80554 + FM-MURAM function calls.
80555 +
80556 + No actual initialization or configuration of FM_MURAM hardware is
80557 + done by this routine.
80558 +
80559 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
80560 + @Param[in] size - Size of the FM-MURAM partition.
80561 +
80562 + @Return Handle to FM-MURAM object, or NULL for Failure.
80563 +*//***************************************************************************/
80564 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
80565 +
80566 +/**************************************************************************//**
80567 + @Function FM_MURAM_Free
80568 +
80569 + @Description Frees all resources that were assigned to FM-MURAM module.
80570 +
80571 + Calling this routine invalidates the descriptor.
80572 +
80573 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80574 +
80575 + @Return E_OK on success; Error code otherwise.
80576 +*//***************************************************************************/
80577 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
80578 +
80579 +/** @} */ /* end of FM_muram_init_grp group */
80580 +
80581 +
80582 +/**************************************************************************//**
80583 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
80584 +
80585 + @Description FM MURAM control API functions, definitions and enums
80586 +
80587 + @{
80588 +*//***************************************************************************/
80589 +
80590 +/**************************************************************************//**
80591 + @Function FM_MURAM_AllocMem
80592 +
80593 + @Description Allocate some memory from FM-MURAM partition.
80594 +
80595 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80596 + @Param[in] size - size of the memory to be allocated.
80597 + @Param[in] align - Alignment of the memory.
80598 +
80599 + @Return address of the allocated memory; NULL otherwise.
80600 +*//***************************************************************************/
80601 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
80602 +
80603 +/**************************************************************************//**
80604 + @Function FM_MURAM_AllocMemForce
80605 +
80606 + @Description Allocate some specific memory from FM-MURAM partition (according
80607 + to base).
80608 +
80609 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80610 + @Param[in] base - the desired base-address to be allocated.
80611 + @Param[in] size - size of the memory to be allocated.
80612 +
80613 + @Return address of the allocated memory; NULL otherwise.
80614 +*//***************************************************************************/
80615 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
80616 +
80617 +/**************************************************************************//**
80618 + @Function FM_MURAM_FreeMem
80619 +
80620 + @Description Free an allocated memory from FM-MURAM partition.
80621 +
80622 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80623 + @Param[in] ptr - A pointer to an allocated memory.
80624 +
80625 + @Return E_OK on success; Error code otherwise.
80626 +*//***************************************************************************/
80627 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
80628 +
80629 +/**************************************************************************//**
80630 + @Function FM_MURAM_GetFreeMemSize
80631 +
80632 + @Description Returns the size (in bytes) of free MURAM memory.
80633 +
80634 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
80635 +
80636 + @Return Free MURAM memory size in bytes.
80637 +*//***************************************************************************/
80638 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
80639 +
80640 +/** @} */ /* end of FM_muram_ctrl_grp group */
80641 +/** @} */ /* end of FM_muram_grp group */
80642 +/** @} */ /* end of FM_grp group */
80643 +
80644 +
80645 +
80646 +#endif /* __FM_MURAM_EXT */
80647 --- /dev/null
80648 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
80649 @@ -0,0 +1,3974 @@
80650 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
80651 + * All rights reserved.
80652 + *
80653 + * Redistribution and use in source and binary forms, with or without
80654 + * modification, are permitted provided that the following conditions are met:
80655 + * * Redistributions of source code must retain the above copyright
80656 + * notice, this list of conditions and the following disclaimer.
80657 + * * Redistributions in binary form must reproduce the above copyright
80658 + * notice, this list of conditions and the following disclaimer in the
80659 + * documentation and/or other materials provided with the distribution.
80660 + * * Neither the name of Freescale Semiconductor nor the
80661 + * names of its contributors may be used to endorse or promote products
80662 + * derived from this software without specific prior written permission.
80663 + *
80664 + *
80665 + * ALTERNATIVELY, this software may be distributed under the terms of the
80666 + * GNU General Public License ("GPL") as published by the Free Software
80667 + * Foundation, either version 2 of that License or (at your option) any
80668 + * later version.
80669 + *
80670 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80671 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80672 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80673 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80674 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80675 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80676 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80677 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80678 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80679 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80680 + */
80681 +
80682 +
80683 +/**************************************************************************//**
80684 + @File fm_pcd_ext.h
80685 +
80686 + @Description FM PCD API definitions
80687 +*//***************************************************************************/
80688 +#ifndef __FM_PCD_EXT
80689 +#define __FM_PCD_EXT
80690 +
80691 +#include "std_ext.h"
80692 +#include "net_ext.h"
80693 +#include "list_ext.h"
80694 +#include "fm_ext.h"
80695 +#include "fsl_fman_kg.h"
80696 +
80697 +
80698 +/**************************************************************************//**
80699 + @Group FM_grp Frame Manager API
80700 +
80701 + @Description Frame Manager Application Programming Interface
80702 +
80703 + @{
80704 +*//***************************************************************************/
80705 +
80706 +/**************************************************************************//**
80707 + @Group FM_PCD_grp FM PCD
80708 +
80709 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
80710 +
80711 + The FM PCD module is responsible for the initialization of all
80712 + global classifying FM modules. This includes the parser general and
80713 + common registers, the key generator global and common registers,
80714 + and the policer global and common registers.
80715 + In addition, the FM PCD SW module will initialize all required
80716 + key generator schemes, coarse classification flows, and policer
80717 + profiles. When FM module is configured to work with one of these
80718 + entities, it will register to it using the FM PORT API. The PCD
80719 + module will manage the PCD resources - i.e. resource management of
80720 + KeyGen schemes, etc.
80721 +
80722 + @{
80723 +*//***************************************************************************/
80724 +
80725 +/**************************************************************************//**
80726 + @Collection General PCD defines
80727 +*//***************************************************************************/
80728 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
80729 +
80730 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
80731 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
80732 + /**< Number of distinction units is limited by
80733 + register size (32 bits) minus reserved bits
80734 + for private headers. */
80735 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
80736 + in a distinction unit */
80737 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
80738 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
80739 + For HW implementation reasons, in most
80740 + cases less than this will be allowed; The
80741 + driver will return an initialization error
80742 + if resource is unavailable. */
80743 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
80744 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
80745 +
80746 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
80747 +#define FM_SW_PRS_MAX_IMAGE_SIZE (FM_PCD_SW_PRS_SIZE /*- FM_PCD_PRS_SW_OFFSET -FM_PCD_PRS_SW_TAIL_SIZE*/-FM_PCD_PRS_SW_PATCHES_SIZE)
80748 + /**< Maximum size of SW parser code */
80749 +
80750 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
80751 + insert manipulation */
80752 +
80753 +#if (DPAA_VERSION >= 11)
80754 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
80755 +#endif /* (DPAA_VERSION >= 11) */
80756 +/* @} */
80757 +
80758 +
80759 +/**************************************************************************//**
80760 + @Group FM_PCD_init_grp FM PCD Initialization Unit
80761 +
80762 + @Description Frame Manager PCD Initialization Unit API
80763 +
80764 + @{
80765 +*//***************************************************************************/
80766 +
80767 +/**************************************************************************//**
80768 + @Description PCD counters
80769 +*//***************************************************************************/
80770 +typedef enum e_FmPcdCounters {
80771 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
80772 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
80773 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
80774 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
80775 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
80776 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
80777 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
80778 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
80779 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
80780 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
80781 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
80782 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
80783 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
80784 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
80785 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */
80786 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */
80787 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */
80788 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */
80789 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
80790 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */
80791 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */
80792 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
80793 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
80794 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
80795 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
80796 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
80797 +} e_FmPcdCounters;
80798 +
80799 +/**************************************************************************//**
80800 + @Description PCD interrupts
80801 +*//***************************************************************************/
80802 +typedef enum e_FmPcdExceptions {
80803 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
80804 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
80805 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
80806 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
80807 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
80808 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
80809 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
80810 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
80811 +} e_FmPcdExceptions;
80812 +
80813 +
80814 +/**************************************************************************//**
80815 + @Description Exceptions user callback routine, will be called upon an
80816 + exception passing the exception identification.
80817 +
80818 + @Param[in] h_App - User's application descriptor.
80819 + @Param[in] exception - The exception.
80820 + *//***************************************************************************/
80821 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
80822 +
80823 +/**************************************************************************//**
80824 + @Description Exceptions user callback routine, will be called upon an exception
80825 + passing the exception identification.
80826 +
80827 + @Param[in] h_App - User's application descriptor.
80828 + @Param[in] exception - The exception.
80829 + @Param[in] index - id of the relevant source (may be scheme or profile id).
80830 + *//***************************************************************************/
80831 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
80832 + e_FmPcdExceptions exception,
80833 + uint16_t index);
80834 +
80835 +/**************************************************************************//**
80836 + @Description A callback for enqueuing frame onto a QM queue.
80837 +
80838 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
80839 + @Param[in] p_Fd - Frame descriptor for the frame.
80840 +
80841 + @Return E_OK on success; Error code otherwise.
80842 + *//***************************************************************************/
80843 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
80844 +
80845 +/**************************************************************************//**
80846 + @Description Host-Command parameters structure.
80847 +
80848 + When using Host command for PCD functionalities, a dedicated port
80849 + must be used. If this routine is called for a PCD in a single partition
80850 + environment, or it is the Master partition in a Multi-partition
80851 + environment, The port will be initialized by the PCD driver
80852 + initialization routine.
80853 + *//***************************************************************************/
80854 +typedef struct t_FmPcdHcParams {
80855 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
80856 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
80857 + NOTE: When configuring Host Command port for
80858 + FMANv3 devices (DPAA_VERSION 11 and higher),
80859 + portId=0 MUST be used. */
80860 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
80861 + (irrelevant for P4080 revision 1.0) */
80862 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
80863 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
80864 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
80865 + will be used by the FM for dequeue. */
80866 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
80867 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
80868 +} t_FmPcdHcParams;
80869 +
80870 +/**************************************************************************//**
80871 + @Description The main structure for PCD initialization
80872 + *//***************************************************************************/
80873 +typedef struct t_FmPcdParams {
80874 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
80875 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
80876 + of the FM ports. */
80877 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
80878 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
80879 + t_Handle h_Fm; /**< A handle to the FM module. */
80880 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
80881 + this parameter is relevant if 'kgSupport'=TRUE. */
80882 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
80883 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
80884 + Relevant when FM not runs in "guest-mode". */
80885 +
80886 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
80887 + Relevant when FM not runs in "guest-mode". */
80888 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
80889 + Policer profile exceptions;
80890 + Relevant when FM not runs in "guest-mode". */
80891 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80892 + be passed by the driver upon calling the above callbacks;
80893 + Relevant when FM not runs in "guest-mode". */
80894 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
80895 + this parameter is relevant if 'plcrSupport'=TRUE.
80896 + NOTE: this parameter relevant only when working with multiple partitions. */
80897 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
80898 + this parameter is relevant if 'plcrSupport'=TRUE.
80899 + NOTE: this parameter relevant only when working with multiple partitions. */
80900 +} t_FmPcdParams;
80901 +
80902 +
80903 +/**************************************************************************//**
80904 + @Function FM_PCD_Config
80905 +
80906 + @Description Basic configuration of the PCD module.
80907 + Creates descriptor for the FM PCD module.
80908 +
80909 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
80910 +
80911 + @Return A handle to the initialized module.
80912 +*//***************************************************************************/
80913 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
80914 +
80915 +/**************************************************************************//**
80916 + @Function FM_PCD_Init
80917 +
80918 + @Description Initialization of the PCD module.
80919 +
80920 + @Param[in] h_FmPcd - FM PCD module descriptor.
80921 +
80922 + @Return E_OK on success; Error code otherwise.
80923 +*//***************************************************************************/
80924 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
80925 +
80926 +/**************************************************************************//**
80927 + @Function FM_PCD_Free
80928 +
80929 + @Description Frees all resources that were assigned to FM module.
80930 +
80931 + Calling this routine invalidates the descriptor.
80932 +
80933 + @Param[in] h_FmPcd - FM PCD module descriptor.
80934 +
80935 + @Return E_OK on success; Error code otherwise.
80936 +*//***************************************************************************/
80937 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
80938 +
80939 +/**************************************************************************//**
80940 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
80941 +
80942 + @Description Frame Manager PCD Advanced Configuration API.
80943 +
80944 + @{
80945 +*//***************************************************************************/
80946 +
80947 +/**************************************************************************//**
80948 + @Function FM_PCD_ConfigException
80949 +
80950 + @Description Calling this routine changes the internal driver data base
80951 + from its default selection of exceptions enabling.
80952 + [DEFAULT_numOfSharedPlcrProfiles].
80953 +
80954 + @Param[in] h_FmPcd FM PCD module descriptor.
80955 + @Param[in] exception The exception to be selected.
80956 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
80957 +
80958 + @Return E_OK on success; Error code otherwise.
80959 +
80960 + @Cautions This routine should NOT be called from guest-partition
80961 + (i.e. guestId != NCSW_MASTER_ID)
80962 +*//***************************************************************************/
80963 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
80964 +
80965 +/**************************************************************************//**
80966 + @Function FM_PCD_ConfigHcFramesDataMemory
80967 +
80968 + @Description Configures memory-partition-id for FMan-Controller Host-Command
80969 + frames. Calling this routine changes the internal driver data
80970 + base from its default configuration [0].
80971 +
80972 + @Param[in] h_FmPcd FM PCD module descriptor.
80973 + @Param[in] memId Memory partition ID.
80974 +
80975 + @Return E_OK on success; Error code otherwise.
80976 +
80977 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
80978 + when FM_PCD_Config() routine was called.
80979 +*//***************************************************************************/
80980 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
80981 +
80982 +/**************************************************************************//**
80983 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
80984 +
80985 + @Description Calling this routine changes the internal driver data base
80986 + from its default selection of exceptions enablement.
80987 + [DEFAULT_numOfSharedPlcrProfiles].
80988 +
80989 + @Param[in] h_FmPcd FM PCD module descriptor.
80990 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
80991 + be shared between ports on this partition
80992 +
80993 + @Return E_OK on success; Error code otherwise.
80994 +*//***************************************************************************/
80995 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
80996 +
80997 +/**************************************************************************//**
80998 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
80999 +
81000 + @Description Calling this routine changes the internal driver data base
81001 + from its default selection of exceptions enablement.
81002 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
81003 +
81004 + @Param[in] h_FmPcd FM PCD module descriptor.
81005 + @Param[in] enable TRUE to enable, FALSE to disable
81006 +
81007 + @Return E_OK on success; Error code otherwise.
81008 +
81009 + @Cautions This routine should NOT be called from guest-partition
81010 + (i.e. guestId != NCSW_MASTER_ID)
81011 +*//***************************************************************************/
81012 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
81013 +
81014 +/**************************************************************************//**
81015 + @Function FM_PCD_ConfigPrsMaxCycleLimit
81016 +
81017 + @Description Calling this routine changes the internal data structure for
81018 + the maximum parsing time from its default value
81019 + [DEFAULT_MAX_PRS_CYC_LIM].
81020 +
81021 + @Param[in] h_FmPcd FM PCD module descriptor.
81022 + @Param[in] value 0 to disable the mechanism, or new
81023 + maximum parsing time.
81024 +
81025 + @Return E_OK on success; Error code otherwise.
81026 +
81027 + @Cautions This routine should NOT be called from guest-partition
81028 + (i.e. guestId != NCSW_MASTER_ID)
81029 +*//***************************************************************************/
81030 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
81031 +
81032 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
81033 +/** @} */ /* end of FM_PCD_init_grp group */
81034 +
81035 +
81036 +/**************************************************************************//**
81037 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
81038 +
81039 + @Description Frame Manager PCD Runtime Unit API
81040 +
81041 + The runtime control allows creation of PCD infrastructure modules
81042 + such as Network Environment Characteristics, Classification Plan
81043 + Groups and Coarse Classification Trees.
81044 + It also allows on-the-fly initialization, modification and removal
81045 + of PCD modules such as KeyGen schemes, coarse classification nodes
81046 + and Policer profiles.
81047 +
81048 + In order to explain the programming model of the PCD driver interface
81049 + a few terms should be explained, and will be used below.
81050 + - Distinction Header - One of the 16 protocols supported by the FM parser,
81051 + or one of the SHIM headers (1 or 2). May be a header with a special
81052 + option (see below).
81053 + - Interchangeable Headers Group - This is a group of Headers recognized
81054 + by either one of them. For example, if in a specific context the user
81055 + chooses to treat IPv4 and IPV6 in the same way, they may create an
81056 + interchangeable Headers Unit consisting of these 2 headers.
81057 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
81058 + Group.
81059 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
81060 + IPv6, includes multicast, broadcast and other protocol specific options.
81061 + In terms of hardware it relates to the options available in the classification
81062 + plan.
81063 + - Network Environment Characteristics - a set of Distinction Units that define
81064 + the total recognizable header selection for a certain environment. This is
81065 + NOT the list of all headers that will ever appear in a flow, but rather
81066 + everything that needs distinction in a flow, where distinction is made by KeyGen
81067 + schemes and coarse classification action descriptors.
81068 +
81069 + The PCD runtime modules initialization is done in stages. The first stage after
81070 + initializing the PCD module itself is to establish a Network Flows Environment
81071 + Definition. The application may choose to establish one or more such environments.
81072 + Later, when needed, the application will have to state, for some of its modules,
81073 + to which single environment it belongs.
81074 +
81075 + @{
81076 +*//***************************************************************************/
81077 +
81078 +/**************************************************************************//**
81079 + @Description A structure for SW parser labels
81080 + *//***************************************************************************/
81081 +typedef struct t_FmPcdPrsLabelParams {
81082 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
81083 + resolution), relative to Parser RAM. */
81084 + e_NetHeaderType hdr; /**< The existence of this header will invoke
81085 + the SW parser code; Use HEADER_TYPE_NONE
81086 + to indicate that sw parser is to run
81087 + independent of the existence of any protocol
81088 + (run before HW parser). */
81089 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
81090 + attachments for the same header, use this
81091 + index to distinguish between them. */
81092 +} t_FmPcdPrsLabelParams;
81093 +
81094 +/**************************************************************************//**
81095 + @Description A structure for SW parser
81096 + *//***************************************************************************/
81097 +typedef struct t_FmPcdPrsSwParams {
81098 + bool override; /**< FALSE to invoke a check that nothing else
81099 + was loaded to this address, including
81100 + internal patches.
81101 + TRUE to override any existing code.*/
81102 + uint32_t size; /**< SW parser code size */
81103 + uint16_t base; /**< SW parser base (in instruction counts!
81104 + must be larger than 0x20)*/
81105 + uint8_t *p_Code; /**< SW parser code */
81106 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
81107 + /**< SW parser data (parameters) */
81108 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
81109 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
81110 + /**< SW parser labels table, containing
81111 + numOfLabels entries */
81112 +} t_FmPcdPrsSwParams;
81113 +
81114 +
81115 +/**************************************************************************//**
81116 + @Function FM_PCD_Enable
81117 +
81118 + @Description This routine should be called after PCD is initialized for enabling all
81119 + PCD engines according to their existing configuration.
81120 +
81121 + @Param[in] h_FmPcd FM PCD module descriptor.
81122 +
81123 + @Return E_OK on success; Error code otherwise.
81124 +
81125 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81126 +*//***************************************************************************/
81127 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
81128 +
81129 +/**************************************************************************//**
81130 + @Function FM_PCD_Disable
81131 +
81132 + @Description This routine may be called when PCD is enabled in order to
81133 + disable all PCD engines. It may be called
81134 + only when none of the ports in the system are using the PCD.
81135 +
81136 + @Param[in] h_FmPcd FM PCD module descriptor.
81137 +
81138 + @Return E_OK on success; Error code otherwise.
81139 +
81140 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
81141 +*//***************************************************************************/
81142 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
81143 +
81144 +/**************************************************************************//**
81145 + @Function FM_PCD_GetCounter
81146 +
81147 + @Description Reads one of the FM PCD counters.
81148 +
81149 + @Param[in] h_FmPcd FM PCD module descriptor.
81150 + @Param[in] counter The requested counter.
81151 +
81152 + @Return Counter's current value.
81153 +
81154 + @Cautions Allowed only following FM_PCD_Init().
81155 + Note that it is user's responsibility to call this routine only
81156 + for enabled counters, and there will be no indication if a
81157 + disabled counter is accessed.
81158 +*//***************************************************************************/
81159 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
81160 +
81161 +/**************************************************************************//**
81162 +@Function FM_PCD_PrsLoadSw
81163 +
81164 +@Description This routine may be called in order to load software parsing code.
81165 +
81166 +
81167 +@Param[in] h_FmPcd FM PCD module descriptor.
81168 +@Param[in] p_SwPrs A pointer to a structure of software
81169 + parser parameters, including the software
81170 + parser image.
81171 +
81172 +@Return E_OK on success; Error code otherwise.
81173 +
81174 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81175 + This routine should NOT be called from guest-partition
81176 + (i.e. guestId != NCSW_MASTER_ID)
81177 +*//***************************************************************************/
81178 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
81179 +
81180 +/**************************************************************************//**
81181 +@Function FM_PCD_SetAdvancedOffloadSupport
81182 +
81183 +@Description This routine must be called in order to support the following features:
81184 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
81185 +
81186 +@Param[in] h_FmPcd FM PCD module descriptor.
81187 +
81188 +@Return E_OK on success; Error code otherwise.
81189 +
81190 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81191 + This routine should NOT be called from guest-partition
81192 + (i.e. guestId != NCSW_MASTER_ID)
81193 +*//***************************************************************************/
81194 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
81195 +
81196 +/**************************************************************************//**
81197 + @Function FM_PCD_KgSetDfltValue
81198 +
81199 + @Description Calling this routine sets a global default value to be used
81200 + by the KeyGen when parser does not recognize a required
81201 + field/header.
81202 + By default default values are 0.
81203 +
81204 + @Param[in] h_FmPcd FM PCD module descriptor.
81205 + @Param[in] valueId 0,1 - one of 2 global default values.
81206 + @Param[in] value The requested default value.
81207 +
81208 + @Return E_OK on success; Error code otherwise.
81209 +
81210 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81211 + This routine should NOT be called from guest-partition
81212 + (i.e. guestId != NCSW_MASTER_ID)
81213 +*//***************************************************************************/
81214 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
81215 +
81216 +/**************************************************************************//**
81217 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
81218 +
81219 + @Description Calling this routine allows the KeyGen to access data past
81220 + the parser finishing point.
81221 +
81222 + @Param[in] h_FmPcd FM PCD module descriptor.
81223 + @Param[in] payloadOffset the number of bytes beyond the parser location.
81224 +
81225 + @Return E_OK on success; Error code otherwise.
81226 +
81227 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
81228 + This routine should NOT be called from guest-partition
81229 + (i.e. guestId != NCSW_MASTER_ID)
81230 +*//***************************************************************************/
81231 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
81232 +
81233 +/**************************************************************************//**
81234 + @Function FM_PCD_SetException
81235 +
81236 + @Description Calling this routine enables/disables PCD interrupts.
81237 +
81238 + @Param[in] h_FmPcd FM PCD module descriptor.
81239 + @Param[in] exception The exception to be selected.
81240 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81241 +
81242 + @Return E_OK on success; Error code otherwise.
81243 +
81244 + @Cautions Allowed only following FM_PCD_Init().
81245 + This routine should NOT be called from guest-partition
81246 + (i.e. guestId != NCSW_MASTER_ID)
81247 +*//***************************************************************************/
81248 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
81249 +
81250 +/**************************************************************************//**
81251 + @Function FM_PCD_ModifyCounter
81252 +
81253 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
81254 +
81255 + @Param[in] h_FmPcd FM PCD module descriptor.
81256 + @Param[in] counter The requested counter.
81257 + @Param[in] value The requested value to be written into the counter.
81258 +
81259 + @Return E_OK on success; Error code otherwise.
81260 +
81261 + @Cautions Allowed only following FM_PCD_Init().
81262 + This routine should NOT be called from guest-partition
81263 + (i.e. guestId != NCSW_MASTER_ID)
81264 +*//***************************************************************************/
81265 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
81266 +
81267 +/**************************************************************************//**
81268 + @Function FM_PCD_SetPlcrStatistics
81269 +
81270 + @Description This routine may be used to enable/disable policer statistics
81271 + counter. By default the statistics is enabled.
81272 +
81273 + @Param[in] h_FmPcd FM PCD module descriptor
81274 + @Param[in] enable TRUE to enable, FALSE to disable.
81275 +
81276 + @Return E_OK on success; Error code otherwise.
81277 +
81278 + @Cautions Allowed only following FM_PCD_Init().
81279 + This routine should NOT be called from guest-partition
81280 + (i.e. guestId != NCSW_MASTER_ID)
81281 +*//***************************************************************************/
81282 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
81283 +
81284 +/**************************************************************************//**
81285 + @Function FM_PCD_SetPrsStatistics
81286 +
81287 + @Description Defines whether to gather parser statistics including all ports.
81288 +
81289 + @Param[in] h_FmPcd FM PCD module descriptor.
81290 + @Param[in] enable TRUE to enable, FALSE to disable.
81291 +
81292 + @Return None
81293 +
81294 + @Cautions Allowed only following FM_PCD_Init().
81295 + This routine should NOT be called from guest-partition
81296 + (i.e. guestId != NCSW_MASTER_ID)
81297 +*//***************************************************************************/
81298 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
81299 +
81300 +/**************************************************************************//**
81301 + @Function FM_PCD_HcTxConf
81302 +
81303 + @Description This routine should be called to confirm frames that were
81304 + received on the HC confirmation queue.
81305 +
81306 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81307 + @Param[in] p_Fd Frame descriptor of the received frame.
81308 +
81309 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
81310 + option was selected in the initialization.
81311 +*//***************************************************************************/
81312 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
81313 +
81314 +/**************************************************************************//*
81315 + @Function FM_PCD_ForceIntr
81316 +
81317 + @Description Causes an interrupt event on the requested source.
81318 +
81319 + @Param[in] h_FmPcd FM PCD module descriptor.
81320 + @Param[in] exception An exception to be forced.
81321 +
81322 + @Return E_OK on success; Error code if the exception is not enabled,
81323 + or is not able to create interrupt.
81324 +
81325 + @Cautions Allowed only following FM_PCD_Init().
81326 + This routine should NOT be called from guest-partition
81327 + (i.e. guestId != NCSW_MASTER_ID)
81328 +*//***************************************************************************/
81329 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
81330 +
81331 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81332 +/**************************************************************************//**
81333 + @Function FM_PCD_DumpRegs
81334 +
81335 + @Description Dumps all PCD registers
81336 +
81337 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81338 +
81339 + @Return E_OK on success; Error code otherwise.
81340 +
81341 + @Cautions Allowed only following FM_PCD_Init().
81342 + NOTE: this routine may be called only for FM in master mode
81343 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81344 + are mapped.
81345 +*//***************************************************************************/
81346 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
81347 +
81348 +/**************************************************************************//**
81349 + @Function FM_PCD_KgDumpRegs
81350 +
81351 + @Description Dumps all PCD KG registers
81352 +
81353 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81354 +
81355 + @Return E_OK on success; Error code otherwise.
81356 +
81357 + @Cautions Allowed only following FM_PCD_Init().
81358 + NOTE: this routine may be called only for FM in master mode
81359 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81360 + are mapped.
81361 +*//***************************************************************************/
81362 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
81363 +
81364 +/**************************************************************************//**
81365 + @Function FM_PCD_PlcrDumpRegs
81366 +
81367 + @Description Dumps all PCD Policer registers
81368 +
81369 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81370 +
81371 + @Return E_OK on success; Error code otherwise.
81372 +
81373 + @Cautions Allowed only following FM_PCD_Init().
81374 + NOTE: this routine may be called only for FM in master mode
81375 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81376 + are mapped.
81377 +*//***************************************************************************/
81378 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
81379 +
81380 +/**************************************************************************//**
81381 + @Function FM_PCD_PlcrProfileDumpRegs
81382 +
81383 + @Description Dumps all PCD Policer profile registers
81384 +
81385 + @Param[in] h_Profile A handle to a Policer profile.
81386 +
81387 + @Return E_OK on success; Error code otherwise.
81388 +
81389 + @Cautions Allowed only following FM_PCD_Init().
81390 + NOTE: this routine may be called only for FM in master mode
81391 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81392 + are mapped.
81393 +*//***************************************************************************/
81394 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
81395 +
81396 +/**************************************************************************//**
81397 + @Function FM_PCD_PrsDumpRegs
81398 +
81399 + @Description Dumps all PCD Parser registers
81400 +
81401 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81402 +
81403 + @Return E_OK on success; Error code otherwise.
81404 +
81405 + @Cautions Allowed only following FM_PCD_Init().
81406 + NOTE: this routine may be called only for FM in master mode
81407 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
81408 + are mapped.
81409 +*//***************************************************************************/
81410 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
81411 +
81412 +/**************************************************************************//**
81413 + @Function FM_PCD_HcDumpRegs
81414 +
81415 + @Description Dumps HC Port registers
81416 +
81417 + @Param[in] h_FmPcd A handle to an FM PCD Module.
81418 +
81419 + @Return E_OK on success; Error code otherwise.
81420 +
81421 + @Cautions Allowed only following FM_PCD_Init().
81422 + NOTE: this routine may be called only for FM in master mode
81423 + (i.e. 'guestId'=NCSW_MASTER_ID).
81424 +*//***************************************************************************/
81425 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
81426 +#endif /* (defined(DEBUG_ERRORS) && ... */
81427 +
81428 +
81429 +
81430 +/**************************************************************************//**
81431 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
81432 +
81433 + @Description Frame Manager PCD Runtime Building API
81434 +
81435 + This group contains routines for setting, deleting and modifying
81436 + PCD resources, for defining the total PCD tree.
81437 + @{
81438 +*//***************************************************************************/
81439 +
81440 +/**************************************************************************//**
81441 + @Collection Definitions of coarse classification
81442 + parameters as required by KeyGen (when coarse classification
81443 + is the next engine after this scheme).
81444 +*//***************************************************************************/
81445 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
81446 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
81447 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
81448 +#define FM_PCD_MAX_NUM_OF_KEYS 256
81449 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
81450 +#define FM_PCD_MAX_SIZE_OF_KEY 56
81451 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
81452 +#define FM_PCD_LAST_KEY_INDEX 0xffff
81453 +
81454 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
81455 +/* @} */
81456 +
81457 +/**************************************************************************//**
81458 + @Collection A set of definitions to allow protocol
81459 + special option description.
81460 +*//***************************************************************************/
81461 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
81462 +
81463 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
81464 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
81465 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
81466 +
81467 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
81468 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
81469 +
81470 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
81471 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
81472 +
81473 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
81474 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
81475 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
81476 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
81477 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
81478 +
81479 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
81480 + IPV4 Reassembly manipulation requires network
81481 + environment with IPV4 header and IPV4_FRAG_1 option */
81482 +
81483 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
81484 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
81485 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
81486 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
81487 +
81488 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
81489 + IPV6 Reassembly manipulation requires network
81490 + environment with IPV6 header and IPV6_FRAG_1 option;
81491 + in case where fragment found, the fragment-extension offset
81492 + may be found at 'shim2' (in parser-result). */
81493 +#if (DPAA_VERSION >= 11)
81494 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
81495 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
81496 + CAPWAP Reassembly manipulation requires network
81497 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
81498 + in case where fragment found, the fragment-extension offset
81499 + may be found at 'shim2' (in parser-result). */
81500 +#endif /* (DPAA_VERSION >= 11) */
81501 +
81502 +
81503 +/* @} */
81504 +
81505 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
81506 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
81507 +
81508 +/**************************************************************************//**
81509 + @Collection A set of definitions to support Header Manipulation selection.
81510 +*//***************************************************************************/
81511 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
81512 +
81513 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
81514 +
81515 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
81516 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81517 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
81518 + of t_FmPcdManipHdrFieldUpdateIpv4) */
81519 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
81520 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
81521 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81522 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
81523 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
81524 +
81525 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
81526 +
81527 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
81528 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81529 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
81530 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
81531 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81532 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
81533 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
81534 +
81535 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
81536 +
81537 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
81538 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81539 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
81540 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
81541 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
81542 +
81543 +/* @} */
81544 +
81545 +/**************************************************************************//**
81546 + @Description A type used for returning the order of the key extraction.
81547 + each value in this array represents the index of the extraction
81548 + command as defined by the user in the initialization extraction array.
81549 + The valid size of this array is the user define number of extractions
81550 + required (also marked by the second '0' in this array).
81551 +*//***************************************************************************/
81552 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
81553 +
81554 +/**************************************************************************//**
81555 + @Description All PCD engines
81556 +*//***************************************************************************/
81557 +typedef enum e_FmPcdEngine {
81558 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
81559 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
81560 + e_FM_PCD_KG, /**< KeyGen */
81561 + e_FM_PCD_CC, /**< Coarse classifier */
81562 + e_FM_PCD_PLCR, /**< Policer */
81563 + e_FM_PCD_PRS, /**< Parser */
81564 +#if (DPAA_VERSION >= 11)
81565 + e_FM_PCD_FR, /**< Frame-Replicator */
81566 +#endif /* (DPAA_VERSION >= 11) */
81567 + e_FM_PCD_HASH /**< Hash table */
81568 +} e_FmPcdEngine;
81569 +
81570 +/**************************************************************************//**
81571 + @Description Enumeration type for selecting extraction by header types
81572 +*//***************************************************************************/
81573 +typedef enum e_FmPcdExtractByHdrType {
81574 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
81575 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
81576 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
81577 +} e_FmPcdExtractByHdrType;
81578 +
81579 +/**************************************************************************//**
81580 + @Description Enumeration type for selecting extraction source
81581 + (when it is not the header)
81582 +*//***************************************************************************/
81583 +typedef enum e_FmPcdExtractFrom {
81584 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
81585 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
81586 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
81587 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
81588 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
81589 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
81590 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
81591 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
81592 +} e_FmPcdExtractFrom;
81593 +
81594 +/**************************************************************************//**
81595 + @Description Enumeration type for selecting extraction type
81596 +*//***************************************************************************/
81597 +typedef enum e_FmPcdExtractType {
81598 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
81599 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
81600 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
81601 +} e_FmPcdExtractType;
81602 +
81603 +/**************************************************************************//**
81604 + @Description Enumeration type for selecting default extraction value
81605 +*//***************************************************************************/
81606 +typedef enum e_FmPcdKgExtractDfltSelect {
81607 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
81608 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
81609 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
81610 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
81611 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
81612 +} e_FmPcdKgExtractDfltSelect;
81613 +
81614 +/**************************************************************************//**
81615 + @Description Enumeration type defining all default groups - each group shares
81616 + a default value, one of four user-initialized values.
81617 +*//***************************************************************************/
81618 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
81619 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
81620 + e_FM_PCD_KG_TCI, /**< TCI field */
81621 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
81622 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
81623 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
81624 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
81625 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
81626 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
81627 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
81628 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
81629 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
81630 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
81631 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
81632 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
81633 + any data extraction that is not the full
81634 + field described above */
81635 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
81636 + any data extraction without validation */
81637 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
81638 + extraction from parser result or
81639 + direct use of default value */
81640 +} e_FmPcdKgKnownFieldsDfltTypes;
81641 +
81642 +/**************************************************************************//**
81643 + @Description Enumeration type for defining header index for scenarios with
81644 + multiple (tunneled) headers
81645 +*//***************************************************************************/
81646 +typedef enum e_FmPcdHdrIndex {
81647 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
81648 + to specify regular IP (not tunneled). */
81649 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
81650 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
81651 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
81652 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
81653 +} e_FmPcdHdrIndex;
81654 +
81655 +/**************************************************************************//**
81656 + @Description Enumeration type for selecting the policer profile functional type
81657 +*//***************************************************************************/
81658 +typedef enum e_FmPcdProfileTypeSelection {
81659 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
81660 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
81661 +} e_FmPcdProfileTypeSelection;
81662 +
81663 +/**************************************************************************//**
81664 + @Description Enumeration type for selecting the policer profile algorithm
81665 +*//***************************************************************************/
81666 +typedef enum e_FmPcdPlcrAlgorithmSelection {
81667 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
81668 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
81669 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
81670 +} e_FmPcdPlcrAlgorithmSelection;
81671 +
81672 +/**************************************************************************//**
81673 + @Description Enumeration type for selecting a policer profile color mode
81674 +*//***************************************************************************/
81675 +typedef enum e_FmPcdPlcrColorMode {
81676 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
81677 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
81678 +} e_FmPcdPlcrColorMode;
81679 +
81680 +/**************************************************************************//**
81681 + @Description Enumeration type for selecting a policer profile color
81682 +*//***************************************************************************/
81683 +typedef enum e_FmPcdPlcrColor {
81684 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
81685 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
81686 + e_FM_PCD_PLCR_RED, /**< Red color code */
81687 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
81688 +} e_FmPcdPlcrColor;
81689 +
81690 +/**************************************************************************//**
81691 + @Description Enumeration type for selecting the policer profile packet frame length selector
81692 +*//***************************************************************************/
81693 +typedef enum e_FmPcdPlcrFrameLengthSelect {
81694 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
81695 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
81696 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
81697 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
81698 +} e_FmPcdPlcrFrameLengthSelect;
81699 +
81700 +/**************************************************************************//**
81701 + @Description Enumeration type for selecting roll-back frame
81702 +*//***************************************************************************/
81703 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
81704 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
81705 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
81706 +} e_FmPcdPlcrRollBackFrameSelect;
81707 +
81708 +/**************************************************************************//**
81709 + @Description Enumeration type for selecting the policer profile packet or byte mode
81710 +*//***************************************************************************/
81711 +typedef enum e_FmPcdPlcrRateMode {
81712 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
81713 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
81714 +} e_FmPcdPlcrRateMode;
81715 +
81716 +/**************************************************************************//**
81717 + @Description Enumeration type for defining action of frame
81718 +*//***************************************************************************/
81719 +typedef enum e_FmPcdDoneAction {
81720 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
81721 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
81722 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
81723 + flag will be set for this frame. */
81724 +} e_FmPcdDoneAction;
81725 +
81726 +/**************************************************************************//**
81727 + @Description Enumeration type for selecting the policer counter
81728 +*//***************************************************************************/
81729 +typedef enum e_FmPcdPlcrProfileCounters {
81730 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
81731 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
81732 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
81733 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
81734 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
81735 +} e_FmPcdPlcrProfileCounters;
81736 +
81737 +/**************************************************************************//**
81738 + @Description Enumeration type for selecting the PCD action after extraction
81739 +*//***************************************************************************/
81740 +typedef enum e_FmPcdAction {
81741 + e_FM_PCD_ACTION_NONE, /**< NONE */
81742 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
81743 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
81744 +} e_FmPcdAction;
81745 +
81746 +/**************************************************************************//**
81747 + @Description Enumeration type for selecting type of insert manipulation
81748 +*//***************************************************************************/
81749 +typedef enum e_FmPcdManipHdrInsrtType {
81750 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
81751 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
81752 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81753 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
81754 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81755 +} e_FmPcdManipHdrInsrtType;
81756 +
81757 +/**************************************************************************//**
81758 + @Description Enumeration type for selecting type of remove manipulation
81759 +*//***************************************************************************/
81760 +typedef enum e_FmPcdManipHdrRmvType {
81761 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
81762 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
81763 +} e_FmPcdManipHdrRmvType;
81764 +
81765 +/**************************************************************************//**
81766 + @Description Enumeration type for selecting specific L2 fields removal
81767 +*//***************************************************************************/
81768 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
81769 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
81770 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
81771 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
81772 + the header which follows the MPLS header */
81773 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
81774 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
81775 +} e_FmPcdManipHdrRmvSpecificL2;
81776 +
81777 +/**************************************************************************//**
81778 + @Description Enumeration type for selecting specific fields updates
81779 +*//***************************************************************************/
81780 +typedef enum e_FmPcdManipHdrFieldUpdateType {
81781 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
81782 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
81783 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
81784 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
81785 +} e_FmPcdManipHdrFieldUpdateType;
81786 +
81787 +/**************************************************************************//**
81788 + @Description Enumeration type for selecting VLAN updates
81789 +*//***************************************************************************/
81790 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
81791 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
81792 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
81793 +} e_FmPcdManipHdrFieldUpdateVlan;
81794 +
81795 +/**************************************************************************//**
81796 + @Description Enumeration type for selecting specific L2 header insertion
81797 +*//***************************************************************************/
81798 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
81799 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
81800 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
81801 +} e_FmPcdManipHdrInsrtSpecificL2;
81802 +
81803 +#if (DPAA_VERSION >= 11)
81804 +/**************************************************************************//**
81805 + @Description Enumeration type for selecting QoS mapping mode
81806 +
81807 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
81808 + User should instruct the port to read the hash-result
81809 +*//***************************************************************************/
81810 +typedef enum e_FmPcdManipHdrQosMappingMode {
81811 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
81812 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
81813 +} e_FmPcdManipHdrQosMappingMode;
81814 +
81815 +/**************************************************************************//**
81816 + @Description Enumeration type for selecting QoS source
81817 +
81818 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
81819 + User should left room for the hash-result on input/output buffer
81820 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
81821 +*//***************************************************************************/
81822 +typedef enum e_FmPcdManipHdrQosSrc {
81823 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
81824 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
81825 +} e_FmPcdManipHdrQosSrc;
81826 +#endif /* (DPAA_VERSION >= 11) */
81827 +
81828 +/**************************************************************************//**
81829 + @Description Enumeration type for selecting type of header insertion
81830 +*//***************************************************************************/
81831 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
81832 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
81833 +#if (DPAA_VERSION >= 11)
81834 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
81835 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
81836 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
81837 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
81838 +#endif /* (DPAA_VERSION >= 11) */
81839 +} e_FmPcdManipHdrInsrtByHdrType;
81840 +
81841 +/**************************************************************************//**
81842 + @Description Enumeration type for selecting specific customCommand
81843 +*//***************************************************************************/
81844 +typedef enum e_FmPcdManipHdrCustomType {
81845 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
81846 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
81847 +} e_FmPcdManipHdrCustomType;
81848 +
81849 +/**************************************************************************//**
81850 + @Description Enumeration type for selecting specific customCommand
81851 +*//***************************************************************************/
81852 +typedef enum e_FmPcdManipHdrCustomIpReplace {
81853 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
81854 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
81855 +} e_FmPcdManipHdrCustomIpReplace;
81856 +
81857 +/**************************************************************************//**
81858 + @Description Enumeration type for selecting type of header removal
81859 +*//***************************************************************************/
81860 +typedef enum e_FmPcdManipHdrRmvByHdrType {
81861 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
81862 +#if (DPAA_VERSION >= 11)
81863 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
81864 +#endif /* (DPAA_VERSION >= 11) */
81865 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81866 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
81867 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81868 +} e_FmPcdManipHdrRmvByHdrType;
81869 +
81870 +/**************************************************************************//**
81871 + @Description Enumeration type for selecting type of timeout mode
81872 +*//***************************************************************************/
81873 +typedef enum e_FmPcdManipReassemTimeOutMode {
81874 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
81875 + from the first fragment to the last */
81876 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
81877 +} e_FmPcdManipReassemTimeOutMode;
81878 +
81879 +/**************************************************************************//**
81880 + @Description Enumeration type for selecting type of WaysNumber mode
81881 +*//***************************************************************************/
81882 +typedef enum e_FmPcdManipReassemWaysNumber {
81883 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
81884 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
81885 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
81886 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
81887 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
81888 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
81889 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
81890 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
81891 +} e_FmPcdManipReassemWaysNumber;
81892 +
81893 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
81894 +/**************************************************************************//**
81895 + @Description Enumeration type for selecting type of statistics mode
81896 +*//***************************************************************************/
81897 +typedef enum e_FmPcdStatsType {
81898 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
81899 +} e_FmPcdStatsType;
81900 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
81901 +
81902 +/**************************************************************************//**
81903 + @Description Enumeration type for selecting manipulation type
81904 +*//***************************************************************************/
81905 +typedef enum e_FmPcdManipType {
81906 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
81907 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
81908 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
81909 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
81910 +} e_FmPcdManipType;
81911 +
81912 +/**************************************************************************//**
81913 + @Description Enumeration type for selecting type of statistics mode
81914 +*//***************************************************************************/
81915 +typedef enum e_FmPcdCcStatsMode {
81916 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
81917 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
81918 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
81919 +#if (DPAA_VERSION >= 11)
81920 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
81921 + This mode is supported only on B4860 device */
81922 +#endif /* (DPAA_VERSION >= 11) */
81923 +} e_FmPcdCcStatsMode;
81924 +
81925 +/**************************************************************************//**
81926 + @Description Enumeration type for determining the action in case an IP packet
81927 + is larger than MTU but its DF (Don't Fragment) bit is set.
81928 +*//***************************************************************************/
81929 +typedef enum e_FmPcdManipDontFragAction {
81930 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
81931 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
81932 + /**< Obsolete, cannot enqueue to error queue;
81933 + In practice, selects to discard packets;
81934 + Will be removed in the future */
81935 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
81936 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
81937 +} e_FmPcdManipDontFragAction;
81938 +
81939 +/**************************************************************************//**
81940 + @Description Enumeration type for selecting type of special offload manipulation
81941 +*//***************************************************************************/
81942 +typedef enum e_FmPcdManipSpecialOffloadType {
81943 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
81944 +#if (DPAA_VERSION >= 11)
81945 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
81946 +#endif /* (DPAA_VERSION >= 11) */
81947 +} e_FmPcdManipSpecialOffloadType;
81948 +
81949 +
81950 +/**************************************************************************//**
81951 + @Description A Union of protocol dependent special options
81952 +*//***************************************************************************/
81953 +typedef union u_FmPcdHdrProtocolOpt {
81954 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
81955 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
81956 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
81957 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
81958 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
81959 +#if (DPAA_VERSION >= 11)
81960 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
81961 +#endif /* (DPAA_VERSION >= 11) */
81962 +} u_FmPcdHdrProtocolOpt;
81963 +
81964 +/**************************************************************************//**
81965 + @Description A union holding protocol fields
81966 +
81967 +
81968 + Fields supported as "full fields":
81969 + HEADER_TYPE_ETH:
81970 + NET_HEADER_FIELD_ETH_DA
81971 + NET_HEADER_FIELD_ETH_SA
81972 + NET_HEADER_FIELD_ETH_TYPE
81973 +
81974 + HEADER_TYPE_LLC_SNAP:
81975 + NET_HEADER_FIELD_LLC_SNAP_TYPE
81976 +
81977 + HEADER_TYPE_VLAN:
81978 + NET_HEADER_FIELD_VLAN_TCI
81979 + (index may apply:
81980 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81981 + e_FM_PCD_HDR_INDEX_LAST)
81982 +
81983 + HEADER_TYPE_MPLS:
81984 + NET_HEADER_FIELD_MPLS_LABEL_STACK
81985 + (index may apply:
81986 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81987 + e_FM_PCD_HDR_INDEX_2,
81988 + e_FM_PCD_HDR_INDEX_LAST)
81989 +
81990 + HEADER_TYPE_IPv4:
81991 + NET_HEADER_FIELD_IPv4_SRC_IP
81992 + NET_HEADER_FIELD_IPv4_DST_IP
81993 + NET_HEADER_FIELD_IPv4_PROTO
81994 + NET_HEADER_FIELD_IPv4_TOS
81995 + (index may apply:
81996 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
81997 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
81998 +
81999 + HEADER_TYPE_IPv6:
82000 + NET_HEADER_FIELD_IPv6_SRC_IP
82001 + NET_HEADER_FIELD_IPv6_DST_IP
82002 + NET_HEADER_FIELD_IPv6_NEXT_HDR
82003 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
82004 + (index may apply:
82005 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82006 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82007 +
82008 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
82009 + the last next header indication, meaning the next L4, which may be
82010 + present at the Ipv6 last extension. On earlier revisions this field
82011 + applies to the Next-Header field of the main IPv6 header)
82012 +
82013 + HEADER_TYPE_IP:
82014 + NET_HEADER_FIELD_IP_PROTO
82015 + (index may apply:
82016 + e_FM_PCD_HDR_INDEX_LAST)
82017 + NET_HEADER_FIELD_IP_DSCP
82018 + (index may apply:
82019 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
82020 + HEADER_TYPE_GRE:
82021 + NET_HEADER_FIELD_GRE_TYPE
82022 +
82023 + HEADER_TYPE_MINENCAP
82024 + NET_HEADER_FIELD_MINENCAP_SRC_IP
82025 + NET_HEADER_FIELD_MINENCAP_DST_IP
82026 + NET_HEADER_FIELD_MINENCAP_TYPE
82027 +
82028 + HEADER_TYPE_TCP:
82029 + NET_HEADER_FIELD_TCP_PORT_SRC
82030 + NET_HEADER_FIELD_TCP_PORT_DST
82031 + NET_HEADER_FIELD_TCP_FLAGS
82032 +
82033 + HEADER_TYPE_UDP:
82034 + NET_HEADER_FIELD_UDP_PORT_SRC
82035 + NET_HEADER_FIELD_UDP_PORT_DST
82036 +
82037 + HEADER_TYPE_UDP_LITE:
82038 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
82039 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
82040 +
82041 + HEADER_TYPE_IPSEC_AH:
82042 + NET_HEADER_FIELD_IPSEC_AH_SPI
82043 + NET_HEADER_FIELD_IPSEC_AH_NH
82044 +
82045 + HEADER_TYPE_IPSEC_ESP:
82046 + NET_HEADER_FIELD_IPSEC_ESP_SPI
82047 +
82048 + HEADER_TYPE_SCTP:
82049 + NET_HEADER_FIELD_SCTP_PORT_SRC
82050 + NET_HEADER_FIELD_SCTP_PORT_DST
82051 +
82052 + HEADER_TYPE_DCCP:
82053 + NET_HEADER_FIELD_DCCP_PORT_SRC
82054 + NET_HEADER_FIELD_DCCP_PORT_DST
82055 +
82056 + HEADER_TYPE_PPPoE:
82057 + NET_HEADER_FIELD_PPPoE_PID
82058 + NET_HEADER_FIELD_PPPoE_SID
82059 +
82060 + *****************************************************************
82061 + Fields supported as "from fields":
82062 + HEADER_TYPE_ETH (with or without validation):
82063 + NET_HEADER_FIELD_ETH_TYPE
82064 +
82065 + HEADER_TYPE_VLAN (with or without validation):
82066 + NET_HEADER_FIELD_VLAN_TCI
82067 + (index may apply:
82068 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82069 + e_FM_PCD_HDR_INDEX_LAST)
82070 +
82071 + HEADER_TYPE_IPv4 (without validation):
82072 + NET_HEADER_FIELD_IPv4_PROTO
82073 + (index may apply:
82074 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82075 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82076 +
82077 + HEADER_TYPE_IPv6 (without validation):
82078 + NET_HEADER_FIELD_IPv6_NEXT_HDR
82079 + (index may apply:
82080 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
82081 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
82082 +
82083 +*//***************************************************************************/
82084 +typedef union t_FmPcdFields {
82085 + headerFieldEth_t eth; /**< Ethernet */
82086 + headerFieldVlan_t vlan; /**< VLAN */
82087 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
82088 + headerFieldPppoe_t pppoe; /**< PPPoE */
82089 + headerFieldMpls_t mpls; /**< MPLS */
82090 + headerFieldIp_t ip; /**< IP */
82091 + headerFieldIpv4_t ipv4; /**< IPv4 */
82092 + headerFieldIpv6_t ipv6; /**< IPv6 */
82093 + headerFieldUdp_t udp; /**< UDP */
82094 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
82095 + headerFieldTcp_t tcp; /**< TCP */
82096 + headerFieldSctp_t sctp; /**< SCTP */
82097 + headerFieldDccp_t dccp; /**< DCCP */
82098 + headerFieldGre_t gre; /**< GRE */
82099 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
82100 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
82101 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
82102 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
82103 +} t_FmPcdFields;
82104 +
82105 +/**************************************************************************//**
82106 + @Description Parameters for defining header extraction for key generation
82107 +*//***************************************************************************/
82108 +typedef struct t_FmPcdFromHdr {
82109 + uint8_t size; /**< Size in byte */
82110 + uint8_t offset; /**< Byte offset */
82111 +} t_FmPcdFromHdr;
82112 +
82113 +/**************************************************************************//**
82114 + @Description Parameters for defining field extraction for key generation
82115 +*//***************************************************************************/
82116 +typedef struct t_FmPcdFromField {
82117 + t_FmPcdFields field; /**< Field selection */
82118 + uint8_t size; /**< Size in byte */
82119 + uint8_t offset; /**< Byte offset */
82120 +} t_FmPcdFromField;
82121 +
82122 +/**************************************************************************//**
82123 + @Description Parameters for defining a single network environment unit
82124 +
82125 + A distinction unit should be defined if it will later be used
82126 + by one or more PCD engines to distinguish between flows.
82127 +*//***************************************************************************/
82128 +typedef struct t_FmPcdDistinctionUnit {
82129 + struct {
82130 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
82131 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
82132 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
82133 +} t_FmPcdDistinctionUnit;
82134 +
82135 +/**************************************************************************//**
82136 + @Description Parameters for defining all different distinction units supported
82137 + by a specific PCD Network Environment Characteristics module.
82138 +
82139 + Each unit represent a protocol or a group of protocols that may
82140 + be used later by the different PCD engines to distinguish
82141 + between flows.
82142 +*//***************************************************************************/
82143 +typedef struct t_FmPcdNetEnvParams {
82144 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
82145 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
82146 + different units to be identified */
82147 +} t_FmPcdNetEnvParams;
82148 +
82149 +/**************************************************************************//**
82150 + @Description Parameters for defining a single extraction action when
82151 + creating a key
82152 +*//***************************************************************************/
82153 +typedef struct t_FmPcdExtractEntry {
82154 + e_FmPcdExtractType type; /**< Extraction type select */
82155 + union {
82156 + struct {
82157 + e_NetHeaderType hdr; /**< Header selection */
82158 + bool ignoreProtocolValidation;
82159 + /**< Ignore protocol validation */
82160 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82161 + IP. Otherwise should be cleared. */
82162 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
82163 + union {
82164 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
82165 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
82166 + t_FmPcdFields fullField; /**< Extract full filed parameters */
82167 + } extractByHdrType;
82168 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82169 + struct {
82170 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
82171 + e_FmPcdAction action; /**< Relevant for CC Only */
82172 + uint16_t icIndxMask; /**< Relevant only for CC when
82173 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
82174 + Note that the number of bits that are set within
82175 + this mask must be log2 of the CC-node 'numOfKeys'.
82176 + Note that the mask cannot be set on the lower bits. */
82177 + uint8_t offset; /**< Byte offset */
82178 + uint8_t size; /**< Size in byte */
82179 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82180 + };
82181 +} t_FmPcdExtractEntry;
82182 +
82183 +/**************************************************************************//**
82184 + @Description Parameters for defining masks for each extracted field in the key.
82185 +*//***************************************************************************/
82186 +typedef struct t_FmPcdKgExtractMask {
82187 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
82188 + uint8_t offset; /**< Byte offset */
82189 + uint8_t mask; /**< A byte mask (selected bits will be used) */
82190 +} t_FmPcdKgExtractMask;
82191 +
82192 +/**************************************************************************//**
82193 + @Description Parameters for defining default selection per groups of fields
82194 +*//***************************************************************************/
82195 +typedef struct t_FmPcdKgExtractDflt {
82196 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
82197 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
82198 +} t_FmPcdKgExtractDflt;
82199 +
82200 +/**************************************************************************//**
82201 + @Description Parameters for defining key extraction and hashing
82202 +*//***************************************************************************/
82203 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
82204 + uint32_t privateDflt0; /**< Scheme default register 0 */
82205 + uint32_t privateDflt1; /**< Scheme default register 1 */
82206 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
82207 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
82208 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
82209 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
82210 + /**< For each extraction used in this scheme, specify the required
82211 + default register to be used when header is not found.
82212 + types not specified in this array will get undefined value. */
82213 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
82214 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
82215 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
82216 + result. 0 means using the 24 LSB's, otherwise use the
82217 + 24 LSB's after shifting right.*/
82218 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
82219 + of queues for the key and hash functionality */
82220 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
82221 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
82222 + destination fields on all layers; If TRUE, driver will check that for
82223 + all layers, if SRC extraction is selected, DST extraction must also be
82224 + selected, and vice versa. */
82225 +} t_FmPcdKgKeyExtractAndHashParams;
82226 +
82227 +/**************************************************************************//**
82228 + @Description Parameters for defining a single FQID mask (extracted OR).
82229 +*//***************************************************************************/
82230 +typedef struct t_FmPcdKgExtractedOrParams {
82231 + e_FmPcdExtractType type; /**< Extraction type select */
82232 + union {
82233 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
82234 + e_NetHeaderType hdr;
82235 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
82236 + IP. Otherwise should be cleared.*/
82237 + bool ignoreProtocolValidation;
82238 + /**< continue extraction even if protocol is not recognized */
82239 + } extractByHdr; /**< Header to extract by */
82240 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
82241 + };
82242 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
82243 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
82244 + field not found */
82245 + uint8_t mask; /**< Extraction mask (specified bits are used) */
82246 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
82247 + the extracted byte; Assume byte is placed as the 8 MSB's in
82248 + a 32 bit word where the lower bits
82249 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
82250 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
82251 + extracted byte will effect the 8 LSB's of the FQID,
82252 + if bitOffsetInFqid=31 than the byte's MSB will effect
82253 + the FQID's LSB; 0 means - no effect on FQID;
82254 + Note that one, and only one of
82255 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82256 + extracted byte must effect either FQID or Policer profile).*/
82257 + uint8_t bitOffsetInPlcrProfile;
82258 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
82259 + effect using the extracted byte; Assume byte is placed
82260 + as the 8 MSB's in a 16 bit word where the lower bits
82261 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
82262 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
82263 + than the extracted byte will effect the whole policer profile id,
82264 + if bitOffsetInFqid=15 than the byte's MSB will effect
82265 + the Policer Profile id's LSB;
82266 + 0 means - no effect on policer profile; Note that one, and only one of
82267 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
82268 + extracted byte must effect either FQID or Policer profile).*/
82269 +} t_FmPcdKgExtractedOrParams;
82270 +
82271 +/**************************************************************************//**
82272 + @Description Parameters for configuring a scheme counter
82273 +*//***************************************************************************/
82274 +typedef struct t_FmPcdKgSchemeCounter {
82275 + bool update; /**< FALSE to keep the current counter state
82276 + and continue from that point, TRUE to update/reset
82277 + the counter when the scheme is written. */
82278 + uint32_t value; /**< If update=TRUE, this value will be written into the
82279 + counter. clear this field to reset the counter. */
82280 +} t_FmPcdKgSchemeCounter;
82281 +
82282 +/**************************************************************************//**
82283 + @Description Parameters for configuring a policer profile for a KeyGen scheme
82284 + (when policer is the next engine after this scheme).
82285 +*//***************************************************************************/
82286 +typedef struct t_FmPcdKgPlcrProfile {
82287 + bool sharedProfile; /**< TRUE if this profile is shared between ports
82288 + (managed by master partition); Must not be TRUE
82289 + if profile is after Coarse Classification*/
82290 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
82291 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
82292 + together with fqidOffsetShift and numOfProfiles
82293 + parameters, to define a range of profiles from
82294 + which the KeyGen result will determine the
82295 + destination policer profile. */
82296 + union {
82297 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
82298 + should indicate the policer profile offset within the
82299 + port's policer profiles or shared window. */
82300 + struct {
82301 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82302 + final FQID - without the FQID base). */
82303 + uint8_t fqidOffsetRelativeProfileIdBase;
82304 + /**< The base of the FMan Port's relative Storage-Profile ID;
82305 + this value will be "OR'ed" with the KeyGen create FQID
82306 + offset (i.e. not the final FQID - without the FQID base);
82307 + the final result should indicate the Storage-Profile offset
82308 + within the FMan Port's relative Storage-Profiles window/
82309 + (or the SHARED window depends on 'sharedProfile'). */
82310 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
82311 + } indirectProfile; /**< Indirect profile parameters */
82312 + } profileSelect; /**< Direct/indirect profile selection and parameters */
82313 +} t_FmPcdKgPlcrProfile;
82314 +
82315 +#if (DPAA_VERSION >= 11)
82316 +/**************************************************************************//**
82317 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
82318 +*//***************************************************************************/
82319 +typedef struct t_FmPcdKgStorageProfile {
82320 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
82321 + profile id;
82322 + If FALSE, fqidOffsetRelativeProfileIdBase is used
82323 + together with fqidOffsetShift and numOfProfiles
82324 + parameters to define a range of profiles from which
82325 + the KeyGen result will determine the destination
82326 + storage profile. */
82327 + union {
82328 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
82329 + should indicate the storage profile offset within the
82330 + port's storage profiles window. */
82331 + struct {
82332 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
82333 + final FQID - without the FQID base). */
82334 + uint8_t fqidOffsetRelativeProfileIdBase;
82335 + /**< The base of the FMan Port's relative Storage-Profile ID;
82336 + this value will be "OR'ed" with the KeyGen create FQID
82337 + offset (i.e. not the final FQID - without the FQID base);
82338 + the final result should indicate the Storage-Profile offset
82339 + within the FMan Port's relative Storage-Profiles window. */
82340 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
82341 + } indirectProfile; /**< Indirect profile parameters. */
82342 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
82343 +} t_FmPcdKgStorageProfile;
82344 +#endif /* (DPAA_VERSION >= 11) */
82345 +
82346 +/**************************************************************************//**
82347 + @Description Parameters for defining CC as the next engine after KeyGen
82348 +*//***************************************************************************/
82349 +typedef struct t_FmPcdKgCc {
82350 + t_Handle h_CcTree; /**< A handle to a CC Tree */
82351 + uint8_t grpId; /**< CC group id within the CC tree */
82352 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
82353 + policing is required. */
82354 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
82355 + selected profile is the one set at port initialization. */
82356 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
82357 + bypassPlcrProfileGeneration = FALSE */
82358 +} t_FmPcdKgCc;
82359 +
82360 +/**************************************************************************//**
82361 + @Description Parameters for defining initializing a KeyGen scheme
82362 +*//***************************************************************************/
82363 +typedef struct t_FmPcdKgSchemeParams {
82364 + bool modify; /**< TRUE to change an existing scheme */
82365 + union
82366 + {
82367 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
82368 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
82369 + } id;
82370 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
82371 + for match vector; KeyGen will ignore it when matching */
82372 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
82373 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82374 + by FM_PCD_NetEnvCharacteristicsSet() */
82375 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
82376 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
82377 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
82378 + } netEnvParams;
82379 + bool useHash; /**< use the KeyGen Hash functionality */
82380 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
82381 + /**< used only if useHash = TRUE */
82382 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
82383 + In such a case FQID after KeyGen will be the default FQID
82384 + defined for the relevant port, or the FQID defined by CC
82385 + in cases where CC was the previous engine. */
82386 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
82387 + If hash is used and an even distribution is expected
82388 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
82389 + hashDistributionNumOfFqids. */
82390 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
82391 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
82392 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
82393 + registers are shared between qidMasks
82394 + functionality and some of the extraction
82395 + actions; Normally only some will be used
82396 + for qidMask. Driver will return error if
82397 + resource is full at initialization time. */
82398 +
82399 +#if (DPAA_VERSION >= 11)
82400 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
82401 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
82402 +#endif /* (DPAA_VERSION >= 11) */
82403 +
82404 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
82405 + union { /**< depends on nextEngine */
82406 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
82407 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
82408 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
82409 + } kgNextEngineParams;
82410 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
82411 + the scheme counter */
82412 +} t_FmPcdKgSchemeParams;
82413 +
82414 +/**************************************************************************//**
82415 + @Collection Definitions for CC statistics
82416 +*//***************************************************************************/
82417 +#if (DPAA_VERSION >= 11)
82418 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
82419 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
82420 +#endif /* (DPAA_VERSION >= 11) */
82421 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
82422 +/* @} */
82423 +
82424 +/**************************************************************************//**
82425 + @Description Parameters for defining CC as the next engine after a CC node.
82426 +*//***************************************************************************/
82427 +typedef struct t_FmPcdCcNextCcParams {
82428 + t_Handle h_CcNode; /**< A handle of the next CC node */
82429 +} t_FmPcdCcNextCcParams;
82430 +
82431 +#if (DPAA_VERSION >= 11)
82432 +/**************************************************************************//**
82433 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
82434 +*//***************************************************************************/
82435 +typedef struct t_FmPcdCcNextFrParams {
82436 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
82437 +} t_FmPcdCcNextFrParams;
82438 +#endif /* (DPAA_VERSION >= 11) */
82439 +
82440 +/**************************************************************************//**
82441 + @Description Parameters for defining Policer as the next engine after a CC node.
82442 +*//***************************************************************************/
82443 +typedef struct t_FmPcdCcNextPlcrParams {
82444 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
82445 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
82446 + TRUE if this profile is shared between ports */
82447 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
82448 + (otherwise profile id is taken from KeyGen);
82449 + This parameter should indicate the policer
82450 + profile offset within the port's
82451 + policer profiles or from SHARED window.*/
82452 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
82453 + FQID for enqueuing the frame;
82454 + In earlier chips if policer next engine is KEYGEN,
82455 + this parameter can be 0, because the KEYGEN
82456 + always decides the enqueue FQID.*/
82457 +#if (DPAA_VERSION >= 11)
82458 + uint8_t newRelativeStorageProfileId;
82459 + /**< Indicates the relative storage profile offset within
82460 + the port's storage profiles window;
82461 + Relevant only if the port was configured with VSP. */
82462 +#endif /* (DPAA_VERSION >= 11) */
82463 +} t_FmPcdCcNextPlcrParams;
82464 +
82465 +/**************************************************************************//**
82466 + @Description Parameters for defining enqueue as the next action after a CC node.
82467 +*//***************************************************************************/
82468 +typedef struct t_FmPcdCcNextEnqueueParams {
82469 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82470 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82471 + relevant if action = e_FM_PCD_ENQ_FRAME */
82472 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82473 + (otherwise FQID is taken from KeyGen),
82474 + relevant if action = e_FM_PCD_ENQ_FRAME */
82475 +#if (DPAA_VERSION >= 11)
82476 + uint8_t newRelativeStorageProfileId;
82477 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82478 + storage profile offset within the port's storage profiles
82479 + window; Relevant only if the port was configured with VSP. */
82480 +#endif /* (DPAA_VERSION >= 11) */
82481 +} t_FmPcdCcNextEnqueueParams;
82482 +
82483 +/**************************************************************************//**
82484 + @Description Parameters for defining KeyGen as the next engine after a CC node.
82485 +*//***************************************************************************/
82486 +typedef struct t_FmPcdCcNextKgParams {
82487 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
82488 + Note - this parameters irrelevant for earlier chips */
82489 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
82490 + (otherwise FQID is taken from KeyGen),
82491 + Note - this parameters irrelevant for earlier chips */
82492 +#if (DPAA_VERSION >= 11)
82493 + uint8_t newRelativeStorageProfileId;
82494 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
82495 + storage profile offset within the port's storage profiles
82496 + window; Relevant only if the port was configured with VSP. */
82497 +#endif /* (DPAA_VERSION >= 11) */
82498 +
82499 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
82500 +} t_FmPcdCcNextKgParams;
82501 +
82502 +/**************************************************************************//**
82503 + @Description Parameters for defining the next engine after a CC node.
82504 +*//***************************************************************************/
82505 +typedef struct t_FmPcdCcNextEngineParams {
82506 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
82507 + according to nextEngine definition */
82508 + union {
82509 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
82510 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
82511 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
82512 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
82513 +#if (DPAA_VERSION >= 11)
82514 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
82515 +#endif /* (DPAA_VERSION >= 11) */
82516 + } params; /**< union used for all the next-engine parameters options */
82517 +
82518 + t_Handle h_Manip; /**< Handle to Manipulation object.
82519 + Relevant if next engine is of type result
82520 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
82521 +
82522 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
82523 + for each frame passing through this
82524 + Coarse Classification entry. */
82525 +} t_FmPcdCcNextEngineParams;
82526 +
82527 +/**************************************************************************//**
82528 + @Description Parameters for defining a single CC key
82529 +*//***************************************************************************/
82530 +typedef struct t_FmPcdCcKeyParams {
82531 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82532 + pointer to the key of the size defined in keySize */
82533 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
82534 + pointer to the Mask per key of the size defined
82535 + in keySize. p_Key and p_Mask (if defined) has to be
82536 + of the same size defined in the keySize;
82537 + NOTE that if this value is equal for all entries whithin
82538 + this table, the driver will automatically use global-mask
82539 + (i.e. one common mask for all entries) instead of private
82540 + one; that is done in order to spare some memory and for
82541 + better performance. */
82542 + t_FmPcdCcNextEngineParams ccNextEngineParams;
82543 + /**< parameters for the next for the defined Key in
82544 + the p_Key */
82545 +} t_FmPcdCcKeyParams;
82546 +
82547 +/**************************************************************************//**
82548 + @Description Parameters for defining CC keys parameters
82549 + The driver supports two methods for CC node allocation: dynamic and static.
82550 + Static mode was created in order to prevent runtime alloc/free
82551 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
82552 + the driver automatically allocates the memory according to
82553 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
82554 + size that may be used for this CC-Node taking into consideration
82555 + 'maskSupport' and 'statisticsMode' parameters.
82556 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
82557 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
82558 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
82559 + all required structures are allocated according to 'numOfKeys'
82560 + parameter. During runtime modification, these structures are
82561 + re-allocated according to the updated number of keys.
82562 +
82563 + Please note that 'action' and 'icIndxMask' mentioned in the
82564 + specific parameter explanations are passed in the extraction
82565 + parameters of the node (fields of extractCcParams.extractNonHdr).
82566 +*//***************************************************************************/
82567 +typedef struct t_KeysParams {
82568 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
82569 + A value of zero may be used for dynamic memory allocation. */
82570 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
82571 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
82572 + Should be TRUE to reserve table memory for key masks, even if
82573 + initial keys do not contain masks, or if the node was initialized
82574 + as 'empty' (without keys); this will allow user to add keys with
82575 + masks at runtime.
82576 + NOTE that if user want to use only global-masks (i.e. one common mask
82577 + for all the entries within this table, this parameter should set to 'FALSE'. */
82578 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
82579 + To enable statistics gathering, statistics should be enabled per
82580 + every key, using 'statisticsEn' in next engine parameters structure
82581 + of that key;
82582 + If 'maxNumOfKeys' is set, all required structures will be
82583 + preallocated for all keys. */
82584 +#if (DPAA_VERSION >= 11)
82585 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82586 + /**< Relevant only for 'RMON' statistics mode
82587 + (this feature is supported only on B4860 device);
82588 + Holds a list of programmable thresholds - for each received frame,
82589 + its length in bytes is examined against these range thresholds and
82590 + the appropriate counter is incremented by 1 - for example, to belong
82591 + to range i, the following should hold:
82592 + range i-1 threshold < frame length <= range i threshold
82593 + Each range threshold must be larger then its preceding range
82594 + threshold, and last range threshold must be 0xFFFF. */
82595 +#endif /* (DPAA_VERSION >= 11) */
82596 + uint16_t numOfKeys; /**< Number of initial keys;
82597 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
82598 + this field should be power-of-2 of the number of bits that are
82599 + set in 'icIndxMask'. */
82600 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
82601 + to be the standard size of the selected key; For other extraction
82602 + types, 'keySize' has to be as size of extraction; When 'action' =
82603 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
82604 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
82605 + /**< An array with 'numOfKeys' entries, each entry specifies the
82606 + corresponding key parameters;
82607 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
82608 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
82609 + for the 'miss' entry. */
82610 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
82611 + /**< Parameters for defining the next engine when a key is not matched;
82612 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
82613 +} t_KeysParams;
82614 +
82615 +
82616 +/**************************************************************************//**
82617 + @Description Parameters for defining a CC node
82618 +*//***************************************************************************/
82619 +typedef struct t_FmPcdCcNodeParams {
82620 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
82621 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
82622 +} t_FmPcdCcNodeParams;
82623 +
82624 +/**************************************************************************//**
82625 + @Description Parameters for defining a hash table
82626 +*//***************************************************************************/
82627 +typedef struct t_FmPcdHashTableParams {
82628 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
82629 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
82630 + requested statistics mode will be allocated according to maxNumOfKeys. */
82631 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
82632 + that leads to this hash-table. */
82633 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
82634 + The number-of-sets for this hash will be calculated
82635 + as (2^(number of bits set in 'hashResMask'));
82636 + The 4 lower bits must be cleared. */
82637 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
82638 + 2-bytes to be used as hash index. */
82639 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
82640 +
82641 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
82642 +
82643 +} t_FmPcdHashTableParams;
82644 +
82645 +/**************************************************************************//**
82646 + @Description Parameters for defining a CC tree group.
82647 +
82648 + This structure defines a CC group in terms of NetEnv units
82649 + and the action to be taken in each case. The unitIds list must
82650 + be given in order from low to high indices.
82651 +
82652 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
82653 + structures where each defines the next action to be taken for
82654 + each units combination. for example:
82655 + numOfDistinctionUnits = 2
82656 + unitIds = {1,3}
82657 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
82658 + unit 1 - not found; unit 3 - not found;
82659 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
82660 + unit 1 - not found; unit 3 - found;
82661 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
82662 + unit 1 - found; unit 3 - not found;
82663 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
82664 + unit 1 - found; unit 3 - found;
82665 +*//***************************************************************************/
82666 +typedef struct t_FmPcdCcGrpParams {
82667 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
82668 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
82669 + /**< Indices of the units as defined in
82670 + FM_PCD_NetEnvCharacteristicsSet() */
82671 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
82672 + /**< Maximum entries per group is 16 */
82673 +} t_FmPcdCcGrpParams;
82674 +
82675 +/**************************************************************************//**
82676 + @Description Parameters for defining CC tree groups
82677 +*//***************************************************************************/
82678 +typedef struct t_FmPcdCcTreeParams {
82679 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
82680 + by FM_PCD_NetEnvCharacteristicsSet() */
82681 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
82682 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
82683 + /**< Parameters for each group. */
82684 +} t_FmPcdCcTreeParams;
82685 +
82686 +
82687 +/**************************************************************************//**
82688 + @Description CC key statistics structure
82689 +*//***************************************************************************/
82690 +typedef struct t_FmPcdCcKeyStatistics {
82691 + uint32_t byteCount; /**< This counter reflects byte count of frames that
82692 + were matched by this key. */
82693 + uint32_t frameCount; /**< This counter reflects count of frames that
82694 + were matched by this key. */
82695 +#if (DPAA_VERSION >= 11)
82696 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
82697 + /**< These counters reflect how many frames matched
82698 + this key in 'RMON' statistics mode:
82699 + Each counter holds the number of frames of a
82700 + specific frames length range, according to the
82701 + ranges provided at initialization. */
82702 +#endif /* (DPAA_VERSION >= 11) */
82703 +} t_FmPcdCcKeyStatistics;
82704 +
82705 +/**************************************************************************//**
82706 + @Description Parameters for defining policer byte rate
82707 +*//***************************************************************************/
82708 +typedef struct t_FmPcdPlcrByteRateModeParams {
82709 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
82710 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
82711 + e_FM_PCD_PLCR_FULL_FRM_LEN */
82712 +} t_FmPcdPlcrByteRateModeParams;
82713 +
82714 +/**************************************************************************//**
82715 + @Description Parameters for defining the policer profile (based on
82716 + RFC-2698 or RFC-4115 attributes).
82717 +*//***************************************************************************/
82718 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
82719 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
82720 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
82721 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
82722 + uint32_t committedBurstSize; /**< Bytes/Packets */
82723 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
82724 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
82725 +} t_FmPcdPlcrNonPassthroughAlgParams;
82726 +
82727 +/**************************************************************************//**
82728 + @Description Parameters for defining the next engine after policer
82729 +*//***************************************************************************/
82730 +typedef union u_FmPcdPlcrNextEngineParams {
82731 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
82732 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
82733 + is Policer, must be a SHARED profile */
82734 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
82735 +} u_FmPcdPlcrNextEngineParams;
82736 +
82737 +/**************************************************************************//**
82738 + @Description Parameters for defining the policer profile entry
82739 +*//***************************************************************************/
82740 +typedef struct t_FmPcdPlcrProfileParams {
82741 + bool modify; /**< TRUE to change an existing profile */
82742 + union {
82743 + struct {
82744 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
82745 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
82746 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
82747 + } newParams; /**< use it when modify = FALSE */
82748 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
82749 + } id;
82750 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
82751 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
82752 +
82753 + union {
82754 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
82755 + any incoming packet with the default value. */
82756 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
82757 + pre-color value of 2'b11. */
82758 + } color;
82759 +
82760 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
82761 +
82762 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
82763 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
82764 +
82765 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
82766 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
82767 +
82768 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
82769 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
82770 +
82771 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
82772 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
82773 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
82774 +} t_FmPcdPlcrProfileParams;
82775 +
82776 +/**************************************************************************//**
82777 + @Description Parameters for selecting a location for requested manipulation
82778 +*//***************************************************************************/
82779 +typedef struct t_FmManipHdrInfo {
82780 + e_NetHeaderType hdr; /**< Header selection */
82781 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
82782 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
82783 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
82784 +} t_FmManipHdrInfo;
82785 +
82786 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82787 +/**************************************************************************//**
82788 + @Description Parameters for defining an insertion manipulation
82789 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
82790 +*//***************************************************************************/
82791 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
82792 + uint8_t size; /**< Size of insert template to the start of the frame. */
82793 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
82794 + /**< Array of the insertion template. */
82795 +
82796 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
82797 + struct {
82798 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
82799 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
82800 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
82801 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
82802 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
82803 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
82804 + bool recalculateLength; /**< TRUE if recalculate length has to be performed due to the engines in the path which can change the frame later, relevant if modifyOuterIp = TRUE.*/
82805 + struct {
82806 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
82807 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
82808 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
82809 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
82810 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
82811 +
82812 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
82813 + struct {
82814 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
82815 + VPri only 3 bits, it has to be adjusted to the right*/
82816 + } modifyOuterVlanParams;
82817 +} t_FmPcdManipHdrInsrtByTemplateParams;
82818 +
82819 +/**************************************************************************//**
82820 + @Description Parameters for defining CAPWAP fragmentation
82821 +*//***************************************************************************/
82822 +typedef struct t_CapwapFragmentationParams {
82823 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
82824 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
82825 + and all other fragments exclude the CAPWAP options field,
82826 + FALSE - all fragments include CAPWAP header options field. */
82827 +} t_CapwapFragmentationParams;
82828 +
82829 +/**************************************************************************//**
82830 + @Description Parameters for defining CAPWAP reassembly
82831 +*//***************************************************************************/
82832 +typedef struct t_CapwapReassemblyParams {
82833 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
82834 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82835 + maxNumFramesInProcess has to be in the range of 4 - 512,
82836 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82837 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
82838 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
82839 + and all processed fragments will be enqueued with error indication;
82840 + If FALSE, only duplicated fragments will be enqueued with error indication. */
82841 +
82842 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
82843 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
82844 + uint32_t timeoutRoutineRequestTime;
82845 + /**< Represents the time interval in microseconds between consecutive
82846 + timeout routine requests It has to be power of 2. */
82847 + uint32_t timeoutThresholdForReassmProcess;
82848 + /**< Time interval (microseconds) for marking frames in process as too old;
82849 + Frames in process are those for which at least one fragment was received
82850 + but not all fragments. */
82851 +
82852 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
82853 +} t_CapwapReassemblyParams;
82854 +
82855 +/**************************************************************************//**
82856 + @Description Parameters for defining fragmentation/reassembly manipulation
82857 +*//***************************************************************************/
82858 +typedef struct t_FmPcdManipFragOrReasmParams {
82859 + bool frag; /**< TRUE if using the structure for fragmentation,
82860 + otherwise this structure is used for reassembly */
82861 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82862 + Same LIODN number is used for these buffers as for
82863 + the received frames buffers, so buffers of this pool
82864 + need to be allocated in the same memory area as the
82865 + received buffers. If the received buffers arrive
82866 + from different sources, the Scatter/Gather BP id
82867 + should be mutual to all these sources. */
82868 + e_NetHeaderType hdr; /**< Header selection */
82869 + union {
82870 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
82871 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
82872 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
82873 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
82874 + } u;
82875 +} t_FmPcdManipFragOrReasmParams;
82876 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
82877 +
82878 +
82879 +/**************************************************************************//**
82880 + @Description Parameters for defining header removal by header type
82881 +*//***************************************************************************/
82882 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
82883 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
82884 + union {
82885 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
82886 + struct {
82887 + bool include; /**< If FALSE, remove until the specified header (not including the header);
82888 + If TRUE, remove also the specified header. */
82889 + t_FmManipHdrInfo hdrInfo;
82890 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82891 +#endif /* (DPAA_VERSION >= 11) || ... */
82892 +#if (DPAA_VERSION >= 11)
82893 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
82894 +#endif /* (DPAA_VERSION >= 11) */
82895 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
82896 + Defines which L2 headers to remove. */
82897 + } u;
82898 +} t_FmPcdManipHdrRmvByHdrParams;
82899 +
82900 +/**************************************************************************//**
82901 + @Description Parameters for configuring IP fragmentation manipulation
82902 +
82903 + Restrictions:
82904 + - IP Fragmentation output fragments must not be forwarded to application directly.
82905 + - Maximum number of fragments per frame is 16.
82906 + - Fragmentation of IP fragments is not supported.
82907 + - IPv4 packets containing header Option fields are fragmented by copying all option
82908 + fields to each fragment, regardless of the copy bit value.
82909 + - Transmit confirmation is not supported.
82910 + - Fragmentation after SEC can't handle S/G frames.
82911 + - Fragmentation nodes must be set as the last PCD action (i.e. the
82912 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
82913 + - Only BMan buffers shall be used for frames to be fragmented.
82914 + - IPF does not support VSP. Therefore, on the same port where we have IPF
82915 + we cannot support VSP.
82916 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
82917 + does not support VSP. Therefore, on the same port where we have IPF we
82918 + cannot support VSP.
82919 +*//***************************************************************************/
82920 +typedef struct t_FmPcdManipFragIpParams {
82921 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
82922 + IP fragmentation will be executed.*/
82923 +#if (DPAA_VERSION == 10)
82924 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
82925 +#endif /* (DPAA_VERSION == 10) */
82926 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
82927 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
82928 + received frame's buffer. */
82929 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
82930 + This parameters is relevant when 'sgBpidEn=TRUE';
82931 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
82932 + of this pool need to be allocated in the same memory area as the received buffers.
82933 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
82934 + mutual to all these sources. */
82935 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
82936 + than MTU and its DF bit is set, then this field will
82937 + determine the action to be taken.*/
82938 +} t_FmPcdManipFragIpParams;
82939 +
82940 +/**************************************************************************//**
82941 + @Description Parameters for configuring IP reassembly manipulation.
82942 +
82943 + This is a common structure for both IPv4 and IPv6 reassembly
82944 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
82945 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
82946 +
82947 + Restrictions:
82948 + - Application must define at least one scheme to catch the reassembled frames.
82949 + - Maximum number of fragments per frame is 16.
82950 + - Reassembly of IPv4 fragments containing Option fields is supported.
82951 +
82952 +*//***************************************************************************/
82953 +typedef struct t_FmPcdManipReassemIpParams {
82954 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
82955 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
82956 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
82957 + NOTE: The following comment is relevant only for FMAN v2 devices:
82958 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
82959 + the user schemes id to ensure that the reassembly schemes will be first match;
82960 + Rest schemes, if defined, should have higher relative scheme ID. */
82961 +#if (DPAA_VERSION >= 11)
82962 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
82963 + profile than the opening fragment (Non-Consistent-SP state)
82964 + then one of two possible scenarios occurs:
82965 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
82966 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
82967 +#else
82968 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
82969 +#endif /* (DPAA_VERSION >= 11) */
82970 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
82971 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
82972 + uint16_t minFragSize[2]; /**< Minimum fragment size:
82973 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
82974 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
82975 + /**< Number of frames per hash entry needed for reassembly process:
82976 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
82977 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
82978 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
82979 + Must be power of 2;
82980 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
82981 + maxNumFramesInProcess has to be in the range of 4 - 512;
82982 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
82983 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
82984 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
82985 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
82986 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
82987 + uint32_t timeoutThresholdForReassmProcess;
82988 + /**< Represents the time interval in microseconds which defines
82989 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
82990 +} t_FmPcdManipReassemIpParams;
82991 +
82992 +/**************************************************************************//**
82993 + @Description structure for defining IPSEC manipulation
82994 +*//***************************************************************************/
82995 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
82996 + bool decryption; /**< TRUE if being used in decryption direction;
82997 + FALSE if being used in encryption direction. */
82998 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
82999 + (direction depends on the 'decryption' field). */
83000 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
83001 + (direction depends on the 'decryption' field). */
83002 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
83003 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
83004 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
83005 + It is specifies the length of the outer IP header that was configured in the
83006 + corresponding SA. */
83007 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
83008 + The value must be a multiplication of 16 */
83009 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
83010 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
83011 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
83012 +} t_FmPcdManipSpecialOffloadIPSecParams;
83013 +
83014 +#if (DPAA_VERSION >= 11)
83015 +/**************************************************************************//**
83016 + @Description Parameters for configuring CAPWAP fragmentation manipulation
83017 +
83018 + Restrictions:
83019 + - Maximum number of fragments per frame is 16.
83020 + - Transmit confirmation is not supported.
83021 + - Fragmentation nodes must be set as the last PCD action (i.e. the
83022 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
83023 + - Only BMan buffers shall be used for frames to be fragmented.
83024 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
83025 + does not support VSP. Therefore, on the same port where we have IPF we
83026 + cannot support VSP.
83027 +*//***************************************************************************/
83028 +typedef struct t_FmPcdManipFragCapwapParams {
83029 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
83030 + CAPWAP fragmentation will be executed.*/
83031 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
83032 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
83033 + received frame's buffer. */
83034 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
83035 + This parameters is relevant when 'sgBpidEn=TRUE';
83036 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
83037 + of this pool need to be allocated in the same memory area as the received buffers.
83038 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
83039 + mutual to all these sources. */
83040 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
83041 + When this mode is enabled then only the first fragment include the CAPWAP header options
83042 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
83043 + options field (CAPWAP header is updated accordingly).*/
83044 +} t_FmPcdManipFragCapwapParams;
83045 +
83046 +/**************************************************************************//**
83047 + @Description Parameters for configuring CAPWAP reassembly manipulation.
83048 +
83049 + Restrictions:
83050 + - Application must define one scheme to catch the reassembled frames.
83051 + - Maximum number of fragments per frame is 16.
83052 +
83053 +*//***************************************************************************/
83054 +typedef struct t_FmPcdManipReassemCapwapParams {
83055 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
83056 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
83057 + Rest schemes, if defined, should have higher relative scheme ID. */
83058 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
83059 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
83060 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
83061 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
83062 + considered as a valid length;
83063 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
83064 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
83065 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
83066 + /**< Number of frames per hash entry needed for reassembly process */
83067 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
83068 + Must be power of 2;
83069 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
83070 + maxNumFramesInProcess has to be in the range of 4 - 512;
83071 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
83072 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
83073 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
83074 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
83075 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
83076 + uint32_t timeoutThresholdForReassmProcess;
83077 + /**< Represents the time interval in microseconds which defines
83078 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
83079 +} t_FmPcdManipReassemCapwapParams;
83080 +
83081 +/**************************************************************************//**
83082 + @Description structure for defining CAPWAP manipulation
83083 +*//***************************************************************************/
83084 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
83085 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
83086 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
83087 +} t_FmPcdManipSpecialOffloadCapwapParams;
83088 +
83089 +#endif /* (DPAA_VERSION >= 11) */
83090 +
83091 +
83092 +/**************************************************************************//**
83093 + @Description Parameters for defining special offload manipulation
83094 +*//***************************************************************************/
83095 +typedef struct t_FmPcdManipSpecialOffloadParams {
83096 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
83097 + union
83098 + {
83099 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
83100 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
83101 +#if (DPAA_VERSION >= 11)
83102 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
83103 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
83104 +#endif /* (DPAA_VERSION >= 11) */
83105 + } u;
83106 +} t_FmPcdManipSpecialOffloadParams;
83107 +
83108 +/**************************************************************************//**
83109 + @Description Parameters for defining insertion manipulation
83110 +*//***************************************************************************/
83111 +typedef struct t_FmPcdManipHdrInsrt {
83112 + uint8_t size; /**< size of inserted section */
83113 + uint8_t *p_Data; /**< data to be inserted */
83114 +} t_FmPcdManipHdrInsrt;
83115 +
83116 +
83117 +/**************************************************************************//**
83118 + @Description Parameters for defining generic removal manipulation
83119 +*//***************************************************************************/
83120 +typedef struct t_FmPcdManipHdrRmvGenericParams {
83121 + uint8_t offset; /**< Offset from beginning of header to the start
83122 + location of the removal */
83123 + uint8_t size; /**< Size of removed section */
83124 +} t_FmPcdManipHdrRmvGenericParams;
83125 +
83126 +/**************************************************************************//**
83127 + @Description Parameters for defining generic insertion manipulation
83128 +*//***************************************************************************/
83129 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
83130 + uint8_t offset; /**< Offset from beginning of header to the start
83131 + location of the insertion */
83132 + uint8_t size; /**< Size of inserted section */
83133 + bool replace; /**< TRUE to override (replace) existing data at
83134 + 'offset', FALSE to insert */
83135 + uint8_t *p_Data; /**< Pointer to data to be inserted */
83136 +} t_FmPcdManipHdrInsrtGenericParams;
83137 +
83138 +/**************************************************************************//**
83139 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
83140 +*//***************************************************************************/
83141 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
83142 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
83143 + /**< A table of VPri values for each DSCP value;
83144 + The index is the DSCP value (0-0x3F) and the
83145 + value is the corresponding VPRI (0-15). */
83146 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
83147 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
83148 + this field is the Q Tag default value if the
83149 + IP header is not found. */
83150 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
83151 +
83152 +/**************************************************************************//**
83153 + @Description Parameters for defining header manipulation VLAN fields updates
83154 +*//***************************************************************************/
83155 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
83156 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
83157 + union {
83158 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
83159 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
83160 + is the new VLAN pri. */
83161 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
83162 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
83163 + } u;
83164 +} t_FmPcdManipHdrFieldUpdateVlan;
83165 +
83166 +/**************************************************************************//**
83167 + @Description Parameters for defining header manipulation IPV4 fields updates
83168 +*//***************************************************************************/
83169 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
83170 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83171 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
83172 + HDR_MANIP_IPV4_TOS */
83173 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
83174 + contains HDR_MANIP_IPV4_ID */
83175 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
83176 + contains HDR_MANIP_IPV4_SRC */
83177 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
83178 + contains HDR_MANIP_IPV4_DST */
83179 +} t_FmPcdManipHdrFieldUpdateIpv4;
83180 +
83181 +/**************************************************************************//**
83182 + @Description Parameters for defining header manipulation IPV6 fields updates
83183 +*//***************************************************************************/
83184 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
83185 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83186 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
83187 + HDR_MANIP_IPV6_TC */
83188 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83189 + /**< 16 byte new IP SRC; Relevant only if validUpdates
83190 + contains HDR_MANIP_IPV6_SRC */
83191 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
83192 + /**< 16 byte new IP DST; Relevant only if validUpdates
83193 + contains HDR_MANIP_IPV6_DST */
83194 +} t_FmPcdManipHdrFieldUpdateIpv6;
83195 +
83196 +/**************************************************************************//**
83197 + @Description Parameters for defining header manipulation TCP/UDP fields updates
83198 +*//***************************************************************************/
83199 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
83200 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
83201 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
83202 + contains HDR_MANIP_TCP_UDP_SRC */
83203 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
83204 + contains HDR_MANIP_TCP_UDP_DST */
83205 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
83206 +
83207 +/**************************************************************************//**
83208 + @Description Parameters for defining header manipulation fields updates
83209 +*//***************************************************************************/
83210 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
83211 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
83212 + union {
83213 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
83214 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
83215 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
83216 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
83217 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
83218 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
83219 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
83220 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
83221 + } u;
83222 +} t_FmPcdManipHdrFieldUpdateParams;
83223 +
83224 +
83225 +
83226 +/**************************************************************************//**
83227 + @Description Parameters for defining custom header manipulation for generic field replacement
83228 +*//***************************************************************************/
83229 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
83230 + uint8_t srcOffset; /**< Location of new data - Offset from
83231 + Parse Result (>= 16, srcOffset+size <= 32, ) */
83232 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
83233 + start of frame (dstOffset + size <= 256). */
83234 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
83235 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
83236 + replacement (1 - bit will be replaced);
83237 + Clear to use field as is. */
83238 + uint8_t maskOffset; /**< Relevant if mask != 0;
83239 + Mask offset within the replaces "size" */
83240 +} t_FmPcdManipHdrCustomGenFieldReplace;
83241 +
83242 +/**************************************************************************//**
83243 + @Description Parameters for defining custom header manipulation for IP replacement
83244 +*//***************************************************************************/
83245 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
83246 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
83247 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
83248 + bool updateIpv4Id; /**< Relevant when replaceType =
83249 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
83250 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
83251 + updateIpv4Id = TRUE */
83252 + uint8_t hdrSize; /**< The size of the new IP header */
83253 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
83254 + /**< The new IP header */
83255 +} t_FmPcdManipHdrCustomIpHdrReplace;
83256 +
83257 +/**************************************************************************//**
83258 + @Description Parameters for defining custom header manipulation
83259 +*//***************************************************************************/
83260 +typedef struct t_FmPcdManipHdrCustomParams {
83261 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
83262 + union {
83263 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
83264 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
83265 + } u;
83266 +} t_FmPcdManipHdrCustomParams;
83267 +
83268 +/**************************************************************************//**
83269 + @Description Parameters for defining specific L2 insertion manipulation
83270 +*//***************************************************************************/
83271 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
83272 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
83273 + bool update; /**< TRUE to update MPLS header */
83274 + uint8_t size; /**< size of inserted section */
83275 + uint8_t *p_Data; /**< data to be inserted */
83276 +} t_FmPcdManipHdrInsrtSpecificL2Params;
83277 +
83278 +#if (DPAA_VERSION >= 11)
83279 +/**************************************************************************//**
83280 + @Description Parameters for defining IP insertion manipulation
83281 +*//***************************************************************************/
83282 +typedef struct t_FmPcdManipHdrInsrtIpParams {
83283 + bool calcL4Checksum; /**< Calculate L4 checksum. */
83284 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
83285 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
83286 + the inserted header */
83287 + uint16_t id; /**< 16 bit New IP ID */
83288 + bool dontFragOverwrite;
83289 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
83290 + * This byte is configured to be overwritten when RPD is set. */
83291 + uint8_t lastDstOffset;
83292 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
83293 + * in order to calculate UDP checksum pseudo header;
83294 + * Otherwise set it to '0'. */
83295 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
83296 +} t_FmPcdManipHdrInsrtIpParams;
83297 +#endif /* (DPAA_VERSION >= 11) */
83298 +
83299 +/**************************************************************************//**
83300 + @Description Parameters for defining header insertion manipulation by header type
83301 +*//***************************************************************************/
83302 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
83303 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
83304 + union {
83305 +
83306 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
83307 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
83308 + Selects which L2 headers to insert */
83309 +#if (DPAA_VERSION >= 11)
83310 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
83311 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
83312 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
83313 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
83314 +#endif /* (DPAA_VERSION >= 11) */
83315 + } u;
83316 +} t_FmPcdManipHdrInsrtByHdrParams;
83317 +
83318 +/**************************************************************************//**
83319 + @Description Parameters for defining header insertion manipulation
83320 +*//***************************************************************************/
83321 +typedef struct t_FmPcdManipHdrInsrtParams {
83322 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
83323 + union {
83324 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
83325 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
83326 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
83327 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
83328 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83329 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
83330 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
83331 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83332 + } u;
83333 +} t_FmPcdManipHdrInsrtParams;
83334 +
83335 +/**************************************************************************//**
83336 + @Description Parameters for defining header removal manipulation
83337 +*//***************************************************************************/
83338 +typedef struct t_FmPcdManipHdrRmvParams {
83339 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
83340 + union {
83341 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
83342 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
83343 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
83344 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
83345 + } u;
83346 +} t_FmPcdManipHdrRmvParams;
83347 +
83348 +/**************************************************************************//**
83349 + @Description Parameters for defining header manipulation node
83350 +*//***************************************************************************/
83351 +typedef struct t_FmPcdManipHdrParams {
83352 + bool rmv; /**< TRUE, to define removal manipulation */
83353 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
83354 +
83355 + bool insrt; /**< TRUE, to define insertion manipulation */
83356 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
83357 +
83358 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
83359 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
83360 +
83361 + bool custom; /**< TRUE, to define custom manipulation */
83362 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
83363 +
83364 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
83365 + Restrictions:
83366 + 1. MUST be set if the next engine after the CC is not another CC node
83367 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
83368 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
83369 + also never pointed as h_NextManip of other manipulation nodes)
83370 + 2. MUST be set if the next engine after the CC is another CC node, and
83371 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
83372 +} t_FmPcdManipHdrParams;
83373 +
83374 +/**************************************************************************//**
83375 + @Description Parameters for defining fragmentation manipulation
83376 +*//***************************************************************************/
83377 +typedef struct t_FmPcdManipFragParams {
83378 + e_NetHeaderType hdr; /**< Header selection */
83379 + union {
83380 +#if (DPAA_VERSION >= 11)
83381 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
83382 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83383 +#endif /* (DPAA_VERSION >= 11) */
83384 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
83385 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83386 + } u;
83387 +} t_FmPcdManipFragParams;
83388 +
83389 +/**************************************************************************//**
83390 + @Description Parameters for defining reassembly manipulation
83391 +*//***************************************************************************/
83392 +typedef struct t_FmPcdManipReassemParams {
83393 + e_NetHeaderType hdr; /**< Header selection */
83394 + union {
83395 +#if (DPAA_VERSION >= 11)
83396 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
83397 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
83398 +#endif /* (DPAA_VERSION >= 11) */
83399 +
83400 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
83401 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
83402 + } u;
83403 +} t_FmPcdManipReassemParams;
83404 +
83405 +/**************************************************************************//**
83406 + @Description Parameters for defining a manipulation node
83407 +*//***************************************************************************/
83408 +typedef struct t_FmPcdManipParams {
83409 + e_FmPcdManipType type; /**< Selects type of manipulation node */
83410 + union{
83411 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
83412 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
83413 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
83414 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
83415 + } u;
83416 +
83417 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
83418 + Handle to another (previously defined) manipulation node;
83419 + Allows concatenation of manipulation actions;
83420 + This parameter is optional and may be NULL. */
83421 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83422 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
83423 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
83424 + relevant if fragOrReasm = TRUE */
83425 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83426 +} t_FmPcdManipParams;
83427 +
83428 +/**************************************************************************//**
83429 + @Description Structure for retrieving IP reassembly statistics
83430 +*//***************************************************************************/
83431 +typedef struct t_FmPcdManipReassemIpStats {
83432 + /* common counters for both IPv4 and IPv6 */
83433 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83434 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83435 + a Reassembly Frame Descriptor */
83436 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83437 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83438 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83439 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83440 +#if (DPAA_VERSION >= 11)
83441 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
83442 + successfully reassembled frames */
83443 +#endif /* (DPAA_VERSION >= 11) */
83444 + struct {
83445 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83446 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83447 + have been processed for all frames */
83448 + uint32_t processedFragments; /**< Counts the number of processed fragments
83449 + (valid and error fragments) for all frames */
83450 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83451 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83452 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83453 + to access an IP-Reassembly Automatic Learning Hash set */
83454 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83455 + exceeds 16 */
83456 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
83457 +} t_FmPcdManipReassemIpStats;
83458 +
83459 +/**************************************************************************//**
83460 + @Description Structure for retrieving IP fragmentation statistics
83461 +*//***************************************************************************/
83462 +typedef struct t_FmPcdManipFragIpStats {
83463 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83464 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83465 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83466 +} t_FmPcdManipFragIpStats;
83467 +
83468 +#if (DPAA_VERSION >= 11)
83469 +/**************************************************************************//**
83470 + @Description Structure for retrieving CAPWAP reassembly statistics
83471 +*//***************************************************************************/
83472 +typedef struct t_FmPcdManipReassemCapwapStats {
83473 + uint32_t timeout; /**< Counts the number of timeout occurrences */
83474 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
83475 + a Reassembly Frame Descriptor */
83476 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
83477 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
83478 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
83479 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
83480 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
83481 + uint32_t validFragments; /**< Counts the total number of valid fragments that
83482 + have been processed for all frames */
83483 + uint32_t processedFragments; /**< Counts the number of processed fragments
83484 + (valid and error fragments) for all frames */
83485 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
83486 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
83487 + to access an Reassembly Automatic Learning Hash set */
83488 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
83489 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
83490 + exceeds 16 */
83491 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
83492 + length exceeds MaxReassembledFrameLength value */
83493 +} t_FmPcdManipReassemCapwapStats;
83494 +
83495 +/**************************************************************************//**
83496 + @Description Structure for retrieving CAPWAP fragmentation statistics
83497 +*//***************************************************************************/
83498 +typedef struct t_FmPcdManipFragCapwapStats {
83499 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
83500 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
83501 + uint32_t generatedFragments; /**< Number of fragments that were generated */
83502 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83503 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
83504 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
83505 +} t_FmPcdManipFragCapwapStats;
83506 +#endif /* (DPAA_VERSION >= 11) */
83507 +
83508 +/**************************************************************************//**
83509 + @Description Structure for retrieving reassembly statistics
83510 +*//***************************************************************************/
83511 +typedef struct t_FmPcdManipReassemStats {
83512 + union {
83513 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
83514 +#if (DPAA_VERSION >= 11)
83515 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
83516 +#endif /* (DPAA_VERSION >= 11) */
83517 + } u;
83518 +} t_FmPcdManipReassemStats;
83519 +
83520 +/**************************************************************************//**
83521 + @Description Structure for retrieving fragmentation statistics
83522 +*//***************************************************************************/
83523 +typedef struct t_FmPcdManipFragStats {
83524 + union {
83525 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
83526 +#if (DPAA_VERSION >= 11)
83527 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
83528 +#endif /* (DPAA_VERSION >= 11) */
83529 + } u;
83530 +} t_FmPcdManipFragStats;
83531 +
83532 +/**************************************************************************//**
83533 + @Description Structure for selecting manipulation statistics
83534 +*//***************************************************************************/
83535 +typedef struct t_FmPcdManipStats {
83536 + union {
83537 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
83538 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
83539 + } u;
83540 +} t_FmPcdManipStats;
83541 +
83542 +#if (DPAA_VERSION >= 11)
83543 +/**************************************************************************//**
83544 + @Description Parameters for defining frame replicator group and its members
83545 +*//***************************************************************************/
83546 +typedef struct t_FmPcdFrmReplicGroupParams {
83547 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
83548 + Must be at least 2. */
83549 + uint8_t numOfEntries; /**< Number of members in the group;
83550 + Must be at least 1. */
83551 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
83552 + /**< Array of members' parameters */
83553 +} t_FmPcdFrmReplicGroupParams;
83554 +#endif /* (DPAA_VERSION >= 11) */
83555 +
83556 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83557 +/**************************************************************************//**
83558 + @Description structure for defining statistics node
83559 +*//***************************************************************************/
83560 +typedef struct t_FmPcdStatsParams {
83561 + e_FmPcdStatsType type; /**< type of statistics node */
83562 +} t_FmPcdStatsParams;
83563 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83564 +
83565 +/**************************************************************************//**
83566 + @Function FM_PCD_NetEnvCharacteristicsSet
83567 +
83568 + @Description Define a set of Network Environment Characteristics.
83569 +
83570 + When setting an environment it is important to understand its
83571 + application. It is not meant to describe the flows that will run
83572 + on the ports using this environment, but what the user means TO DO
83573 + with the PCD mechanisms in order to parse-classify-distribute those
83574 + frames.
83575 + By specifying a distinction unit, the user means it would use that option
83576 + for distinction between frames at either a KeyGen scheme or a coarse
83577 + classification action descriptor. Using interchangeable headers to define a
83578 + unit means that the user is indifferent to which of the interchangeable
83579 + headers is present in the frame, and wants the distinction to be based
83580 + on the presence of either one of them.
83581 +
83582 + Depending on context, there are limitations to the use of environments. A
83583 + port using the PCD functionality is bound to an environment. Some or even
83584 + all ports may share an environment but also an environment per port is
83585 + possible. When initializing a scheme, a classification plan group (see below),
83586 + or a coarse classification tree, one of the initialized environments must be
83587 + stated and related to. When a port is bound to a scheme, a classification
83588 + plan group, or a coarse classification tree, it MUST be bound to the same
83589 + environment.
83590 +
83591 + The different PCD modules, may relate (for flows definition) ONLY on
83592 + distinction units as defined by their environment. When initializing a
83593 + scheme for example, it may not choose to select IPV4 as a match for
83594 + recognizing flows unless it was defined in the relating environment. In
83595 + fact, to guide the user through the configuration of the PCD, each module's
83596 + characterization in terms of flows is not done using protocol names, but using
83597 + environment indexes.
83598 +
83599 + In terms of HW implementation, the list of distinction units sets the LCV vectors
83600 + and later used for match vector, classification plan vectors and coarse classification
83601 + indexing.
83602 +
83603 + @Param[in] h_FmPcd FM PCD module descriptor.
83604 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
83605 + the network environment.
83606 +
83607 + @Return A handle to the initialized object on success; NULL code otherwise.
83608 +
83609 + @Cautions Allowed only following FM_PCD_Init().
83610 +*//***************************************************************************/
83611 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
83612 +
83613 +/**************************************************************************//**
83614 + @Function FM_PCD_NetEnvCharacteristicsDelete
83615 +
83616 + @Description Deletes a set of Network Environment Characteristics.
83617 +
83618 + @Param[in] h_NetEnv A handle to the Network environment.
83619 +
83620 + @Return E_OK on success; Error code otherwise.
83621 +*//***************************************************************************/
83622 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
83623 +
83624 +/**************************************************************************//**
83625 + @Function FM_PCD_KgSchemeSet
83626 +
83627 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
83628 + This routine should be called for adding or modifying a scheme.
83629 + When a scheme needs modifying, the API requires that it will be
83630 + rewritten. In such a case 'modify' should be TRUE. If the
83631 + routine is called for a valid scheme and 'modify' is FALSE,
83632 + it will return error.
83633 +
83634 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
83635 + Otherwise NULL (ignored by driver).
83636 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
83637 +
83638 + @Return A handle to the initialized scheme on success; NULL code otherwise.
83639 + When used as "modify" (rather than for setting a new scheme),
83640 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
83641 + BUSY state.
83642 +
83643 + @Cautions Allowed only following FM_PCD_Init().
83644 +*//***************************************************************************/
83645 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
83646 + t_FmPcdKgSchemeParams *p_SchemeParams);
83647 +
83648 +/**************************************************************************//**
83649 + @Function FM_PCD_KgSchemeDelete
83650 +
83651 + @Description Deleting an initialized scheme.
83652 +
83653 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
83654 +
83655 + @Return E_OK on success; Error code otherwise.
83656 +
83657 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83658 +*//***************************************************************************/
83659 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
83660 +
83661 +/**************************************************************************//**
83662 + @Function FM_PCD_KgSchemeGetCounter
83663 +
83664 + @Description Reads scheme packet counter.
83665 +
83666 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83667 +
83668 + @Return Counter's current value.
83669 +
83670 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83671 +*//***************************************************************************/
83672 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
83673 +
83674 +/**************************************************************************//**
83675 + @Function FM_PCD_KgSchemeSetCounter
83676 +
83677 + @Description Writes scheme packet counter.
83678 +
83679 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
83680 + @Param[in] value New scheme counter value - typically '0' for
83681 + resetting the counter.
83682 +
83683 + @Return E_OK on success; Error code otherwise.
83684 +
83685 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
83686 +*//***************************************************************************/
83687 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
83688 +
83689 +/**************************************************************************//**
83690 + @Function FM_PCD_PlcrProfileSet
83691 +
83692 + @Description Sets a profile entry in the policer profile table.
83693 + The routine overrides any existing value.
83694 +
83695 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83696 + @Param[in] p_Profile A structure of parameters for defining a
83697 + policer profile entry.
83698 +
83699 + @Return A handle to the initialized object on success; NULL code otherwise.
83700 + When used as "modify" (rather than for setting a new profile),
83701 + p_Profile->id.h_Profile will return NULL if action fails due to profile
83702 + BUSY state.
83703 + @Cautions Allowed only following FM_PCD_Init().
83704 +*//***************************************************************************/
83705 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
83706 + t_FmPcdPlcrProfileParams *p_Profile);
83707 +
83708 +/**************************************************************************//**
83709 + @Function FM_PCD_PlcrProfileDelete
83710 +
83711 + @Description Delete a profile entry in the policer profile table.
83712 + The routine set entry to invalid.
83713 +
83714 + @Param[in] h_Profile A handle to the profile.
83715 +
83716 + @Return E_OK on success; Error code otherwise.
83717 +
83718 + @Cautions Allowed only following FM_PCD_Init().
83719 +*//***************************************************************************/
83720 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
83721 +
83722 +/**************************************************************************//**
83723 + @Function FM_PCD_PlcrProfileGetCounter
83724 +
83725 + @Description Sets an entry in the classification plan.
83726 + The routine overrides any existing value.
83727 +
83728 + @Param[in] h_Profile A handle to the profile.
83729 + @Param[in] counter Counter selector.
83730 +
83731 + @Return specific counter value.
83732 +
83733 + @Cautions Allowed only following FM_PCD_Init().
83734 +*//***************************************************************************/
83735 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
83736 + e_FmPcdPlcrProfileCounters counter);
83737 +
83738 +/**************************************************************************//**
83739 + @Function FM_PCD_PlcrProfileSetCounter
83740 +
83741 + @Description Sets an entry in the classification plan.
83742 + The routine overrides any existing value.
83743 +
83744 + @Param[in] h_Profile A handle to the profile.
83745 + @Param[in] counter Counter selector.
83746 + @Param[in] value value to set counter with.
83747 +
83748 + @Return E_OK on success; Error code otherwise.
83749 +
83750 + @Cautions Allowed only following FM_PCD_Init().
83751 +*//***************************************************************************/
83752 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
83753 + e_FmPcdPlcrProfileCounters counter,
83754 + uint32_t value);
83755 +
83756 +/**************************************************************************//**
83757 + @Function FM_PCD_CcRootBuild
83758 +
83759 + @Description This routine must be called to define a complete coarse
83760 + classification tree. This is the way to define coarse
83761 + classification to a certain flow - the KeyGen schemes
83762 + may point only to trees defined in this way.
83763 +
83764 + @Param[in] h_FmPcd FM PCD module descriptor.
83765 + @Param[in] p_Params A structure of parameters to define the tree.
83766 +
83767 + @Return A handle to the initialized object on success; NULL code otherwise.
83768 +
83769 + @Cautions Allowed only following FM_PCD_Init().
83770 +*//***************************************************************************/
83771 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
83772 + t_FmPcdCcTreeParams *p_Params);
83773 +
83774 +/**************************************************************************//**
83775 + @Function FM_PCD_CcRootDelete
83776 +
83777 + @Description Deleting an built tree.
83778 +
83779 + @Param[in] h_CcTree A handle to a CC tree.
83780 +
83781 + @Return E_OK on success; Error code otherwise.
83782 +
83783 + @Cautions Allowed only following FM_PCD_Init().
83784 +*//***************************************************************************/
83785 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
83786 +
83787 +/**************************************************************************//**
83788 + @Function FM_PCD_CcRootModifyNextEngine
83789 +
83790 + @Description Modify the Next Engine Parameters in the entry of the tree.
83791 +
83792 + @Param[in] h_CcTree A handle to the tree
83793 + @Param[in] grpId A Group index in the tree
83794 + @Param[in] index Entry index in the group defined by grpId
83795 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
83796 +
83797 + @Return E_OK on success; Error code otherwise.
83798 +
83799 + @Cautions Allowed only following FM_PCD_CcBuildTree().
83800 +*//***************************************************************************/
83801 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
83802 + uint8_t grpId,
83803 + uint8_t index,
83804 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83805 +
83806 +/**************************************************************************//**
83807 + @Function FM_PCD_MatchTableSet
83808 +
83809 + @Description This routine should be called for each CC (coarse classification)
83810 + node. The whole CC tree should be built bottom up so that each
83811 + node points to already defined nodes.
83812 +
83813 + @Param[in] h_FmPcd FM PCD module descriptor.
83814 + @Param[in] p_Param A structure of parameters defining the CC node
83815 +
83816 + @Return A handle to the initialized object on success; NULL code otherwise.
83817 +
83818 + @Cautions Allowed only following FM_PCD_Init().
83819 +*//***************************************************************************/
83820 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
83821 +
83822 +/**************************************************************************//**
83823 + @Function FM_PCD_MatchTableDelete
83824 +
83825 + @Description Deleting an built node.
83826 +
83827 + @Param[in] h_CcNode A handle to a CC node.
83828 +
83829 + @Return E_OK on success; Error code otherwise.
83830 +
83831 + @Cautions Allowed only following FM_PCD_Init().
83832 +*//***************************************************************************/
83833 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
83834 +
83835 +/**************************************************************************//**
83836 + @Function FM_PCD_MatchTableModifyMissNextEngine
83837 +
83838 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
83839 +
83840 + @Param[in] h_CcNode A handle to the node
83841 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83842 +
83843 + @Return E_OK on success; Error code otherwise.
83844 +
83845 + @Cautions Allowed only following FM_PCD_MatchTableSet();
83846 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
83847 + When configuring nextEngine = e_FM_PCD_CC, note that
83848 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83849 + from the currently changed table.
83850 +
83851 +*//***************************************************************************/
83852 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
83853 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83854 +
83855 +/**************************************************************************//**
83856 + @Function FM_PCD_MatchTableRemoveKey
83857 +
83858 + @Description Remove the key (including next engine parameters of this key)
83859 + defined by the index of the relevant node.
83860 +
83861 + @Param[in] h_CcNode A handle to the node
83862 + @Param[in] keyIndex Key index for removing
83863 +
83864 + @Return E_OK on success; Error code otherwise.
83865 +
83866 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83867 + node and the nodes that lead to it.
83868 +*//***************************************************************************/
83869 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
83870 +
83871 +/**************************************************************************//**
83872 + @Function FM_PCD_MatchTableAddKey
83873 +
83874 + @Description Add the key (including next engine parameters of this key in the
83875 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
83876 + may be used by user that don't care about the position of the
83877 + key in the table - in that case, the key will be automatically
83878 + added by the driver in the last available entry.
83879 +
83880 + @Param[in] h_CcNode A handle to the node
83881 + @Param[in] keyIndex Key index for adding.
83882 + @Param[in] keySize Key size of added key
83883 + @Param[in] p_KeyParams A pointer to the parameters includes
83884 + new key with Next Engine Parameters
83885 +
83886 + @Return E_OK on success; Error code otherwise.
83887 +
83888 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83889 + node and the nodes that lead to it.
83890 +*//***************************************************************************/
83891 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
83892 + uint16_t keyIndex,
83893 + uint8_t keySize,
83894 + t_FmPcdCcKeyParams *p_KeyParams);
83895 +
83896 +/**************************************************************************//**
83897 + @Function FM_PCD_MatchTableModifyNextEngine
83898 +
83899 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
83900 +
83901 + @Param[in] h_CcNode A handle to the node
83902 + @Param[in] keyIndex Key index for Next Engine modifications
83903 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
83904 +
83905 + @Return E_OK on success; Error code otherwise.
83906 +
83907 + @Cautions Allowed only following FM_PCD_MatchTableSet().
83908 + When configuring nextEngine = e_FM_PCD_CC, note that
83909 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83910 + from the currently changed table.
83911 +
83912 +*//***************************************************************************/
83913 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
83914 + uint16_t keyIndex,
83915 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
83916 +
83917 +/**************************************************************************//**
83918 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
83919 +
83920 + @Description Modify the key and Next Engine Parameters of this key in the
83921 + index defined by the keyIndex.
83922 +
83923 + @Param[in] h_CcNode A handle to the node
83924 + @Param[in] keyIndex Key index for adding
83925 + @Param[in] keySize Key size of added key
83926 + @Param[in] p_KeyParams A pointer to the parameters includes
83927 + modified key and modified Next Engine Parameters
83928 +
83929 + @Return E_OK on success; Error code otherwise.
83930 +
83931 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83932 + node and the nodes that lead to it.
83933 + When configuring nextEngine = e_FM_PCD_CC, note that
83934 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
83935 + from the currently changed table.
83936 +*//***************************************************************************/
83937 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
83938 + uint16_t keyIndex,
83939 + uint8_t keySize,
83940 + t_FmPcdCcKeyParams *p_KeyParams);
83941 +
83942 +/**************************************************************************//**
83943 + @Function FM_PCD_MatchTableModifyKey
83944 +
83945 + @Description Modify the key in the index defined by the keyIndex.
83946 +
83947 + @Param[in] h_CcNode A handle to the node
83948 + @Param[in] keyIndex Key index for adding
83949 + @Param[in] keySize Key size of added key
83950 + @Param[in] p_Key A pointer to the new key
83951 + @Param[in] p_Mask A pointer to the new mask if relevant,
83952 + otherwise pointer to NULL
83953 +
83954 + @Return E_OK on success; Error code otherwise.
83955 +
83956 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83957 + node and the nodes that lead to it.
83958 +*//***************************************************************************/
83959 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
83960 + uint16_t keyIndex,
83961 + uint8_t keySize,
83962 + uint8_t *p_Key,
83963 + uint8_t *p_Mask);
83964 +
83965 +/**************************************************************************//**
83966 + @Function FM_PCD_MatchTableFindNRemoveKey
83967 +
83968 + @Description Remove the key (including next engine parameters of this key)
83969 + defined by the key and mask. Note that this routine will search
83970 + the node to locate the index of the required key (& mask) to remove.
83971 +
83972 + @Param[in] h_CcNode A handle to the node
83973 + @Param[in] keySize Key size of the one to remove.
83974 + @Param[in] p_Key A pointer to the requested key to remove.
83975 + @Param[in] p_Mask A pointer to the mask if relevant,
83976 + otherwise pointer to NULL
83977 +
83978 + @Return E_OK on success; Error code otherwise.
83979 +
83980 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
83981 + node and the nodes that lead to it.
83982 +*//***************************************************************************/
83983 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
83984 + uint8_t keySize,
83985 + uint8_t *p_Key,
83986 + uint8_t *p_Mask);
83987 +
83988 +/**************************************************************************//**
83989 + @Function FM_PCD_MatchTableFindNModifyNextEngine
83990 +
83991 + @Description Modify the Next Engine Parameters in the relevant key entry of
83992 + the node. Note that this routine will search the node to locate
83993 + the index of the required key (& mask) to modify.
83994 +
83995 + @Param[in] h_CcNode A handle to the node
83996 + @Param[in] keySize Key size of the one to modify.
83997 + @Param[in] p_Key A pointer to the requested key to modify.
83998 + @Param[in] p_Mask A pointer to the mask if relevant,
83999 + otherwise pointer to NULL
84000 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
84001 +
84002 + @Return E_OK on success; Error code otherwise.
84003 +
84004 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84005 + When configuring nextEngine = e_FM_PCD_CC, note that
84006 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84007 + from the currently changed table.
84008 +*//***************************************************************************/
84009 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
84010 + uint8_t keySize,
84011 + uint8_t *p_Key,
84012 + uint8_t *p_Mask,
84013 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84014 +
84015 +/**************************************************************************//**
84016 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
84017 +
84018 + @Description Modify the key and Next Engine Parameters of this key in the
84019 + index defined by the keyIndex. Note that this routine will search
84020 + the node to locate the index of the required key (& mask) to modify.
84021 +
84022 + @Param[in] h_CcNode A handle to the node
84023 + @Param[in] keySize Key size of the one to modify.
84024 + @Param[in] p_Key A pointer to the requested key to modify.
84025 + @Param[in] p_Mask A pointer to the mask if relevant,
84026 + otherwise pointer to NULL
84027 + @Param[in] p_KeyParams A pointer to the parameters includes
84028 + modified key and modified Next Engine Parameters
84029 +
84030 + @Return E_OK on success; Error code otherwise.
84031 +
84032 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84033 + node and the nodes that lead to it.
84034 + When configuring nextEngine = e_FM_PCD_CC, note that
84035 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84036 + from the currently changed table.
84037 +*//***************************************************************************/
84038 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
84039 + uint8_t keySize,
84040 + uint8_t *p_Key,
84041 + uint8_t *p_Mask,
84042 + t_FmPcdCcKeyParams *p_KeyParams);
84043 +
84044 +/**************************************************************************//**
84045 + @Function FM_PCD_MatchTableFindNModifyKey
84046 +
84047 + @Description Modify the key in the index defined by the keyIndex. Note that
84048 + this routine will search the node to locate the index of the
84049 + required key (& mask) to modify.
84050 +
84051 + @Param[in] h_CcNode A handle to the node
84052 + @Param[in] keySize Key size of the one to modify.
84053 + @Param[in] p_Key A pointer to the requested key to modify.
84054 + @Param[in] p_Mask A pointer to the mask if relevant,
84055 + otherwise pointer to NULL
84056 + @Param[in] p_NewKey A pointer to the new key
84057 + @Param[in] p_NewMask A pointer to the new mask if relevant,
84058 + otherwise pointer to NULL
84059 +
84060 + @Return E_OK on success; Error code otherwise.
84061 +
84062 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
84063 + node and the nodes that lead to it.
84064 +*//***************************************************************************/
84065 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
84066 + uint8_t keySize,
84067 + uint8_t *p_Key,
84068 + uint8_t *p_Mask,
84069 + uint8_t *p_NewKey,
84070 + uint8_t *p_NewMask);
84071 +
84072 +/**************************************************************************//**
84073 + @Function FM_PCD_MatchTableGetKeyCounter
84074 +
84075 + @Description This routine may be used to get a counter of specific key in a CC
84076 + Node; This counter reflects how many frames passed that were matched
84077 + this key.
84078 +
84079 + @Param[in] h_CcNode A handle to the node
84080 + @Param[in] keyIndex Key index for adding
84081 +
84082 + @Return The specific key counter.
84083 +
84084 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84085 +*//***************************************************************************/
84086 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
84087 +
84088 +/**************************************************************************//**
84089 + @Function FM_PCD_MatchTableGetKeyStatistics
84090 +
84091 + @Description This routine may be used to get statistics counters of specific key
84092 + in a CC Node.
84093 +
84094 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84095 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84096 + these counters reflect how many frames passed that were matched
84097 + this key; The total frames count will be returned in the counter
84098 + of the first range (as only one frame length range was defined).
84099 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84100 + frame count will be separated to frame length counters, based on
84101 + provided frame length ranges.
84102 +
84103 + @Param[in] h_CcNode A handle to the node
84104 + @Param[in] keyIndex Key index for adding
84105 + @Param[out] p_KeyStatistics Key statistics counters
84106 +
84107 + @Return The specific key statistics.
84108 +
84109 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84110 +*//***************************************************************************/
84111 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
84112 + uint16_t keyIndex,
84113 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84114 +
84115 +/**************************************************************************//**
84116 + @Function FM_PCD_MatchTableGetMissStatistics
84117 +
84118 + @Description This routine may be used to get statistics counters of miss entry
84119 + in a CC Node.
84120 +
84121 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84122 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84123 + these counters reflect how many frames were not matched to any
84124 + existing key and therefore passed through the miss entry; The
84125 + total frames count will be returned in the counter of the
84126 + first range (as only one frame length range was defined).
84127 +
84128 + @Param[in] h_CcNode A handle to the node
84129 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84130 +
84131 + @Return The statistics for 'miss'.
84132 +
84133 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84134 +*//***************************************************************************/
84135 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
84136 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84137 +
84138 +/**************************************************************************//**
84139 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
84140 +
84141 + @Description This routine may be used to get statistics counters of specific key
84142 + in a CC Node.
84143 +
84144 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84145 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84146 + these counters reflect how many frames passed that were matched
84147 + this key; The total frames count will be returned in the counter
84148 + of the first range (as only one frame length range was defined).
84149 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84150 + frame count will be separated to frame length counters, based on
84151 + provided frame length ranges.
84152 + Note that this routine will search the node to locate the index
84153 + of the required key based on received key parameters.
84154 +
84155 + @Param[in] h_CcNode A handle to the node
84156 + @Param[in] keySize Size of the requested key
84157 + @Param[in] p_Key A pointer to the requested key
84158 + @Param[in] p_Mask A pointer to the mask if relevant,
84159 + otherwise pointer to NULL
84160 + @Param[out] p_KeyStatistics Key statistics counters
84161 +
84162 + @Return The specific key statistics.
84163 +
84164 + @Cautions Allowed only following FM_PCD_MatchTableSet().
84165 +*//***************************************************************************/
84166 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
84167 + uint8_t keySize,
84168 + uint8_t *p_Key,
84169 + uint8_t *p_Mask,
84170 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84171 +
84172 +/**************************************************************************//*
84173 + @Function FM_PCD_MatchTableGetNextEngine
84174 +
84175 + @Description Gets NextEngine of the relevant keyIndex.
84176 +
84177 + @Param[in] h_CcNode A handle to the node.
84178 + @Param[in] keyIndex keyIndex in the relevant node.
84179 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
84180 + the relevant keyIndex of the CC Node
84181 + received as parameter to this function
84182 +
84183 + @Return E_OK on success; Error code otherwise.
84184 +
84185 + @Cautions Allowed only following FM_PCD_Init().
84186 +*//***************************************************************************/
84187 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
84188 + uint16_t keyIndex,
84189 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84190 +
84191 +/**************************************************************************//*
84192 + @Function FM_PCD_MatchTableGetIndexedHashBucket
84193 +
84194 + @Description This routine simulates KeyGen operation on the provided key and
84195 + calculates to which hash bucket it will be mapped.
84196 +
84197 + @Param[in] h_CcNode A handle to the node.
84198 + @Param[in] kgKeySize Key size as it was configured in the KG
84199 + scheme that leads to this hash.
84200 + @Param[in] p_KgKey Pointer to the key; must be like the key
84201 + that the KG is generated, i.e. the same
84202 + extraction and with mask if exist.
84203 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
84204 + scheme that leads to this hash.
84205 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
84206 + @Param[out] p_BucketIndex Index to the bucket of the provided key
84207 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
84208 + provided key.
84209 +
84210 + @Return E_OK on success; Error code otherwise.
84211 +
84212 + @Cautions Allowed only following FM_PCD_HashTableSet()
84213 +*//***************************************************************************/
84214 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
84215 + uint8_t kgKeySize,
84216 + uint8_t *p_KgKey,
84217 + uint8_t kgHashShift,
84218 + t_Handle *p_CcNodeBucketHandle,
84219 + uint8_t *p_BucketIndex,
84220 + uint16_t *p_LastIndex);
84221 +
84222 +/**************************************************************************//**
84223 + @Function FM_PCD_HashTableSet
84224 +
84225 + @Description This routine initializes a hash table structure.
84226 + KeyGen hash result determines the hash bucket.
84227 + Next, KeyGen key is compared against all keys of this
84228 + bucket (exact match).
84229 + Number of sets (number of buckets) of the hash equals to the
84230 + number of 1-s in 'hashResMask' in the provided parameters.
84231 + Number of hash table ways is then calculated by dividing
84232 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
84233 + number of keys that a hash bucket may hold.
84234 + The hash table is initialized empty and keys may be
84235 + added to it following the initialization. Keys masks are not
84236 + supported in current hash table implementation.
84237 + The initialized hash table can be integrated as a node in a
84238 + CC tree.
84239 +
84240 + @Param[in] h_FmPcd FM PCD module descriptor.
84241 + @Param[in] p_Param A structure of parameters defining the hash table
84242 +
84243 + @Return A handle to the initialized object on success; NULL code otherwise.
84244 +
84245 + @Cautions Allowed only following FM_PCD_Init().
84246 +*//***************************************************************************/
84247 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
84248 +
84249 +/**************************************************************************//**
84250 + @Function FM_PCD_HashTableDelete
84251 +
84252 + @Description This routine deletes the provided hash table and released all
84253 + its allocated resources.
84254 +
84255 + @Param[in] h_HashTbl A handle to a hash table
84256 +
84257 + @Return E_OK on success; Error code otherwise.
84258 +
84259 + @Cautions Allowed only following FM_PCD_HashTableSet().
84260 +*//***************************************************************************/
84261 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
84262 +
84263 +/**************************************************************************//**
84264 + @Function FM_PCD_HashTableAddKey
84265 +
84266 + @Description This routine adds the provided key (including next engine
84267 + parameters of this key) to the hash table.
84268 + The key is added as the last key of the bucket that it is
84269 + mapped to.
84270 +
84271 + @Param[in] h_HashTbl A handle to a hash table
84272 + @Param[in] keySize Key size of added key
84273 + @Param[in] p_KeyParams A pointer to the parameters includes
84274 + new key with next engine parameters; The pointer
84275 + to the key mask must be NULL, as masks are not
84276 + supported in hash table implementation.
84277 +
84278 + @Return E_OK on success; Error code otherwise.
84279 +
84280 + @Cautions Allowed only following FM_PCD_HashTableSet().
84281 +*//***************************************************************************/
84282 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
84283 + uint8_t keySize,
84284 + t_FmPcdCcKeyParams *p_KeyParams);
84285 +
84286 +/**************************************************************************//**
84287 + @Function FM_PCD_HashTableRemoveKey
84288 +
84289 + @Description This routine removes the requested key (including next engine
84290 + parameters of this key) from the hash table.
84291 +
84292 + @Param[in] h_HashTbl A handle to a hash table
84293 + @Param[in] keySize Key size of the one to remove.
84294 + @Param[in] p_Key A pointer to the requested key to remove.
84295 +
84296 + @Return E_OK on success; Error code otherwise.
84297 +
84298 + @Cautions Allowed only following FM_PCD_HashTableSet().
84299 +*//***************************************************************************/
84300 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
84301 + uint8_t keySize,
84302 + uint8_t *p_Key);
84303 +
84304 +/**************************************************************************//**
84305 + @Function FM_PCD_HashTableModifyNextEngine
84306 +
84307 + @Description This routine modifies the next engine for the provided key. The
84308 + key should be previously added to the hash table.
84309 +
84310 + @Param[in] h_HashTbl A handle to a hash table
84311 + @Param[in] keySize Key size of the key to modify.
84312 + @Param[in] p_Key A pointer to the requested key to modify.
84313 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84314 + parameters.
84315 +
84316 + @Return E_OK on success; Error code otherwise.
84317 +
84318 + @Cautions Allowed only following FM_PCD_HashTableSet().
84319 + When configuring nextEngine = e_FM_PCD_CC, note that
84320 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84321 + from the currently changed table.
84322 +*//***************************************************************************/
84323 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
84324 + uint8_t keySize,
84325 + uint8_t *p_Key,
84326 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84327 +
84328 +/**************************************************************************//**
84329 + @Function FM_PCD_HashTableModifyMissNextEngine
84330 +
84331 + @Description This routine modifies the next engine on key match miss.
84332 +
84333 + @Param[in] h_HashTbl A handle to a hash table
84334 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
84335 + parameters.
84336 +
84337 + @Return E_OK on success; Error code otherwise.
84338 +
84339 + @Cautions Allowed only following FM_PCD_HashTableSet().
84340 + When configuring nextEngine = e_FM_PCD_CC, note that
84341 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
84342 + from the currently changed table.
84343 +*//***************************************************************************/
84344 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
84345 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84346 +
84347 +/**************************************************************************//*
84348 + @Function FM_PCD_HashTableGetMissNextEngine
84349 +
84350 + @Description Gets NextEngine in case of key match miss.
84351 +
84352 + @Param[in] h_HashTbl A handle to a hash table
84353 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
84354 + hash table.
84355 +
84356 + @Return E_OK on success; Error code otherwise.
84357 +
84358 + @Cautions Allowed only following FM_PCD_HashTableSet().
84359 +*//***************************************************************************/
84360 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
84361 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
84362 +
84363 +/**************************************************************************//**
84364 + @Function FM_PCD_HashTableFindNGetKeyStatistics
84365 +
84366 + @Description This routine may be used to get statistics counters of specific key
84367 + in a hash table.
84368 +
84369 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84370 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84371 + these counters reflect how many frames passed that were matched
84372 + this key; The total frames count will be returned in the counter
84373 + of the first range (as only one frame length range was defined).
84374 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
84375 + frame count will be separated to frame length counters, based on
84376 + provided frame length ranges.
84377 + Note that this routine will identify the bucket of this key in
84378 + the hash table and will search the bucket to locate the index
84379 + of the required key based on received key parameters.
84380 +
84381 + @Param[in] h_HashTbl A handle to a hash table
84382 + @Param[in] keySize Size of the requested key
84383 + @Param[in] p_Key A pointer to the requested key
84384 + @Param[out] p_KeyStatistics Key statistics counters
84385 +
84386 + @Return The specific key statistics.
84387 +
84388 + @Cautions Allowed only following FM_PCD_HashTableSet().
84389 +*//***************************************************************************/
84390 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
84391 + uint8_t keySize,
84392 + uint8_t *p_Key,
84393 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
84394 +
84395 +/**************************************************************************//**
84396 + @Function FM_PCD_HashTableGetMissStatistics
84397 +
84398 + @Description This routine may be used to get statistics counters of 'miss'
84399 + entry of the a hash table.
84400 +
84401 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
84402 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
84403 + these counters reflect how many frames were not matched to any
84404 + existing key and therefore passed through the miss entry;
84405 +
84406 + @Param[in] h_HashTbl A handle to a hash table
84407 + @Param[out] p_MissStatistics Statistics counters for 'miss'
84408 +
84409 + @Return The statistics for 'miss'.
84410 +
84411 + @Cautions Allowed only following FM_PCD_HashTableSet().
84412 +*//***************************************************************************/
84413 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
84414 + t_FmPcdCcKeyStatistics *p_MissStatistics);
84415 +
84416 +/**************************************************************************//**
84417 + @Function FM_PCD_ManipNodeSet
84418 +
84419 + @Description This routine should be called for defining a manipulation
84420 + node. A manipulation node must be defined before the CC node
84421 + that precedes it.
84422 +
84423 + @Param[in] h_FmPcd FM PCD module descriptor.
84424 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
84425 +
84426 + @Return A handle to the initialized object on success; NULL code otherwise.
84427 +
84428 + @Cautions Allowed only following FM_PCD_Init().
84429 +*//***************************************************************************/
84430 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
84431 +
84432 +/**************************************************************************//**
84433 + @Function FM_PCD_ManipNodeDelete
84434 +
84435 + @Description Delete an existing manipulation node.
84436 +
84437 + @Param[in] h_ManipNode A handle to a manipulation node.
84438 +
84439 + @Return E_OK on success; Error code otherwise.
84440 +
84441 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84442 +*//***************************************************************************/
84443 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
84444 +
84445 +/**************************************************************************//**
84446 + @Function FM_PCD_ManipGetStatistics
84447 +
84448 + @Description Retrieve the manipulation statistics.
84449 +
84450 + @Param[in] h_ManipNode A handle to a manipulation node.
84451 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
84452 +
84453 + @Return E_OK on success; Error code otherwise.
84454 +
84455 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84456 +*//***************************************************************************/
84457 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
84458 +
84459 +/**************************************************************************//**
84460 + @Function FM_PCD_ManipNodeReplace
84461 +
84462 + @Description Change existing manipulation node to be according to new requirement.
84463 +
84464 + @Param[in] h_ManipNode A handle to a manipulation node.
84465 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
84466 +
84467 + @Return E_OK on success; Error code otherwise.
84468 +
84469 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
84470 +*//***************************************************************************/
84471 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
84472 +
84473 +#if (DPAA_VERSION >= 11)
84474 +/**************************************************************************//**
84475 + @Function FM_PCD_FrmReplicSetGroup
84476 +
84477 + @Description Initialize a Frame Replicator group.
84478 +
84479 + @Param[in] h_FmPcd FM PCD module descriptor.
84480 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
84481 + the frame replicator group.
84482 +
84483 + @Return A handle to the initialized object on success; NULL code otherwise.
84484 +
84485 + @Cautions Allowed only following FM_PCD_Init().
84486 +*//***************************************************************************/
84487 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
84488 +
84489 +/**************************************************************************//**
84490 + @Function FM_PCD_FrmReplicDeleteGroup
84491 +
84492 + @Description Delete a Frame Replicator group.
84493 +
84494 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84495 +
84496 + @Return E_OK on success; Error code otherwise.
84497 +
84498 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
84499 +*//***************************************************************************/
84500 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
84501 +
84502 +/**************************************************************************//**
84503 + @Function FM_PCD_FrmReplicAddMember
84504 +
84505 + @Description Add the member in the index defined by the memberIndex.
84506 +
84507 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84508 + @Param[in] memberIndex member index for adding.
84509 + @Param[in] p_MemberParams A pointer to the new member parameters.
84510 +
84511 + @Return E_OK on success; Error code otherwise.
84512 +
84513 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84514 +*//***************************************************************************/
84515 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
84516 + uint16_t memberIndex,
84517 + t_FmPcdCcNextEngineParams *p_MemberParams);
84518 +
84519 +/**************************************************************************//**
84520 + @Function FM_PCD_FrmReplicRemoveMember
84521 +
84522 + @Description Remove the member defined by the index from the relevant group.
84523 +
84524 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
84525 + @Param[in] memberIndex member index for removing.
84526 +
84527 + @Return E_OK on success; Error code otherwise.
84528 +
84529 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
84530 +*//***************************************************************************/
84531 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
84532 + uint16_t memberIndex);
84533 +#endif /* (DPAA_VERSION >= 11) */
84534 +
84535 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84536 +/**************************************************************************//**
84537 + @Function FM_PCD_StatisticsSetNode
84538 +
84539 + @Description This routine should be called for defining a statistics node.
84540 +
84541 + @Param[in] h_FmPcd FM PCD module descriptor.
84542 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
84543 +
84544 + @Return A handle to the initialized object on success; NULL code otherwise.
84545 +
84546 + @Cautions Allowed only following FM_PCD_Init().
84547 +*//***************************************************************************/
84548 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
84549 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84550 +
84551 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
84552 +/** @} */ /* end of FM_PCD_Runtime_grp group */
84553 +/** @} */ /* end of FM_PCD_grp group */
84554 +/** @} */ /* end of FM_grp group */
84555 +
84556 +
84557 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
84558 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
84559 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
84560 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
84561 +
84562 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
84563 +
84564 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
84565 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
84566 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
84567 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
84568 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
84569 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
84570 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
84571 +
84572 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
84573 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
84574 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
84575 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
84576 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
84577 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
84578 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
84579 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
84580 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
84581 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
84582 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
84583 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
84584 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
84585 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
84586 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
84587 + FM_PCD_CcRootDelete(__VA_ARGS__)
84588 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
84589 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
84590 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
84591 + FM_PCD_MatchTableDelete(__VA_ARGS__)
84592 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
84593 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
84594 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
84595 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
84596 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
84597 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
84598 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
84599 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
84600 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
84601 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
84602 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
84603 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
84604 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
84605 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
84606 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
84607 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
84608 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
84609 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
84610 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
84611 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
84612 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
84613 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
84614 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
84615 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
84616 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
84617 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
84618 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
84619 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
84620 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
84621 +
84622 +
84623 +#endif /* __FM_PCD_EXT */
84624 --- /dev/null
84625 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
84626 @@ -0,0 +1,2608 @@
84627 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
84628 + * All rights reserved.
84629 + *
84630 + * Redistribution and use in source and binary forms, with or without
84631 + * modification, are permitted provided that the following conditions are met:
84632 + * * Redistributions of source code must retain the above copyright
84633 + * notice, this list of conditions and the following disclaimer.
84634 + * * Redistributions in binary form must reproduce the above copyright
84635 + * notice, this list of conditions and the following disclaimer in the
84636 + * documentation and/or other materials provided with the distribution.
84637 + * * Neither the name of Freescale Semiconductor nor the
84638 + * names of its contributors may be used to endorse or promote products
84639 + * derived from this software without specific prior written permission.
84640 + *
84641 + *
84642 + * ALTERNATIVELY, this software may be distributed under the terms of the
84643 + * GNU General Public License ("GPL") as published by the Free Software
84644 + * Foundation, either version 2 of that License or (at your option) any
84645 + * later version.
84646 + *
84647 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
84648 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
84649 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84650 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
84651 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
84652 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
84653 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
84654 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
84655 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
84656 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84657 + */
84658 +
84659 +
84660 +/**************************************************************************//**
84661 + @File fm_port_ext.h
84662 +
84663 + @Description FM-Port Application Programming Interface.
84664 +*//***************************************************************************/
84665 +#ifndef __FM_PORT_EXT
84666 +#define __FM_PORT_EXT
84667 +
84668 +#include "error_ext.h"
84669 +#include "std_ext.h"
84670 +#include "fm_pcd_ext.h"
84671 +#include "fm_ext.h"
84672 +#include "net_ext.h"
84673 +
84674 +
84675 +/**************************************************************************//**
84676 +
84677 + @Group FM_grp Frame Manager API
84678 +
84679 + @Description FM API functions, definitions and enums
84680 +
84681 + @{
84682 +*//***************************************************************************/
84683 +
84684 +/**************************************************************************//**
84685 + @Group FM_PORT_grp FM Port
84686 +
84687 + @Description FM Port API
84688 +
84689 + The FM uses a general module called "port" to represent a Tx port
84690 + (MAC), an Rx port (MAC) or Offline Parsing port.
84691 + The number of ports in an FM varies between SOCs.
84692 + The SW driver manages these ports as sub-modules of the FM, i.e.
84693 + after an FM is initialized, its ports may be initialized and
84694 + operated upon.
84695 +
84696 + The port is initialized aware of its type, but other functions on
84697 + a port may be indifferent to its type. When necessary, the driver
84698 + verifies coherence and returns error if applicable.
84699 +
84700 + On initialization, user specifies the port type and it's index
84701 + (relative to the port's type) - always starting at 0.
84702 +
84703 + @{
84704 +*//***************************************************************************/
84705 +
84706 +/**************************************************************************//**
84707 + @Description An enum for defining port PCD modes.
84708 + This enum defines the superset of PCD engines support - i.e. not
84709 + all engines have to be used, but all have to be enabled. The real
84710 + flow of a specific frame depends on the PCD configuration and the
84711 + frame headers and payload.
84712 + Note: the first engine and the first engine after the parser (if
84713 + exists) should be in order, the order is important as it will
84714 + define the flow of the port. However, as for the rest engines
84715 + (the ones that follows), the order is not important anymore as
84716 + it is defined by the PCD graph itself.
84717 +*//***************************************************************************/
84718 +typedef enum e_FmPortPcdSupport {
84719 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
84720 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
84721 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
84722 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
84723 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
84724 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
84725 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
84726 + /**< Use all PCD engines */
84727 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
84728 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
84729 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
84730 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
84731 +#ifdef FM_CAPWAP_SUPPORT
84732 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
84733 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
84734 +#endif /* FM_CAPWAP_SUPPORT */
84735 +} e_FmPortPcdSupport;
84736 +
84737 +/**************************************************************************//**
84738 + @Description Port interrupts
84739 +*//***************************************************************************/
84740 +typedef enum e_FmPortExceptions {
84741 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
84742 +} e_FmPortExceptions;
84743 +
84744 +
84745 +/**************************************************************************//**
84746 + @Collection General FM Port defines
84747 +*//***************************************************************************/
84748 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
84749 +/* @} */
84750 +
84751 +/**************************************************************************//**
84752 + @Collection FM Frame error
84753 +*//***************************************************************************/
84754 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
84755 +
84756 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
84757 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
84758 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
84759 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
84760 + was chained to FM */
84761 +
84762 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
84763 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
84764 +
84765 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
84766 +
84767 +#ifdef FM_CAPWAP_SUPPORT
84768 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
84769 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
84770 +#endif /* FM_CAPWAP_SUPPORT */
84771 +
84772 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
84773 + error (SGMII and TBI modes), FIFO parity error. PHY
84774 + Sequence error, PHY error control character detected. */
84775 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
84776 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
84777 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
84778 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
84779 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
84780 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
84781 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
84782 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
84783 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
84784 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
84785 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
84786 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
84787 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
84788 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
84789 +/* @} */
84790 +
84791 +
84792 +
84793 +/**************************************************************************//**
84794 + @Group FM_PORT_init_grp FM Port Initialization Unit
84795 +
84796 + @Description FM Port Initialization Unit
84797 +
84798 + @{
84799 +*//***************************************************************************/
84800 +
84801 +/**************************************************************************//**
84802 + @Description Exceptions user callback routine, will be called upon an
84803 + exception passing the exception identification.
84804 +
84805 + @Param[in] h_App - User's application descriptor.
84806 + @Param[in] exception - The exception.
84807 + *//***************************************************************************/
84808 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
84809 +
84810 +/**************************************************************************//**
84811 + @Description User callback function called by driver with received data.
84812 +
84813 + User provides this function. Driver invokes it.
84814 +
84815 + @Param[in] h_App Application's handle originally specified to
84816 + the API Config function
84817 + @Param[in] p_Data A pointer to data received
84818 + @Param[in] length length of received data
84819 + @Param[in] status receive status and errors
84820 + @Param[in] position position of buffer in frame
84821 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84822 +
84823 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
84824 + operation for all ready data.
84825 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
84826 +*//***************************************************************************/
84827 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
84828 + uint8_t *p_Data,
84829 + uint16_t length,
84830 + uint16_t status,
84831 + uint8_t position,
84832 + t_Handle h_BufContext);
84833 +
84834 +/**************************************************************************//**
84835 + @Description User callback function called by driver when transmit completed.
84836 +
84837 + User provides this function. Driver invokes it.
84838 +
84839 + @Param[in] h_App Application's handle originally specified to
84840 + the API Config function
84841 + @Param[in] p_Data A pointer to data received
84842 + @Param[in] status transmit status and errors
84843 + @Param[in] lastBuffer is last buffer in frame
84844 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
84845 + *//***************************************************************************/
84846 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
84847 + uint8_t *p_Data,
84848 + uint16_t status,
84849 + t_Handle h_BufContext);
84850 +
84851 +/**************************************************************************//**
84852 + @Description A structure for additional Rx port parameters
84853 +*//***************************************************************************/
84854 +typedef struct t_FmPortRxParams {
84855 + uint32_t errFqid; /**< Error Queue Id. */
84856 + uint32_t dfltFqid; /**< Default Queue Id. */
84857 + uint16_t liodnOffset; /**< Port's LIODN offset. */
84858 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
84859 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
84860 +} t_FmPortRxParams;
84861 +
84862 +/**************************************************************************//**
84863 + @Description A structure for additional non-Rx port parameters
84864 +*//***************************************************************************/
84865 +typedef struct t_FmPortNonRxParams {
84866 + uint32_t errFqid; /**< Error Queue Id. */
84867 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
84868 + 0 means no Tx confirmation for processed
84869 + frames. For OP port - default Rx queue. */
84870 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
84871 + by the FM for dequeue. */
84872 +} t_FmPortNonRxParams;
84873 +
84874 +/**************************************************************************//**
84875 + @Description A structure for additional Rx port parameters
84876 +*//***************************************************************************/
84877 +typedef struct t_FmPortImRxTxParams {
84878 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
84879 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
84880 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
84881 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
84882 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
84883 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
84884 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
84885 +} t_FmPortImRxTxParams;
84886 +
84887 +/**************************************************************************//**
84888 + @Description A union for additional parameters depending on port type
84889 +*//***************************************************************************/
84890 +typedef union u_FmPortSpecificParams {
84891 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
84892 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
84893 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
84894 +} u_FmPortSpecificParams;
84895 +
84896 +/**************************************************************************//**
84897 + @Description A structure representing FM initialization parameters
84898 +*//***************************************************************************/
84899 +typedef struct t_FmPortParams {
84900 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
84901 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
84902 + e_FmPortType portType; /**< Port type */
84903 + uint8_t portId; /**< Port Id - relative to type;
84904 + NOTE: When configuring Offline Parsing port for
84905 + FMANv3 devices (DPAA_VERSION 11 and higher),
84906 + it is highly recommended NOT to use portId=0 due to lack
84907 + of HW resources on portId=0. */
84908 + bool independentModeEnable;
84909 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
84910 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
84911 + used together with LIODN offset. */
84912 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
84913 + type. */
84914 +
84915 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
84916 + t_Handle h_App; /**< A handle to an application layer object; This handle will
84917 + be passed by the driver upon calling the above callbacks */
84918 +} t_FmPortParams;
84919 +
84920 +
84921 +/**************************************************************************//**
84922 + @Function FM_PORT_Config
84923 +
84924 + @Description Creates a descriptor for the FM PORT module.
84925 +
84926 + The routine returns a handle (descriptor) to the FM PORT object.
84927 + This descriptor must be passed as first parameter to all other
84928 + FM PORT function calls.
84929 +
84930 + No actual initialization or configuration of FM hardware is
84931 + done by this routine.
84932 +
84933 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
84934 +
84935 + @Retval Handle to FM object, or NULL for Failure.
84936 +*//***************************************************************************/
84937 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
84938 +
84939 +/**************************************************************************//**
84940 + @Function FM_PORT_Init
84941 +
84942 + @Description Initializes the FM PORT module by defining the software structure
84943 + and configuring the hardware registers.
84944 +
84945 + @Param[in] h_FmPort - FM PORT module descriptor
84946 +
84947 + @Return E_OK on success; Error code otherwise.
84948 +*//***************************************************************************/
84949 +t_Error FM_PORT_Init(t_Handle h_FmPort);
84950 +
84951 +/**************************************************************************//**
84952 + @Function FM_PORT_Free
84953 +
84954 + @Description Frees all resources that were assigned to FM PORT module.
84955 +
84956 + Calling this routine invalidates the descriptor.
84957 +
84958 + @Param[in] h_FmPort - FM PORT module descriptor
84959 +
84960 + @Return E_OK on success; Error code otherwise.
84961 +*//***************************************************************************/
84962 +t_Error FM_PORT_Free(t_Handle h_FmPort);
84963 +
84964 +
84965 +/**************************************************************************//**
84966 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
84967 +
84968 + @Description Configuration functions used to change default values.
84969 +
84970 + @{
84971 +*//***************************************************************************/
84972 +
84973 +/**************************************************************************//**
84974 + @Description enum for defining QM frame dequeue
84975 +*//***************************************************************************/
84976 +typedef enum e_FmPortDeqType {
84977 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
84978 + and Intra-Class Scheduling respected. */
84979 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
84980 + and Intra-Class Scheduling respected. */
84981 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
84982 + and override Intra-Class Scheduling */
84983 +} e_FmPortDeqType;
84984 +
84985 +/**************************************************************************//**
84986 + @Description enum for defining QM frame dequeue
84987 +*//***************************************************************************/
84988 +typedef enum e_FmPortDeqPrefetchOption {
84989 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
84990 + only when a dedicated portID Tnum is waiting. */
84991 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
84992 + one dedicated portId tnum is waiting. */
84993 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
84994 + no dedicated portId tnums are waiting. */
84995 +
84996 +} e_FmPortDeqPrefetchOption;
84997 +
84998 +/**************************************************************************//**
84999 + @Description enum for defining port default color
85000 +*//***************************************************************************/
85001 +typedef enum e_FmPortColor {
85002 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
85003 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
85004 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
85005 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
85006 +} e_FmPortColor;
85007 +
85008 +/**************************************************************************//**
85009 + @Description A structure for defining Dual Tx rate limiting scale
85010 +*//***************************************************************************/
85011 +typedef enum e_FmPortDualRateLimiterScaleDown {
85012 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
85013 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
85014 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
85015 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
85016 +} e_FmPortDualRateLimiterScaleDown;
85017 +
85018 +
85019 +/**************************************************************************//**
85020 + @Description A structure for defining FM port resources
85021 +*//***************************************************************************/
85022 +typedef struct t_FmPortRsrc {
85023 + uint32_t num; /**< Committed required resource */
85024 + uint32_t extra; /**< Extra (not committed) required resource */
85025 +} t_FmPortRsrc;
85026 +
85027 +/**************************************************************************//**
85028 + @Description A structure for defining observed pool depletion
85029 +*//***************************************************************************/
85030 +typedef struct t_FmPortObservedBufPoolDepletion {
85031 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
85032 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
85033 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
85034 + and their sizes. */
85035 +} t_FmPortObservedBufPoolDepletion;
85036 +
85037 +/**************************************************************************//**
85038 + @Description A structure for defining Tx rate limiting
85039 +*//***************************************************************************/
85040 +typedef struct t_FmPortRateLimit {
85041 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
85042 + for OP ports. (note that
85043 + for early chips burst size is
85044 + rounded up to a multiply of 1000 frames).*/
85045 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
85046 + OP ports. Rate limit refers to
85047 + data rate (rather than line rate). */
85048 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
85049 + for some earlier chip revisions */
85050 +} t_FmPortRateLimit;
85051 +
85052 +/**************************************************************************//**
85053 + @Description A structure for defining the parameters of
85054 + the Rx port performance counters
85055 +*//***************************************************************************/
85056 +typedef struct t_FmPortPerformanceCnt {
85057 + uint8_t taskCompVal; /**< Task compare value */
85058 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
85059 + value (unused for H/O) */
85060 + uint8_t dmaCompVal; /**< Dma compare value */
85061 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
85062 +} t_FmPortPerformanceCnt;
85063 +
85064 +
85065 +/**************************************************************************//**
85066 + @Description A structure for defining the sizes of the Deep Sleep
85067 + the Auto Response tables
85068 +*//***************************************************************************/
85069 +typedef struct t_FmPortDsarTablesSizes
85070 +{
85071 + uint16_t maxNumOfArpEntries;
85072 + uint16_t maxNumOfEchoIpv4Entries;
85073 + uint16_t maxNumOfNdpEntries;
85074 + uint16_t maxNumOfEchoIpv6Entries;
85075 + uint16_t maxNumOfSnmpIPV4Entries;
85076 + uint16_t maxNumOfSnmpIPV6Entries;
85077 + uint16_t maxNumOfSnmpOidEntries;
85078 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
85079 +
85080 + uint16_t maxNumOfIpProtFiltering;
85081 + uint16_t maxNumOfTcpPortFiltering;
85082 + uint16_t maxNumOfUdpPortFiltering;
85083 +} t_FmPortDsarTablesSizes;
85084 +
85085 +
85086 +/**************************************************************************//**
85087 + @Function FM_PORT_ConfigDsarSupport
85088 +
85089 + @Description This function will allocate the amount of MURAM needed for
85090 + this max number of entries for Deep Sleep Auto Response.
85091 + it will calculate all needed MURAM for autoresponse including
85092 + necesary common stuff.
85093 +
85094 +
85095 + @Param[in] h_FmPort A handle to a FM Port module.
85096 + @Param[in] params A pointer to a structure containing the maximum
85097 + sizes of the auto response tables
85098 +
85099 + @Return E_OK on success; Error code otherwise.
85100 +
85101 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85102 +*//***************************************************************************/
85103 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
85104 +
85105 +/**************************************************************************//**
85106 + @Function FM_PORT_ConfigNumOfOpenDmas
85107 +
85108 + @Description Calling this routine changes the max number of open DMA's
85109 + available for this port. It changes this parameter in the
85110 + internal driver data base from its default configuration
85111 + [OP: 1]
85112 + [1G-RX, 1G-TX: 1 (+1)]
85113 + [10G-RX, 10G-TX: 8 (+8)]
85114 +
85115 + @Param[in] h_FmPort A handle to a FM Port module.
85116 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
85117 + the open DMA allocation.
85118 +
85119 + @Return E_OK on success; Error code otherwise.
85120 +
85121 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85122 +*//***************************************************************************/
85123 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
85124 +
85125 +/**************************************************************************//**
85126 + @Function FM_PORT_ConfigNumOfTasks
85127 +
85128 + @Description Calling this routine changes the max number of tasks
85129 + available for this port. It changes this parameter in the
85130 + internal driver data base from its default configuration
85131 + [OP: 1]
85132 + [1G-RX, 1G-TX: 3 (+2)]
85133 + [10G-RX, 10G-TX: 16 (+8)]
85134 +
85135 + @Param[in] h_FmPort A handle to a FM Port module.
85136 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
85137 + the tasks allocation.
85138 +
85139 + @Return E_OK on success; Error code otherwise.
85140 +
85141 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85142 +*//***************************************************************************/
85143 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
85144 +
85145 +/**************************************************************************//**
85146 + @Function FM_PORT_ConfigSizeOfFifo
85147 +
85148 + @Description Calling this routine changes the max FIFO size configured for this port.
85149 +
85150 + This function changes the internal driver data base from its
85151 + default configuration. Please refer to the driver's User Guide for
85152 + information on default FIFO sizes in the various devices.
85153 + [OP: 2KB]
85154 + [1G-RX, 1G-TX: 11KB]
85155 + [10G-RX, 10G-TX: 12KB]
85156 +
85157 + @Param[in] h_FmPort A handle to a FM Port module.
85158 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
85159 + the FIFO allocation.
85160 +
85161 + @Return E_OK on success; Error code otherwise.
85162 +
85163 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85164 +*//***************************************************************************/
85165 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
85166 +
85167 +/**************************************************************************//**
85168 + @Function FM_PORT_ConfigDeqHighPriority
85169 +
85170 + @Description Calling this routine changes the dequeue priority in the
85171 + internal driver data base from its default configuration
85172 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
85173 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
85174 +
85175 + May be used for Non-Rx ports only
85176 +
85177 + @Param[in] h_FmPort A handle to a FM Port module.
85178 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
85179 +
85180 + @Return E_OK on success; Error code otherwise.
85181 +
85182 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85183 +*//***************************************************************************/
85184 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
85185 +
85186 +/**************************************************************************//**
85187 + @Function FM_PORT_ConfigDeqType
85188 +
85189 + @Description Calling this routine changes the dequeue type parameter in the
85190 + internal driver data base from its default configuration
85191 + [DEFAULT_PORT_deqType].
85192 +
85193 + May be used for Non-Rx ports only
85194 +
85195 + @Param[in] h_FmPort A handle to a FM Port module.
85196 + @Param[in] deqType According to QM definition.
85197 +
85198 + @Return E_OK on success; Error code otherwise.
85199 +
85200 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85201 +*//***************************************************************************/
85202 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
85203 +
85204 +/**************************************************************************//**
85205 + @Function FM_PORT_ConfigDeqPrefetchOption
85206 +
85207 + @Description Calling this routine changes the dequeue prefetch option parameter in the
85208 + internal driver data base from its default configuration
85209 + [DEFAULT_PORT_deqPrefetchOption]
85210 + Note: Available for some chips only
85211 +
85212 + May be used for Non-Rx ports only
85213 +
85214 + @Param[in] h_FmPort A handle to a FM Port module.
85215 + @Param[in] deqPrefetchOption New option
85216 +
85217 + @Return E_OK on success; Error code otherwise.
85218 +
85219 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85220 +*//***************************************************************************/
85221 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
85222 +
85223 +/**************************************************************************//**
85224 + @Function FM_PORT_ConfigDeqByteCnt
85225 +
85226 + @Description Calling this routine changes the dequeue byte count parameter in
85227 + the internal driver data base from its default configuration
85228 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
85229 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
85230 +
85231 + May be used for Non-Rx ports only
85232 +
85233 + @Param[in] h_FmPort A handle to a FM Port module.
85234 + @Param[in] deqByteCnt New byte count
85235 +
85236 + @Return E_OK on success; Error code otherwise.
85237 +
85238 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85239 +*//***************************************************************************/
85240 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
85241 +
85242 +/**************************************************************************//**
85243 + @Function FM_PORT_ConfigBufferPrefixContent
85244 +
85245 + @Description Defines the structure, size and content of the application buffer.
85246 + The prefix will
85247 + In Tx ports, if 'passPrsResult', the application
85248 + should set a value to their offsets in the prefix of
85249 + the FM will save the first 'privDataSize', than,
85250 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
85251 + and timeStamp, and the packet itself (in this order), to the
85252 + application buffer, and to offset.
85253 + Calling this routine changes the buffer margins definitions
85254 + in the internal driver data base from its default
85255 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
85256 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
85257 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
85258 +
85259 + May be used for all ports
85260 +
85261 + @Param[in] h_FmPort A handle to a FM Port module.
85262 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
85263 + structure of the buffer.
85264 + Out parameter: Start margin - offset
85265 + of data from start of external buffer.
85266 +
85267 + @Return E_OK on success; Error code otherwise.
85268 +
85269 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85270 +*//***************************************************************************/
85271 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
85272 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
85273 +
85274 +/**************************************************************************//**
85275 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
85276 +
85277 + @Description Calling this routine changes the number of checksum bytes to ignore
85278 + parameter in the internal driver data base from its default configuration
85279 + [DEFAULT_PORT_cheksumLastBytesIgnore]
85280 +
85281 + May be used by Tx & Rx ports only
85282 +
85283 + @Param[in] h_FmPort A handle to a FM Port module.
85284 + @Param[in] cheksumLastBytesIgnore New value
85285 +
85286 + @Return E_OK on success; Error code otherwise.
85287 +
85288 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85289 +*//***************************************************************************/
85290 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
85291 +
85292 +/**************************************************************************//**
85293 + @Function FM_PORT_ConfigCutBytesFromEnd
85294 +
85295 + @Description Calling this routine changes the number of bytes to cut from a
85296 + frame's end parameter in the internal driver data base
85297 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
85298 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
85299 + less than 14 bytes, the chop operation is not executed.
85300 +
85301 + May be used for Rx ports only
85302 +
85303 + @Param[in] h_FmPort A handle to a FM Port module.
85304 + @Param[in] cutBytesFromEnd New value
85305 +
85306 + @Return E_OK on success; Error code otherwise.
85307 +
85308 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85309 +*//***************************************************************************/
85310 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
85311 +
85312 +/**************************************************************************//**
85313 + @Function FM_PORT_ConfigPoolDepletion
85314 +
85315 + @Description Calling this routine enables pause frame generation depending on the
85316 + depletion status of BM pools. It also defines the conditions to activate
85317 + this functionality. By default, this functionality is disabled.
85318 +
85319 + May be used for Rx ports only
85320 +
85321 + @Param[in] h_FmPort A handle to a FM Port module.
85322 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
85323 +
85324 + @Return E_OK on success; Error code otherwise.
85325 +
85326 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85327 +*//***************************************************************************/
85328 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
85329 +
85330 +/**************************************************************************//**
85331 + @Function FM_PORT_ConfigObservedPoolDepletion
85332 +
85333 + @Description Calling this routine enables a mechanism to stop port enqueue
85334 + depending on the depletion status of selected BM pools.
85335 + It also defines the conditions to activate
85336 + this functionality. By default, this functionality is disabled.
85337 +
85338 + Note: Available for some chips only
85339 +
85340 + May be used for OP ports only
85341 +
85342 + @Param[in] h_FmPort A handle to a FM Port module.
85343 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
85344 +
85345 + @Return E_OK on success; Error code otherwise.
85346 +
85347 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85348 +*//***************************************************************************/
85349 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
85350 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
85351 +
85352 +/**************************************************************************//**
85353 + @Function FM_PORT_ConfigExtBufPools
85354 +
85355 + @Description This routine should be called for OP ports
85356 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
85357 + re-assembly, the FM needs new BM buffers. By calling this routine the user
85358 + specifies the BM buffer pools that should be used.
85359 +
85360 + Note: Available for some chips only
85361 +
85362 + May be used for OP ports only
85363 +
85364 + @Param[in] h_FmPort A handle to a FM Port module.
85365 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
85366 +
85367 + @Return E_OK on success; Error code otherwise.
85368 +
85369 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85370 +*//***************************************************************************/
85371 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
85372 +
85373 +/**************************************************************************//**
85374 + @Function FM_PORT_ConfigBackupPools
85375 +
85376 + @Description Calling this routine allows the configuration of some of the BM pools
85377 + defined for this port as backup pools.
85378 + A pool configured to be a backup pool will be used only if all other
85379 + enabled non-backup pools are depleted.
85380 +
85381 + May be used for Rx ports only
85382 +
85383 + @Param[in] h_FmPort A handle to a FM Port module.
85384 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
85385 + be defined as backup pools.
85386 +
85387 + @Return E_OK on success; Error code otherwise.
85388 +
85389 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85390 +*//***************************************************************************/
85391 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
85392 +
85393 +/**************************************************************************//**
85394 + @Function FM_PORT_ConfigFrmDiscardOverride
85395 +
85396 + @Description Calling this routine changes the error frames destination parameter
85397 + in the internal driver data base from its default configuration:
85398 + override = [DEFAULT_PORT_frmDiscardOverride]
85399 +
85400 + May be used for Rx and OP ports only
85401 +
85402 + @Param[in] h_FmPort A handle to a FM Port module.
85403 + @Param[in] override TRUE to override discarding of error frames and
85404 + enqueueing them to error queue.
85405 +
85406 + @Return E_OK on success; Error code otherwise.
85407 +
85408 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85409 +*//***************************************************************************/
85410 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
85411 +
85412 +/**************************************************************************//**
85413 + @Function FM_PORT_ConfigErrorsToDiscard
85414 +
85415 + @Description Calling this routine changes the behaviour on error parameter
85416 + in the internal driver data base from its default configuration:
85417 + [DEFAULT_PORT_errorsToDiscard].
85418 + If a requested error was previously defined as "ErrorsToEnqueue" it's
85419 + definition will change and the frame will be discarded.
85420 + Errors that were not defined either as "ErrorsToEnqueue" nor as
85421 + "ErrorsToDiscard", will be forwarded to CPU.
85422 +
85423 + May be used for Rx and OP ports only
85424 +
85425 + @Param[in] h_FmPort A handle to a FM Port module.
85426 + @Param[in] errs A list of errors to discard
85427 +
85428 + @Return E_OK on success; Error code otherwise.
85429 +
85430 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85431 +*//***************************************************************************/
85432 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
85433 +
85434 +/**************************************************************************//**
85435 + @Function FM_PORT_ConfigDmaSwapData
85436 +
85437 + @Description Calling this routine changes the DMA swap data aparameter
85438 + in the internal driver data base from its default
85439 + configuration [DEFAULT_PORT_dmaSwapData]
85440 +
85441 + May be used for all port types
85442 +
85443 + @Param[in] h_FmPort A handle to a FM Port module.
85444 + @Param[in] swapData New selection
85445 +
85446 + @Return E_OK on success; Error code otherwise.
85447 +
85448 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85449 +*//***************************************************************************/
85450 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
85451 +
85452 +/**************************************************************************//**
85453 + @Function FM_PORT_ConfigDmaIcCacheAttr
85454 +
85455 + @Description Calling this routine changes the internal context cache
85456 + attribute parameter in the internal driver data base
85457 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
85458 +
85459 + May be used for all port types
85460 +
85461 + @Param[in] h_FmPort A handle to a FM Port module.
85462 + @Param[in] intContextCacheAttr New selection
85463 +
85464 + @Return E_OK on success; Error code otherwise.
85465 +
85466 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85467 +*//***************************************************************************/
85468 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
85469 +
85470 +/**************************************************************************//**
85471 + @Function FM_PORT_ConfigDmaHdrAttr
85472 +
85473 + @Description Calling this routine changes the header cache
85474 + attribute parameter in the internal driver data base
85475 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
85476 +
85477 + May be used for all port types
85478 +
85479 + @Param[in] h_FmPort A handle to a FM Port module.
85480 + @Param[in] headerCacheAttr New selection
85481 +
85482 + @Return E_OK on success; Error code otherwise.
85483 +
85484 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85485 +*//***************************************************************************/
85486 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
85487 +
85488 +/**************************************************************************//**
85489 + @Function FM_PORT_ConfigDmaScatterGatherAttr
85490 +
85491 + @Description Calling this routine changes the scatter gather cache
85492 + attribute parameter in the internal driver data base
85493 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
85494 +
85495 + May be used for all port types
85496 +
85497 + @Param[in] h_FmPort A handle to a FM Port module.
85498 + @Param[in] scatterGatherCacheAttr New selection
85499 +
85500 + @Return E_OK on success; Error code otherwise.
85501 +
85502 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85503 +*//***************************************************************************/
85504 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
85505 +
85506 +/**************************************************************************//**
85507 + @Function FM_PORT_ConfigDmaWriteOptimize
85508 +
85509 + @Description Calling this routine changes the write optimization
85510 + parameter in the internal driver data base
85511 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
85512 + Note:
85513 +
85514 + 1. For head optimization, data alignment must be >= 16 (supported by default).
85515 +
85516 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
85517 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
85518 + is extended to be on 16/64 bytes aligned block (chip dependent).
85519 +
85520 + Relevant for non-Tx port types
85521 +
85522 + @Param[in] h_FmPort A handle to a FM Port module.
85523 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
85524 +
85525 + @Return E_OK on success; Error code otherwise.
85526 +
85527 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85528 +*//***************************************************************************/
85529 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
85530 +
85531 +/**************************************************************************//**
85532 + @Function FM_PORT_ConfigNoScatherGather
85533 +
85534 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
85535 + from its default configuration.
85536 +
85537 + @Param[in] h_FmPort A handle to a FM Port module.
85538 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
85539 + FALSE - frame can be stored in scatter gather (S/G) format).
85540 +
85541 + @Return E_OK on success; Error code otherwise.
85542 +
85543 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85544 +*//***************************************************************************/
85545 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
85546 +
85547 +/**************************************************************************//**
85548 + @Function FM_PORT_ConfigDfltColor
85549 +
85550 + @Description Calling this routine changes the internal default color parameter
85551 + in the internal driver data base
85552 + from its default configuration [DEFAULT_PORT_color]
85553 +
85554 + May be used for all port types
85555 +
85556 + @Param[in] h_FmPort A handle to a FM Port module.
85557 + @Param[in] color New selection
85558 +
85559 + @Return E_OK on success; Error code otherwise.
85560 +
85561 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85562 +*//***************************************************************************/
85563 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
85564 +
85565 +/**************************************************************************//**
85566 + @Function FM_PORT_ConfigSyncReq
85567 +
85568 + @Description Calling this routine changes the synchronization attribute parameter
85569 + in the internal driver data base from its default configuration:
85570 + syncReq = [DEFAULT_PORT_syncReq]
85571 +
85572 + May be used for all port types
85573 +
85574 + @Param[in] h_FmPort A handle to a FM Port module.
85575 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
85576 +
85577 + @Return E_OK on success; Error code otherwise.
85578 +
85579 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85580 +*//***************************************************************************/
85581 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
85582 +
85583 +/**************************************************************************//**
85584 + @Function FM_PORT_ConfigForwardReuseIntContext
85585 +
85586 + @Description This routine is relevant for Rx ports that are routed to OP port.
85587 + It changes the internal context reuse option in the internal
85588 + driver data base from its default configuration:
85589 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
85590 +
85591 + May be used for Rx ports only
85592 +
85593 + @Param[in] h_FmPort A handle to a FM Port module.
85594 + @Param[in] reuse TRUE to reuse internal context on frames
85595 + forwarded to OP port.
85596 +
85597 + @Return E_OK on success; Error code otherwise.
85598 +
85599 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85600 +*//***************************************************************************/
85601 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
85602 +
85603 +/**************************************************************************//**
85604 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
85605 +
85606 + @Description This routine should be called if no Tx confirmation
85607 + is done, and yet buffers should not be released to the BM.
85608 + Normally, buffers are returned using the Tx confirmation
85609 + process. When Tx confirmation is not used (defFqid=0),
85610 + buffers are typically released to the BM. This routine
85611 + may be called to avoid this behavior and not release the
85612 + buffers.
85613 +
85614 + May be used for Tx ports only
85615 +
85616 + @Param[in] h_FmPort A handle to a FM Port module.
85617 +
85618 + @Return E_OK on success; Error code otherwise.
85619 +
85620 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85621 +*//***************************************************************************/
85622 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
85623 +
85624 +/**************************************************************************//**
85625 + @Function FM_PORT_ConfigIMMaxRxBufLength
85626 +
85627 + @Description Changes the maximum receive buffer length from its default
85628 + configuration: Closest rounded down power of 2 value of the
85629 + data buffer size.
85630 +
85631 + The maximum receive buffer length directly affects the structure
85632 + of received frames (single- or multi-buffered) and the performance
85633 + of both the FM and the driver.
85634 +
85635 + The selection between single- or multi-buffered frames should be
85636 + done according to the characteristics of the specific application.
85637 + The recommended mode is to use a single data buffer per packet,
85638 + as this mode provides the best performance. However, the user can
85639 + select to use multiple data buffers per packet.
85640 +
85641 + @Param[in] h_FmPort A handle to a FM Port module.
85642 + @Param[in] newVal Maximum receive buffer length (in bytes).
85643 +
85644 + @Return E_OK on success; Error code otherwise.
85645 +
85646 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85647 + This routine is to be used only if Independent-Mode is enabled.
85648 +*//***************************************************************************/
85649 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
85650 +
85651 +/**************************************************************************//**
85652 + @Function FM_PORT_ConfigIMRxBdRingLength
85653 +
85654 + @Description Changes the receive BD ring length from its default
85655 + configuration:[DEFAULT_PORT_rxBdRingLength]
85656 +
85657 + @Param[in] h_FmPort A handle to a FM Port module.
85658 + @Param[in] newVal The desired BD ring length.
85659 +
85660 + @Return E_OK on success; Error code otherwise.
85661 +
85662 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85663 + This routine is to be used only if Independent-Mode is enabled.
85664 +*//***************************************************************************/
85665 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85666 +
85667 +/**************************************************************************//**
85668 + @Function FM_PORT_ConfigIMTxBdRingLength
85669 +
85670 + @Description Changes the transmit BD ring length from its default
85671 + configuration:[DEFAULT_PORT_txBdRingLength]
85672 +
85673 + @Param[in] h_FmPort A handle to a FM Port module.
85674 + @Param[in] newVal The desired BD ring length.
85675 +
85676 + @Return E_OK on success; Error code otherwise.
85677 +
85678 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85679 + This routine is to be used only if Independent-Mode is enabled.
85680 +*//***************************************************************************/
85681 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
85682 +
85683 +/**************************************************************************//**
85684 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
85685 +
85686 + @Description Configures memory partition and attributes for FMan-Controller
85687 + data structures (e.g. BD rings).
85688 + Calling this routine changes the internal driver data base
85689 + from its default configuration
85690 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
85691 +
85692 + @Param[in] h_FmPort A handle to a FM Port module.
85693 + @Param[in] memId Memory partition ID.
85694 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
85695 +
85696 + @Return E_OK on success; Error code otherwise.
85697 +*//***************************************************************************/
85698 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
85699 + uint8_t memId,
85700 + uint32_t memAttributes);
85701 +
85702 +/**************************************************************************//**
85703 + @Function FM_PORT_ConfigIMPolling
85704 +
85705 + @Description Changes the Rx flow from interrupt driven (default) to polling.
85706 +
85707 + @Param[in] h_FmPort A handle to a FM Port module.
85708 +
85709 + @Return E_OK on success; Error code otherwise.
85710 +
85711 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85712 + This routine is to be used only if Independent-Mode is enabled.
85713 +*//***************************************************************************/
85714 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
85715 +
85716 +/**************************************************************************//**
85717 + @Function FM_PORT_ConfigMaxFrameLength
85718 +
85719 + @Description Changes the definition of the max size of frame that should be
85720 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
85721 + This parameter is used for confirmation of the minimum Fifo
85722 + size calculations and only for Tx ports or ports working in
85723 + independent mode. This should be larger than the maximum possible
85724 + MTU that will be used for this port (i.e. its MAC).
85725 +
85726 + @Param[in] h_FmPort A handle to a FM Port module.
85727 + @Param[in] length Max size of frame
85728 +
85729 + @Return E_OK on success; Error code otherwise.
85730 +
85731 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85732 + This routine is to be used only if Independent-Mode is enabled.
85733 +*//***************************************************************************/
85734 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
85735 +
85736 +/**************************************************************************//*
85737 + @Function FM_PORT_ConfigTxFifoMinFillLevel
85738 +
85739 + @Description Calling this routine changes the fifo minimum
85740 + fill level parameter in the internal driver data base
85741 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
85742 +
85743 + May be used for Tx ports only
85744 +
85745 + @Param[in] h_FmPort A handle to a FM Port module.
85746 + @Param[in] minFillLevel New value
85747 +
85748 + @Return E_OK on success; Error code otherwise.
85749 +
85750 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85751 +*//***************************************************************************/
85752 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
85753 +
85754 +/**************************************************************************//*
85755 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
85756 +
85757 + @Description Calling this routine changes the fifo dequeue
85758 + pipeline depth parameter in the internal driver data base
85759 +
85760 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
85761 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
85762 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
85763 +
85764 + May be used for Tx/OP ports only
85765 +
85766 + @Param[in] h_FmPort A handle to a FM Port module.
85767 + @Param[in] deqPipelineDepth New value
85768 +
85769 + @Return E_OK on success; Error code otherwise.
85770 +
85771 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85772 +*//***************************************************************************/
85773 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
85774 +
85775 +/**************************************************************************//*
85776 + @Function FM_PORT_ConfigTxFifoLowComfLevel
85777 +
85778 + @Description Calling this routine changes the fifo low comfort level
85779 + parameter in internal driver data base
85780 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
85781 +
85782 + May be used for Tx ports only
85783 +
85784 + @Param[in] h_FmPort A handle to a FM Port module.
85785 + @Param[in] fifoLowComfLevel New value
85786 +
85787 + @Return E_OK on success; Error code otherwise.
85788 +
85789 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85790 +*//***************************************************************************/
85791 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
85792 +
85793 +/**************************************************************************//*
85794 + @Function FM_PORT_ConfigRxFifoThreshold
85795 +
85796 + @Description Calling this routine changes the threshold of the FIFO
85797 + fill level parameter in the internal driver data base
85798 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
85799 +
85800 + If the total number of buffers which are
85801 + currently in use and associated with the
85802 + specific RX port exceed this threshold, the
85803 + BMI will signal the MAC to send a pause frame
85804 + over the link.
85805 +
85806 + May be used for Rx ports only
85807 +
85808 + @Param[in] h_FmPort A handle to a FM Port module.
85809 + @Param[in] fifoThreshold New value
85810 +
85811 + @Return E_OK on success; Error code otherwise.
85812 +
85813 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85814 +*//***************************************************************************/
85815 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
85816 +
85817 +/**************************************************************************//*
85818 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
85819 +
85820 + @Description Calling this routine changes the priority elevation level
85821 + parameter in the internal driver data base from its default
85822 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
85823 +
85824 + If the total number of buffers which are currently in use and
85825 + associated with the specific RX port exceed the amount specified
85826 + in priElevationLevel, BMI will signal the main FM's DMA to
85827 + elevate the FM priority on the system bus.
85828 +
85829 + May be used for Rx ports only
85830 +
85831 + @Param[in] h_FmPort A handle to a FM Port module.
85832 + @Param[in] priElevationLevel New value
85833 +
85834 + @Return E_OK on success; Error code otherwise.
85835 +
85836 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85837 +*//***************************************************************************/
85838 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
85839 +
85840 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
85841 +/**************************************************************************//*
85842 + @Function FM_PORT_ConfigBCBWorkaround
85843 +
85844 + @Description Configures BCB errata workaround.
85845 +
85846 + When BCB errata is applicable, the workaround is always
85847 + performed by FM Controller. Thus, this functions doesn't
85848 + actually enable errata workaround but rather allows driver
85849 + to perform adjustments required due to errata workaround
85850 + execution in FM controller.
85851 +
85852 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
85853 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
85854 + set by FM_PORT_SetErrorsRoute() function.
85855 +
85856 + @Param[in] h_FmPort A handle to a FM Port module.
85857 +
85858 + @Return E_OK on success; Error code otherwise.
85859 +
85860 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85861 +*//***************************************************************************/
85862 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
85863 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
85864 +
85865 +#if (DPAA_VERSION >= 11)
85866 +/**************************************************************************//*
85867 + @Function FM_PORT_ConfigInternalBuffOffset
85868 +
85869 + @Description Configures internal buffer offset.
85870 +
85871 + May be used for Rx and OP ports only
85872 +
85873 + @Param[in] h_FmPort A handle to a FM Port module.
85874 + @Param[in] val New value
85875 +
85876 + @Return E_OK on success; Error code otherwise.
85877 +
85878 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
85879 +*//***************************************************************************/
85880 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
85881 +#endif /* (DPAA_VERSION >= 11) */
85882 +
85883 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
85884 +/** @} */ /* end of FM_PORT_init_grp group */
85885 +
85886 +
85887 +/**************************************************************************//**
85888 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
85889 +
85890 + @Description FM Port Runtime control unit API functions, definitions and enums.
85891 +
85892 + @{
85893 +*//***************************************************************************/
85894 +
85895 +/**************************************************************************//**
85896 + @Description enum for defining FM Port counters
85897 +*//***************************************************************************/
85898 +typedef enum e_FmPortCounters {
85899 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
85900 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
85901 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
85902 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
85903 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
85904 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
85905 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
85906 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
85907 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
85908 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
85909 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
85910 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
85911 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
85912 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
85913 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
85914 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
85915 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
85916 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
85917 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
85918 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
85919 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
85920 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
85921 +} e_FmPortCounters;
85922 +
85923 +typedef struct t_FmPortBmiStats {
85924 + uint32_t cntCycle;
85925 + uint32_t cntTaskUtil;
85926 + uint32_t cntQueueUtil;
85927 + uint32_t cntDmaUtil;
85928 + uint32_t cntFifoUtil;
85929 + uint32_t cntRxPauseActivation;
85930 + uint32_t cntFrame;
85931 + uint32_t cntDiscardFrame;
85932 + uint32_t cntDeallocBuf;
85933 + uint32_t cntRxBadFrame;
85934 + uint32_t cntRxLargeFrame;
85935 + uint32_t cntRxFilterFrame;
85936 + uint32_t cntRxListDmaErr;
85937 + uint32_t cntRxOutOfBuffersDiscard;
85938 + uint32_t cntWredDiscard;
85939 + uint32_t cntLengthErr;
85940 + uint32_t cntUnsupportedFormat;
85941 +} t_FmPortBmiStats;
85942 +
85943 +/**************************************************************************//**
85944 + @Description Structure for Port id parameters.
85945 + Fields commented 'IN' are passed by the port module to be used
85946 + by the FM module.
85947 + Fields commented 'OUT' will be filled by FM before returning to port.
85948 +*//***************************************************************************/
85949 +typedef struct t_FmPortCongestionGrps {
85950 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
85951 + to define the size of the following array */
85952 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
85953 + /**< An array of CG indexes;
85954 + Note that the size of the array should be
85955 + 'numOfCongestionGrpsToConsider'. */
85956 +#if (DPAA_VERSION >= 11)
85957 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
85958 + /**< a matrix that represents the map between the CG ids
85959 + defined in 'congestionGrpsToConsider' to the priorties
85960 + mapping array. */
85961 +#endif /* (DPAA_VERSION >= 11) */
85962 +} t_FmPortCongestionGrps;
85963 +
85964 +/**************************************************************************//**
85965 + @Description Structure for Deep Sleep Auto Response ARP Entry
85966 +*//***************************************************************************/
85967 +typedef struct t_FmPortDsarArpEntry
85968 +{
85969 + uint32_t ipAddress;
85970 + uint8_t mac[6];
85971 + bool isVlan;
85972 + uint16_t vid;
85973 +} t_FmPortDsarArpEntry;
85974 +
85975 +/**************************************************************************//**
85976 + @Description Structure for Deep Sleep Auto Response ARP info
85977 +*//***************************************************************************/
85978 +typedef struct t_FmPortDsarArpInfo
85979 +{
85980 + uint8_t tableSize;
85981 + t_FmPortDsarArpEntry *p_AutoResTable;
85982 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
85983 +} t_FmPortDsarArpInfo;
85984 +
85985 +/**************************************************************************//**
85986 + @Description Structure for Deep Sleep Auto Response NDP Entry
85987 +*//***************************************************************************/
85988 +typedef struct t_FmPortDsarNdpEntry
85989 +{
85990 + uint32_t ipAddress[4];
85991 + uint8_t mac[6];
85992 + bool isVlan;
85993 + uint16_t vid;
85994 +} t_FmPortDsarNdpEntry;
85995 +
85996 +/**************************************************************************//**
85997 + @Description Structure for Deep Sleep Auto Response NDP info
85998 +*//***************************************************************************/
85999 +typedef struct t_FmPortDsarNdpInfo
86000 +{
86001 + uint32_t multicastGroup;
86002 +
86003 + uint8_t tableSizeAssigned;
86004 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
86005 + Note that all IP adresses must be from the same multicast group.
86006 + This will be checked and if not operation will fail. */
86007 + uint8_t tableSizeTmp;
86008 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
86009 + Note that all temp IP adresses must be from the same multicast group.
86010 + This will be checked and if not operation will fail. */
86011 +
86012 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
86013 +
86014 +} t_FmPortDsarNdpInfo;
86015 +
86016 +/**************************************************************************//**
86017 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
86018 +*//***************************************************************************/
86019 +typedef struct t_FmPortDsarEchoIpv4Info
86020 +{
86021 + uint8_t tableSize;
86022 + t_FmPortDsarArpEntry *p_AutoResTable;
86023 +} t_FmPortDsarEchoIpv4Info;
86024 +
86025 +/**************************************************************************//**
86026 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
86027 +*//***************************************************************************/
86028 +typedef struct t_FmPortDsarEchoIpv6Info
86029 +{
86030 + uint8_t tableSize;
86031 + t_FmPortDsarNdpEntry *p_AutoResTable;
86032 +} t_FmPortDsarEchoIpv6Info;
86033 +
86034 +/**************************************************************************//**
86035 +@Description Deep Sleep Auto Response SNMP OIDs table entry
86036 +
86037 +*//***************************************************************************/
86038 +typedef struct {
86039 + uint16_t oidSize;
86040 + uint8_t *oidVal; /* only the oid string */
86041 + uint16_t resSize;
86042 + uint8_t *resVal; /* resVal will be the entire reply,
86043 + i.e. "Type|Length|Value" */
86044 +} t_FmPortDsarOidsEntry;
86045 +
86046 +/**************************************************************************//**
86047 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
86048 + Refer to the FMan Controller spec for more details.
86049 +*//***************************************************************************/
86050 +typedef struct
86051 +{
86052 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
86053 + bool isVlan;
86054 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86055 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86056 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
86057 +
86058 +/**************************************************************************//**
86059 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
86060 + Refer to the FMan Controller spec for more details.
86061 +*//***************************************************************************/
86062 +typedef struct
86063 +{
86064 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
86065 + bool isVlan;
86066 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
86067 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
86068 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
86069 +
86070 +/**************************************************************************//**
86071 + @Description Deep Sleep Auto Response SNMP Descriptor
86072 +
86073 +*//***************************************************************************/
86074 +typedef struct
86075 +{
86076 + uint16_t control; /**< Control bits [0-15]. */
86077 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
86078 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
86079 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
86080 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
86081 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
86082 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
86083 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
86084 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
86085 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
86086 +} t_FmPortDsarSnmpInfo;
86087 +
86088 +/**************************************************************************//**
86089 + @Description Structure for Deep Sleep Auto Response filtering Entry
86090 +*//***************************************************************************/
86091 +typedef struct t_FmPortDsarFilteringEntry
86092 +{
86093 + uint16_t srcPort;
86094 + uint16_t dstPort;
86095 + uint16_t srcPortMask;
86096 + uint16_t dstPortMask;
86097 +} t_FmPortDsarFilteringEntry;
86098 +
86099 +/**************************************************************************//**
86100 + @Description Structure for Deep Sleep Auto Response filtering info
86101 +*//***************************************************************************/
86102 +typedef struct t_FmPortDsarFilteringInfo
86103 +{
86104 + /* IP protocol filtering parameters */
86105 + uint8_t ipProtTableSize;
86106 + uint8_t *p_IpProtTablePtr;
86107 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86108 + hit will pass the packet to UDP/TCP filters if needed and if not
86109 + to the classification tree. If the classification tree will pass
86110 + the packet to a queue it will cause a wake interupt.
86111 + When FALSE it the other way around. */
86112 + /* UDP port filtering parameters */
86113 + uint8_t udpPortsTableSize;
86114 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
86115 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86116 + hit will pass the packet to classification tree.
86117 + If the classification tree will pass the packet to a queue it
86118 + will cause a wake interupt.
86119 + When FALSE it the other way around. */
86120 + /* TCP port filtering parameters */
86121 + uint16_t tcpFlagsMask;
86122 + uint8_t tcpPortsTableSize;
86123 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
86124 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
86125 + hit will pass the packet to classification tree.
86126 + If the classification tree will pass the packet to a queue it
86127 + will cause a wake interupt.
86128 + When FALSE it the other way around. */
86129 +} t_FmPortDsarFilteringInfo;
86130 +
86131 +/**************************************************************************//**
86132 + @Description Structure for Deep Sleep Auto Response parameters
86133 +*//***************************************************************************/
86134 +typedef struct t_FmPortDsarParams
86135 +{
86136 + t_Handle h_FmPortTx;
86137 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
86138 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
86139 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
86140 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
86141 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
86142 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
86143 +} t_FmPortDsarParams;
86144 +
86145 +/**************************************************************************//**
86146 + @Function FM_PORT_EnterDsar
86147 +
86148 + @Description Enter Deep Sleep Auto Response mode.
86149 + This function write the apropriate values to in the relevant
86150 + tables in the MURAM.
86151 +
86152 + @Param[in] h_FmPortRx - FM PORT module descriptor
86153 + @Param[in] params - Auto Response parameters
86154 +
86155 + @Return E_OK on success; Error code otherwise.
86156 +
86157 + @Cautions Allowed only following FM_PORT_Init().
86158 +*//***************************************************************************/
86159 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
86160 +
86161 +/**************************************************************************//**
86162 + @Function FM_PORT_EnterDsarFinal
86163 +
86164 + @Description Enter Deep Sleep Auto Response mode.
86165 + This function sets the Tx port in independent mode as needed
86166 + and redirect the receive flow to go through the
86167 + Dsar Fman-ctrl code
86168 +
86169 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
86170 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
86171 +
86172 + @Return E_OK on success; Error code otherwise.
86173 +
86174 + @Cautions Allowed only following FM_PORT_Init().
86175 +*//***************************************************************************/
86176 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
86177 +
86178 +/**************************************************************************//**
86179 + @Function FM_PORT_ExitDsar
86180 +
86181 + @Description Exit Deep Sleep Auto Response mode.
86182 + This function reverse the AR mode and put the ports back into
86183 + their original wake mode
86184 +
86185 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
86186 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
86187 +
86188 + @Return E_OK on success; Error code otherwise.
86189 +
86190 + @Cautions Allowed only following FM_PORT_EnterDsar().
86191 +*//***************************************************************************/
86192 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
86193 +
86194 +/**************************************************************************//**
86195 + @Function FM_PORT_IsInDsar
86196 +
86197 + @Description This function returns TRUE if the port was set as Auto Response
86198 + and FALSE if not. Once Exit AR mode it will return FALSE as well
86199 + until re-enabled once more.
86200 +
86201 + @Param[in] h_FmPort - FM PORT module descriptor
86202 +
86203 + @Return E_OK on success; Error code otherwise.
86204 +*//***************************************************************************/
86205 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
86206 +
86207 +typedef struct t_FmPortDsarStats
86208 +{
86209 + uint32_t arpArCnt;
86210 + uint32_t echoIcmpv4ArCnt;
86211 + uint32_t ndpArCnt;
86212 + uint32_t echoIcmpv6ArCnt;
86213 + uint32_t snmpGetCnt;
86214 + uint32_t snmpGetNextCnt;
86215 +} t_FmPortDsarStats;
86216 +
86217 +/**************************************************************************//**
86218 + @Function FM_PORT_GetDsarStats
86219 +
86220 + @Description Return statistics for Deep Sleep Auto Response
86221 +
86222 + @Param[in] h_FmPortRx - FM PORT module descriptor
86223 + @Param[out] stats - structure containing the statistics counters
86224 +
86225 + @Return E_OK on success; Error code otherwise.
86226 +*//***************************************************************************/
86227 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
86228 +
86229 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
86230 +/**************************************************************************//**
86231 + @Function FM_PORT_DumpRegs
86232 +
86233 + @Description Dump all regs.
86234 +
86235 + Calling this routine invalidates the descriptor.
86236 +
86237 + @Param[in] h_FmPort - FM PORT module descriptor
86238 +
86239 + @Return E_OK on success; Error code otherwise.
86240 +
86241 + @Cautions Allowed only following FM_PORT_Init().
86242 +*//***************************************************************************/
86243 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
86244 +#endif /* (defined(DEBUG_ERRORS) && ... */
86245 +
86246 +/**************************************************************************//**
86247 + @Function FM_PORT_GetBufferDataOffset
86248 +
86249 + @Description Relevant for Rx ports.
86250 + Returns the data offset from the beginning of the data buffer
86251 +
86252 + @Param[in] h_FmPort - FM PORT module descriptor
86253 +
86254 + @Return data offset.
86255 +
86256 + @Cautions Allowed only following FM_PORT_Init().
86257 +*//***************************************************************************/
86258 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
86259 +
86260 +/**************************************************************************//**
86261 + @Function FM_PORT_GetBufferICInfo
86262 +
86263 + @Description Returns the Internal Context offset from the beginning of the data buffer
86264 +
86265 + @Param[in] h_FmPort - FM PORT module descriptor
86266 + @Param[in] p_Data - A pointer to the data buffer.
86267 +
86268 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
86269 + configured for this port.
86270 +
86271 + @Cautions Allowed only following FM_PORT_Init().
86272 +*//***************************************************************************/
86273 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
86274 +
86275 +/**************************************************************************//**
86276 + @Function FM_PORT_GetBufferPrsResult
86277 +
86278 + @Description Returns the pointer to the parse result in the data buffer.
86279 + In Rx ports this is relevant after reception, if parse
86280 + result is configured to be part of the data passed to the
86281 + application. For non Rx ports it may be used to get the pointer
86282 + of the area in the buffer where parse result should be
86283 + initialized - if so configured.
86284 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86285 + configuration.
86286 +
86287 + @Param[in] h_FmPort - FM PORT module descriptor
86288 + @Param[in] p_Data - A pointer to the data buffer.
86289 +
86290 + @Return Parse result pointer on success, NULL if parse result was not
86291 + configured for this port.
86292 +
86293 + @Cautions Allowed only following FM_PORT_Init().
86294 +*//***************************************************************************/
86295 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
86296 +
86297 +/**************************************************************************//**
86298 + @Function FM_PORT_GetBufferTimeStamp
86299 +
86300 + @Description Returns the time stamp in the data buffer.
86301 + Relevant for Rx ports for getting the buffer time stamp.
86302 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
86303 + configuration.
86304 +
86305 + @Param[in] h_FmPort - FM PORT module descriptor
86306 + @Param[in] p_Data - A pointer to the data buffer.
86307 +
86308 + @Return A pointer to the hash result on success, NULL otherwise.
86309 +
86310 + @Cautions Allowed only following FM_PORT_Init().
86311 +*//***************************************************************************/
86312 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
86313 +
86314 +/**************************************************************************//**
86315 + @Function FM_PORT_GetBufferHashResult
86316 +
86317 + @Description Given a data buffer, on the condition that hash result was defined
86318 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
86319 + this routine will return the pointer to the hash result location in the
86320 + buffer prefix.
86321 +
86322 + @Param[in] h_FmPort - FM PORT module descriptor
86323 + @Param[in] p_Data - A pointer to the data buffer.
86324 +
86325 + @Return A pointer to the hash result on success, NULL otherwise.
86326 +
86327 + @Cautions Allowed only following FM_PORT_Init().
86328 +*//***************************************************************************/
86329 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
86330 +
86331 +/**************************************************************************//**
86332 + @Function FM_PORT_Disable
86333 +
86334 + @Description Gracefully disable an FM port. The port will not start new tasks after all
86335 + tasks associated with the port are terminated.
86336 +
86337 + @Param[in] h_FmPort A handle to a FM Port module.
86338 +
86339 + @Return E_OK on success; Error code otherwise.
86340 +
86341 + @Cautions Allowed only following FM_PORT_Init().
86342 + This is a blocking routine, it returns after port is
86343 + gracefully stopped, i.e. the port will not except new frames,
86344 + but it will finish all frames or tasks which were already began
86345 +*//***************************************************************************/
86346 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
86347 +
86348 +/**************************************************************************//**
86349 + @Function FM_PORT_Enable
86350 +
86351 + @Description A runtime routine provided to allow disable/enable of port.
86352 +
86353 + @Param[in] h_FmPort A handle to a FM Port module.
86354 +
86355 + @Return E_OK on success; Error code otherwise.
86356 +
86357 + @Cautions Allowed only following FM_PORT_Init().
86358 +*//***************************************************************************/
86359 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
86360 +
86361 +/**************************************************************************//**
86362 + @Function FM_PORT_SetRateLimit
86363 +
86364 + @Description Calling this routine enables rate limit algorithm.
86365 + By default, this functionality is disabled.
86366 + Note that rate-limit mechanism uses the FM time stamp.
86367 + The selected rate limit specified here would be
86368 + rounded DOWN to the nearest 16M.
86369 +
86370 + May be used for Tx and OP ports only
86371 +
86372 + @Param[in] h_FmPort A handle to a FM Port module.
86373 + @Param[in] p_RateLimit A structure of rate limit parameters
86374 +
86375 + @Return E_OK on success; Error code otherwise.
86376 +
86377 + @Cautions Allowed only following FM_PORT_Init().
86378 + If rate limit is set on a port that need to send PFC frames,
86379 + it might violate the stop transmit timing.
86380 +*//***************************************************************************/
86381 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
86382 +
86383 +/**************************************************************************//**
86384 + @Function FM_PORT_DeleteRateLimit
86385 +
86386 + @Description Calling this routine disables and clears rate limit
86387 + initialization.
86388 +
86389 + May be used for Tx and OP ports only
86390 +
86391 + @Param[in] h_FmPort A handle to a FM Port module.
86392 +
86393 + @Return E_OK on success; Error code otherwise.
86394 +
86395 + @Cautions Allowed only following FM_PORT_Init().
86396 +*//***************************************************************************/
86397 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
86398 +
86399 +/**************************************************************************//**
86400 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
86401 +
86402 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
86403 + This WQ will be blocked upon receiving a PFC frame with this priority.
86404 +
86405 + May be used for Tx ports only.
86406 +
86407 + @Param[in] h_FmPort A handle to a FM Port module.
86408 + @Param[in] prio PFC priority (0-7).
86409 + @Param[in] wq Work Queue (0-7).
86410 +
86411 + @Return E_OK on success; Error code otherwise.
86412 +
86413 + @Cautions Allowed only following FM_PORT_Init().
86414 +*//***************************************************************************/
86415 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
86416 +
86417 +/**************************************************************************//**
86418 + @Function FM_PORT_SetStatisticsCounters
86419 +
86420 + @Description Calling this routine enables/disables port's statistics counters.
86421 + By default, counters are enabled.
86422 +
86423 + May be used for all port types
86424 +
86425 + @Param[in] h_FmPort A handle to a FM Port module.
86426 + @Param[in] enable TRUE to enable, FALSE to disable.
86427 +
86428 + @Return E_OK on success; Error code otherwise.
86429 +
86430 + @Cautions Allowed only following FM_PORT_Init().
86431 +*//***************************************************************************/
86432 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
86433 +
86434 +/**************************************************************************//**
86435 + @Function FM_PORT_SetFrameQueueCounters
86436 +
86437 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
86438 + By default, counters are enabled.
86439 +
86440 + May be used for all ports
86441 +
86442 + @Param[in] h_FmPort A handle to a FM Port module.
86443 + @Param[in] enable TRUE to enable, FALSE to disable.
86444 +
86445 + @Return E_OK on success; Error code otherwise.
86446 +
86447 + @Cautions Allowed only following FM_PORT_Init().
86448 +*//***************************************************************************/
86449 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
86450 +
86451 +/**************************************************************************//**
86452 + @Function FM_PORT_AnalyzePerformanceParams
86453 +
86454 + @Description User may call this routine to so the driver will analyze if the
86455 + basic performance parameters are correct and also the driver may
86456 + suggest of improvements; The basic parameters are FIFO sizes, number
86457 + of DMAs and number of TNUMs for the port.
86458 +
86459 + May be used for all port types
86460 +
86461 + @Param[in] h_FmPort A handle to a FM Port module.
86462 +
86463 + @Return E_OK on success; Error code otherwise.
86464 +
86465 + @Cautions Allowed only following FM_PORT_Init().
86466 +*//***************************************************************************/
86467 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
86468 +
86469 +
86470 +/**************************************************************************//**
86471 + @Function FM_PORT_SetAllocBufCounter
86472 +
86473 + @Description Calling this routine enables/disables BM pool allocate
86474 + buffer counters.
86475 + By default, counters are enabled.
86476 +
86477 + May be used for Rx ports only
86478 +
86479 + @Param[in] h_FmPort A handle to a FM Port module.
86480 + @Param[in] poolId BM pool id.
86481 + @Param[in] enable TRUE to enable, FALSE to disable.
86482 +
86483 + @Return E_OK on success; Error code otherwise.
86484 +
86485 + @Cautions Allowed only following FM_PORT_Init().
86486 +*//***************************************************************************/
86487 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
86488 +
86489 +/**************************************************************************//**
86490 + @Function FM_PORT_GetBmiCounters
86491 +
86492 + @Description Read port's BMI stat counters and place them into
86493 + a designated structure of counters.
86494 +
86495 + @Param[in] h_FmPort A handle to a FM Port module.
86496 + @Param[out] p_BmiStats counters structure
86497 +
86498 + @Return E_OK on success; Error code otherwise.
86499 +
86500 + @Cautions Allowed only following FM_PORT_Init().
86501 +*//***************************************************************************/
86502 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
86503 +
86504 +/**************************************************************************//**
86505 + @Function FM_PORT_GetCounter
86506 +
86507 + @Description Reads one of the FM PORT counters.
86508 +
86509 + @Param[in] h_FmPort A handle to a FM Port module.
86510 + @Param[in] fmPortCounter The requested counter.
86511 +
86512 + @Return Counter's current value.
86513 +
86514 + @Cautions Allowed only following FM_PORT_Init().
86515 + Note that it is user's responsibility to call this routine only
86516 + for enabled counters, and there will be no indication if a
86517 + disabled counter is accessed.
86518 +*//***************************************************************************/
86519 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
86520 +
86521 +/**************************************************************************//**
86522 + @Function FM_PORT_ModifyCounter
86523 +
86524 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86525 +
86526 + @Param[in] h_FmPort A handle to a FM Port module.
86527 + @Param[in] fmPortCounter The requested counter.
86528 + @Param[in] value The requested value to be written into the counter.
86529 +
86530 + @Return E_OK on success; Error code otherwise.
86531 +
86532 + @Cautions Allowed only following FM_PORT_Init().
86533 +*//***************************************************************************/
86534 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
86535 +
86536 +/**************************************************************************//**
86537 + @Function FM_PORT_GetAllocBufCounter
86538 +
86539 + @Description Reads one of the FM PORT buffer counters.
86540 +
86541 + @Param[in] h_FmPort A handle to a FM Port module.
86542 + @Param[in] poolId The requested pool.
86543 +
86544 + @Return Counter's current value.
86545 +
86546 + @Cautions Allowed only following FM_PORT_Init().
86547 + Note that it is user's responsibility to call this routine only
86548 + for enabled counters, and there will be no indication if a
86549 + disabled counter is accessed.
86550 +*//***************************************************************************/
86551 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
86552 +
86553 +/**************************************************************************//**
86554 + @Function FM_PORT_ModifyAllocBufCounter
86555 +
86556 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
86557 +
86558 + @Param[in] h_FmPort A handle to a FM Port module.
86559 + @Param[in] poolId The requested pool.
86560 + @Param[in] value The requested value to be written into the counter.
86561 +
86562 + @Return E_OK on success; Error code otherwise.
86563 +
86564 + @Cautions Allowed only following FM_PORT_Init().
86565 +*//***************************************************************************/
86566 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
86567 +
86568 +/**************************************************************************//**
86569 + @Function FM_PORT_AddCongestionGrps
86570 +
86571 + @Description This routine effects the corresponding Tx port.
86572 + It should be called in order to enable pause
86573 + frame transmission in case of congestion in one or more
86574 + of the congestion groups relevant to this port.
86575 + Each call to this routine may add one or more congestion
86576 + groups to be considered relevant to this port.
86577 +
86578 + May be used for Rx, or RX+OP ports only (depending on chip)
86579 +
86580 + @Param[in] h_FmPort A handle to a FM Port module.
86581 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86582 + id's to consider.
86583 +
86584 + @Return E_OK on success; Error code otherwise.
86585 +
86586 + @Cautions Allowed only following FM_PORT_Init().
86587 +*//***************************************************************************/
86588 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86589 +
86590 +/**************************************************************************//**
86591 + @Function FM_PORT_RemoveCongestionGrps
86592 +
86593 + @Description This routine effects the corresponding Tx port. It should be
86594 + called when congestion groups were
86595 + defined for this port and are no longer relevant, or pause
86596 + frames transmitting is not required on their behalf.
86597 + Each call to this routine may remove one or more congestion
86598 + groups to be considered relevant to this port.
86599 +
86600 + May be used for Rx, or RX+OP ports only (depending on chip)
86601 +
86602 + @Param[in] h_FmPort A handle to a FM Port module.
86603 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
86604 + id's to consider.
86605 +
86606 + @Return E_OK on success; Error code otherwise.
86607 +
86608 + @Cautions Allowed only following FM_PORT_Init().
86609 +*//***************************************************************************/
86610 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
86611 +
86612 +/**************************************************************************//**
86613 + @Function FM_PORT_IsStalled
86614 +
86615 + @Description A routine for checking whether the specified port is stalled.
86616 +
86617 + @Param[in] h_FmPort A handle to a FM Port module.
86618 +
86619 + @Return TRUE if port is stalled, FALSE otherwize
86620 +
86621 + @Cautions Allowed only following FM_PORT_Init().
86622 +*//***************************************************************************/
86623 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
86624 +
86625 +/**************************************************************************//**
86626 + @Function FM_PORT_ReleaseStalled
86627 +
86628 + @Description This routine may be called in case the port was stalled and may
86629 + now be released.
86630 + Note that this routine is available only on older FMan revisions
86631 + (FMan v2, DPAA v1.0 only).
86632 +
86633 + @Param[in] h_FmPort A handle to a FM Port module.
86634 +
86635 + @Return E_OK on success; Error code otherwise.
86636 +
86637 + @Cautions Allowed only following FM_PORT_Init().
86638 +*//***************************************************************************/
86639 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
86640 +
86641 +/**************************************************************************//**
86642 + @Function FM_PORT_SetRxL4ChecksumVerify
86643 +
86644 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
86645 + set/clear the L3/L4 checksum verification (on RX side).
86646 + Note that this takes affect only if hw-parser is enabled!
86647 +
86648 + @Param[in] h_FmPort A handle to a FM Port module.
86649 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
86650 + on frames or not.
86651 +
86652 + @Return E_OK on success; Error code otherwise.
86653 +
86654 + @Cautions Allowed only following FM_PORT_Init().
86655 +*//***************************************************************************/
86656 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
86657 +
86658 +/**************************************************************************//**
86659 + @Function FM_PORT_SetErrorsRoute
86660 +
86661 + @Description Errors selected for this routine will cause a frame with that error
86662 + to be enqueued to error queue.
86663 + Errors not selected for this routine will cause a frame with that error
86664 + to be enqueued to the one of the other port queues.
86665 + By default all errors are defined to be enqueued to error queue.
86666 + Errors that were configured to be discarded (at initialization)
86667 + may not be selected here.
86668 +
86669 + May be used for Rx and OP ports only
86670 +
86671 + @Param[in] h_FmPort A handle to a FM Port module.
86672 + @Param[in] errs A list of errors to enqueue to error queue
86673 +
86674 + @Return E_OK on success; Error code otherwise.
86675 +
86676 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86677 +*//***************************************************************************/
86678 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
86679 +
86680 +/**************************************************************************//**
86681 + @Function FM_PORT_SetIMExceptions
86682 +
86683 + @Description Calling this routine enables/disables FM PORT interrupts.
86684 +
86685 + @Param[in] h_FmPort FM PORT module descriptor.
86686 + @Param[in] exception The exception to be selected.
86687 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
86688 +
86689 + @Return E_OK on success; Error code otherwise.
86690 +
86691 + @Cautions Allowed only following FM_PORT_Init().
86692 + This routine should NOT be called from guest-partition
86693 + (i.e. guestId != NCSW_MASTER_ID)
86694 +*//***************************************************************************/
86695 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
86696 +
86697 +/**************************************************************************//*
86698 + @Function FM_PORT_SetPerformanceCounters
86699 +
86700 + @Description Calling this routine enables/disables port's performance counters.
86701 + By default, counters are enabled.
86702 +
86703 + May be used for all port types
86704 +
86705 + @Param[in] h_FmPort A handle to a FM Port module.
86706 + @Param[in] enable TRUE to enable, FALSE to disable.
86707 +
86708 + @Return E_OK on success; Error code otherwise.
86709 +
86710 + @Cautions Allowed only following FM_PORT_Init().
86711 +*//***************************************************************************/
86712 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
86713 +
86714 +/**************************************************************************//*
86715 + @Function FM_PORT_SetPerformanceCountersParams
86716 +
86717 + @Description Calling this routine defines port's performance
86718 + counters parameters.
86719 +
86720 + May be used for all port types
86721 +
86722 + @Param[in] h_FmPort A handle to a FM Port module.
86723 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
86724 + counters parameters.
86725 +
86726 + @Return E_OK on success; Error code otherwise.
86727 +
86728 + @Cautions Allowed only following FM_PORT_Init().
86729 +*//***************************************************************************/
86730 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
86731 +
86732 +/**************************************************************************//**
86733 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
86734 +
86735 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
86736 +
86737 + @{
86738 +*//***************************************************************************/
86739 +
86740 +/**************************************************************************//**
86741 + @Description A structure defining the KG scheme after the parser.
86742 + This is relevant only to change scheme selection mode - from
86743 + direct to indirect and vice versa, or when the scheme is selected directly,
86744 + to select the scheme id.
86745 +
86746 +*//***************************************************************************/
86747 +typedef struct t_FmPcdKgSchemeSelect {
86748 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
86749 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
86750 + Relevant only when 'direct' is TRUE. */
86751 +} t_FmPcdKgSchemeSelect;
86752 +
86753 +/**************************************************************************//**
86754 + @Description A structure of scheme parameters
86755 +*//***************************************************************************/
86756 +typedef struct t_FmPcdPortSchemesParams {
86757 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86758 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
86759 + port to be bound to */
86760 +} t_FmPcdPortSchemesParams;
86761 +
86762 +/**************************************************************************//**
86763 + @Description Union for defining port protocol parameters for parser
86764 +*//***************************************************************************/
86765 +typedef union u_FmPcdHdrPrsOpts {
86766 + /* MPLS */
86767 + struct {
86768 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
86769 + interpreted as described in HW spec table. When the bit
86770 + is cleared, the parser will advance to MPLS next parse */
86771 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
86772 + } mplsPrsOptions;
86773 + /* VLAN */
86774 + struct {
86775 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
86776 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86777 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
86778 + on VLAN TAG on top of 0x8100 and 0x88A8 */
86779 + } vlanPrsOptions;
86780 + /* PPP */
86781 + struct{
86782 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
86783 + } pppoePrsOptions;
86784 +
86785 + /* IPV6 */
86786 + struct{
86787 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
86788 + } ipv6PrsOptions;
86789 +
86790 + /* UDP */
86791 + struct{
86792 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86793 + } udpPrsOptions;
86794 +
86795 + /* TCP */
86796 + struct {
86797 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
86798 + } tcpPrsOptions;
86799 +} u_FmPcdHdrPrsOpts;
86800 +
86801 +/**************************************************************************//**
86802 + @Description A structure for defining each header for the parser
86803 +*//***************************************************************************/
86804 +typedef struct t_FmPcdPrsAdditionalHdrParams {
86805 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
86806 + to indicate that sw parser is to run first
86807 + (before HW parser, and independent of the
86808 + existence of any protocol), in this case,
86809 + swPrsEnable must be set, and all other
86810 + parameters are irrelevant. */
86811 + bool errDisable; /**< TRUE to disable error indication */
86812 + bool swPrsEnable; /**< Enable jump to SW parser when this
86813 + header is recognized by the HW parser. */
86814 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
86815 + attachments exists for the same header,
86816 + (in the main sw parser code) use this
86817 + index to distinguish between them. */
86818 + bool usePrsOpts; /**< TRUE to use parser options. */
86819 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
86820 + defining the parser options selected.*/
86821 +} t_FmPcdPrsAdditionalHdrParams;
86822 +
86823 +/**************************************************************************//**
86824 + @Description struct for defining port PCD parameters
86825 +*//***************************************************************************/
86826 +typedef struct t_FmPortPcdPrsParams {
86827 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
86828 + port information into the parser result. This information
86829 + may be extracted by Keygen and be used for frames
86830 + distribution when a per-port distinction is required,
86831 + it may also be used as a port logical id for analyzing
86832 + incoming frames. */
86833 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
86834 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
86835 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
86836 + NOTE: this field is not valid when the FM is in "guest" mode
86837 + and IPC is not available. */
86838 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
86839 + special parameters */
86840 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
86841 + /**< 'numOfHdrsWithAdditionalParams' structures
86842 + of additional parameters
86843 + for each header that requires them */
86844 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
86845 + indicate a VLAN tag (in addition to the TPID values
86846 + 0x8100 and 0x88A8). */
86847 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
86848 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
86849 + indicate a VLAN tag (in addition to the TPID values
86850 + 0x8100 and 0x88A8). */
86851 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
86852 +} t_FmPortPcdPrsParams;
86853 +
86854 +/**************************************************************************//**
86855 + @Description struct for defining coarse alassification parameters
86856 +*//***************************************************************************/
86857 +typedef struct t_FmPortPcdCcParams {
86858 + t_Handle h_CcTree; /**< A handle to a CC tree */
86859 +} t_FmPortPcdCcParams;
86860 +
86861 +/**************************************************************************//**
86862 + @Description struct for defining keygen parameters
86863 +*//***************************************************************************/
86864 +typedef struct t_FmPortPcdKgParams {
86865 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
86866 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
86867 + /**< Array of 'numOfSchemes' schemes handles for the
86868 + port to be bound to */
86869 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
86870 + regardless of parser result */
86871 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
86872 + as returned by FM_PCD_KgSetScheme */
86873 +} t_FmPortPcdKgParams;
86874 +
86875 +/**************************************************************************//**
86876 + @Description struct for defining policer parameters
86877 +*//***************************************************************************/
86878 +typedef struct t_FmPortPcdPlcrParams {
86879 + t_Handle h_Profile; /**< Selected profile handle */
86880 +} t_FmPortPcdPlcrParams;
86881 +
86882 +/**************************************************************************//**
86883 + @Description struct for defining port PCD parameters
86884 +*//***************************************************************************/
86885 +typedef struct t_FmPortPcdParams {
86886 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
86887 + Describes the active PCD engines for this port. */
86888 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
86889 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
86890 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
86891 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
86892 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
86893 + following cases:
86894 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
86895 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
86896 + or if any flow uses a KG scheme were policer
86897 + profile is not generated
86898 + ('bypassPlcrProfileGeneration selected'). */
86899 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
86900 +#if (DPAA_VERSION >= 11)
86901 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
86902 +#endif /* (DPAA_VERSION >= 11) */
86903 +} t_FmPortPcdParams;
86904 +
86905 +/**************************************************************************//**
86906 + @Description A structure for defining the Parser starting point
86907 +*//***************************************************************************/
86908 +typedef struct t_FmPcdPrsStart {
86909 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
86910 + start parsing */
86911 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
86912 + 'parsingOffset' */
86913 +} t_FmPcdPrsStart;
86914 +
86915 +#if (DPAA_VERSION >= 11)
86916 +/**************************************************************************//**
86917 + @Description struct for defining external buffer margins
86918 +*//***************************************************************************/
86919 +typedef struct t_FmPortVSPAllocParams {
86920 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
86921 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
86922 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
86923 + if relevant function called for Rx port */
86924 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
86925 +} t_FmPortVSPAllocParams;
86926 +#endif /* (DPAA_VERSION >= 11) */
86927 +
86928 +
86929 +/**************************************************************************//**
86930 + @Function FM_PORT_SetPCD
86931 +
86932 + @Description Calling this routine defines the port's PCD configuration.
86933 + It changes it from its default configuration which is PCD
86934 + disabled (BMI to BMI) and configures it according to the passed
86935 + parameters.
86936 +
86937 + May be used for Rx and OP ports only
86938 +
86939 + @Param[in] h_FmPort A handle to a FM Port module.
86940 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
86941 + configuration.
86942 +
86943 + @Return E_OK on success; Error code otherwise.
86944 +
86945 + @Cautions Allowed only following FM_PORT_Init().
86946 +*//***************************************************************************/
86947 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
86948 +
86949 +/**************************************************************************//**
86950 + @Function FM_PORT_DeletePCD
86951 +
86952 + @Description Calling this routine releases the port's PCD configuration.
86953 + The port returns to its default configuration which is PCD
86954 + disabled (BMI to BMI) and all PCD configuration is removed.
86955 +
86956 + May be used for Rx and OP ports which are
86957 + in PCD mode only
86958 +
86959 + @Param[in] h_FmPort A handle to a FM Port module.
86960 +
86961 + @Return E_OK on success; Error code otherwise.
86962 +
86963 + @Cautions Allowed only following FM_PORT_Init().
86964 +*//***************************************************************************/
86965 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
86966 +
86967 +/**************************************************************************//**
86968 + @Function FM_PORT_AttachPCD
86969 +
86970 + @Description This routine may be called after FM_PORT_DetachPCD was called,
86971 + to return to the originally configured PCD support flow.
86972 + The couple of routines are used to allow PCD configuration changes
86973 + that demand that PCD will not be used while changes take place.
86974 +
86975 + May be used for Rx and OP ports which are
86976 + in PCD mode only
86977 +
86978 + @Param[in] h_FmPort A handle to a FM Port module.
86979 +
86980 + @Return E_OK on success; Error code otherwise.
86981 +
86982 + @Cautions Allowed only following FM_PORT_Init().
86983 +*//***************************************************************************/
86984 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
86985 +
86986 +/**************************************************************************//**
86987 + @Function FM_PORT_DetachPCD
86988 +
86989 + @Description Calling this routine detaches the port from its PCD functionality.
86990 + The port returns to its default flow which is BMI to BMI.
86991 +
86992 + May be used for Rx and OP ports which are
86993 + in PCD mode only
86994 +
86995 + @Param[in] h_FmPort A handle to a FM Port module.
86996 +
86997 + @Return E_OK on success; Error code otherwise.
86998 +
86999 + @Cautions Allowed only following FM_PORT_AttachPCD().
87000 +*//***************************************************************************/
87001 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
87002 +
87003 +/**************************************************************************//**
87004 + @Function FM_PORT_PcdPlcrAllocProfiles
87005 +
87006 + @Description This routine may be called only for ports that use the Policer in
87007 + order to allocate private policer profiles.
87008 +
87009 + @Param[in] h_FmPort A handle to a FM Port module.
87010 + @Param[in] numOfProfiles The number of required policer profiles
87011 +
87012 + @Return E_OK on success; Error code otherwise.
87013 +
87014 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
87015 + and before FM_PORT_SetPCD().
87016 +*//***************************************************************************/
87017 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
87018 +
87019 +/**************************************************************************//**
87020 + @Function FM_PORT_PcdPlcrFreeProfiles
87021 +
87022 + @Description This routine should be called for freeing private policer profiles.
87023 +
87024 + @Param[in] h_FmPort A handle to a FM Port module.
87025 +
87026 + @Return E_OK on success; Error code otherwise.
87027 +
87028 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
87029 + and before FM_PORT_SetPCD().
87030 +*//***************************************************************************/
87031 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
87032 +
87033 +#if (DPAA_VERSION >= 11)
87034 +/**************************************************************************//**
87035 + @Function FM_PORT_VSPAlloc
87036 +
87037 + @Description This routine allocated VSPs per port and forces the port to work
87038 + in VSP mode. Note that the port is initialized by default with the
87039 + physical-storage-profile only.
87040 +
87041 + @Param[in] h_FmPort A handle to a FM Port module.
87042 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
87043 +
87044 + @Return E_OK on success; Error code otherwise.
87045 +
87046 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
87047 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
87048 +*//***************************************************************************/
87049 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
87050 +#endif /* (DPAA_VERSION >= 11) */
87051 +
87052 +/**************************************************************************//**
87053 + @Function FM_PORT_PcdKgModifyInitialScheme
87054 +
87055 + @Description This routine may be called only for ports that use the keygen in
87056 + order to change the initial scheme frame should be routed to.
87057 + The change may be of a scheme id (in case of direct mode),
87058 + from direct to indirect, or from indirect to direct - specifying the scheme id.
87059 +
87060 + @Param[in] h_FmPort A handle to a FM Port module.
87061 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
87062 + a scheme is direct/indirect, and if direct - scheme id.
87063 +
87064 + @Return E_OK on success; Error code otherwise.
87065 +
87066 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87067 +*//***************************************************************************/
87068 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
87069 +
87070 +/**************************************************************************//**
87071 + @Function FM_PORT_PcdPlcrModifyInitialProfile
87072 +
87073 + @Description This routine may be called for ports with flows
87074 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
87075 + only, to change the initial Policer profile frame should be
87076 + routed to. The change may be of a profile and/or absolute/direct
87077 + mode selection.
87078 +
87079 + @Param[in] h_FmPort A handle to a FM Port module.
87080 + @Param[in] h_Profile Policer profile handle
87081 +
87082 + @Return E_OK on success; Error code otherwise.
87083 +
87084 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87085 +*//***************************************************************************/
87086 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
87087 +
87088 +/**************************************************************************//**
87089 + @Function FM_PORT_PcdCcModifyTree
87090 +
87091 + @Description This routine may be called for ports that use coarse classification tree
87092 + if the user wishes to replace the tree. The routine may not be called while port
87093 + receives packets using the PCD functionalities, therefor port must be first detached
87094 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
87095 +
87096 + @Param[in] h_FmPort A handle to a FM Port module.
87097 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
87098 + the BuildTree routine.
87099 +
87100 + @Return E_OK on success; Error code otherwise.
87101 +
87102 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
87103 +*//***************************************************************************/
87104 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
87105 +
87106 +/**************************************************************************//**
87107 + @Function FM_PORT_PcdKgBindSchemes
87108 +
87109 + @Description These routines may be called for adding more schemes for the
87110 + port to be bound to. The selected schemes are not added,
87111 + just this specific port starts using them.
87112 +
87113 + @Param[in] h_FmPort A handle to a FM Port module.
87114 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87115 +
87116 + @Return E_OK on success; Error code otherwise.
87117 +
87118 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87119 +*//***************************************************************************/
87120 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87121 +
87122 +/**************************************************************************//**
87123 + @Function FM_PORT_PcdKgUnbindSchemes
87124 +
87125 + @Description These routines may be called for adding more schemes for the
87126 + port to be bound to. The selected schemes are not removed or invalidated,
87127 + just this specific port stops using them.
87128 +
87129 + @Param[in] h_FmPort A handle to a FM Port module.
87130 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
87131 +
87132 + @Return E_OK on success; Error code otherwise.
87133 +
87134 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
87135 +*//***************************************************************************/
87136 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
87137 +
87138 +/**************************************************************************//**
87139 + @Function FM_PORT_GetIPv4OptionsCount
87140 +
87141 + @Description TODO
87142 +
87143 + @Param[in] h_FmPort A handle to a FM Port module.
87144 + @Param[out] p_Ipv4OptionsCount will hold the counter value
87145 +
87146 + @Return E_OK on success; Error code otherwise.
87147 +
87148 + @Cautions Allowed only following FM_PORT_Init()
87149 +*//***************************************************************************/
87150 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
87151 +
87152 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
87153 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
87154 +
87155 +
87156 +/**************************************************************************//**
87157 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
87158 +
87159 + @Description FM Port Runtime data unit API functions, definitions and enums.
87160 + This API is valid only if working in Independent-Mode.
87161 +
87162 + @{
87163 +*//***************************************************************************/
87164 +
87165 +/**************************************************************************//**
87166 + @Function FM_PORT_ImTx
87167 +
87168 + @Description Tx function, called to transmit a data buffer on the port.
87169 +
87170 + @Param[in] h_FmPort A handle to a FM Port module.
87171 + @Param[in] p_Data A pointer to an LCP data buffer.
87172 + @Param[in] length Size of data for transmission.
87173 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
87174 + of a frame, including a single buffer frame
87175 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
87176 +
87177 + @Return E_OK on success; Error code otherwise.
87178 +
87179 + @Cautions Allowed only following FM_PORT_Init().
87180 + NOTE - This routine can be used only when working in
87181 + Independent-Mode mode.
87182 +*//***************************************************************************/
87183 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
87184 + uint8_t *p_Data,
87185 + uint16_t length,
87186 + bool lastBuffer,
87187 + t_Handle h_BufContext);
87188 +
87189 +/**************************************************************************//**
87190 + @Function FM_PORT_ImTxConf
87191 +
87192 + @Description Tx port confirmation routine, optional, may be called to verify
87193 + transmission of all frames. The procedure performed by this
87194 + routine will be performed automatically on next buffer transmission,
87195 + but if desired, calling this routine will invoke this action on
87196 + demand.
87197 +
87198 + @Param[in] h_FmPort A handle to a FM Port module.
87199 +
87200 + @Cautions Allowed only following FM_PORT_Init().
87201 + NOTE - This routine can be used only when working in
87202 + Independent-Mode mode.
87203 +*//***************************************************************************/
87204 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
87205 +
87206 +/**************************************************************************//**
87207 + @Function FM_PORT_ImRx
87208 +
87209 + @Description Rx function, may be called to poll for received buffers.
87210 + Normally, Rx process is invoked by the driver on Rx interrupt.
87211 + Alternatively, this routine may be called on demand.
87212 +
87213 + @Param[in] h_FmPort A handle to a FM Port module.
87214 +
87215 + @Return E_OK on success; Error code otherwise.
87216 +
87217 + @Cautions Allowed only following FM_PORT_Init().
87218 + NOTE - This routine can be used only when working in
87219 + Independent-Mode mode.
87220 +*//***************************************************************************/
87221 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
87222 +
87223 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
87224 +/** @} */ /* end of FM_PORT_grp group */
87225 +/** @} */ /* end of FM_grp group */
87226 +
87227 +
87228 +
87229 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
87230 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
87231 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
87232 +
87233 +
87234 +#endif /* __FM_PORT_EXT */
87235 --- /dev/null
87236 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
87237 @@ -0,0 +1,619 @@
87238 +/*
87239 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87240 + *
87241 + * Redistribution and use in source and binary forms, with or without
87242 + * modification, are permitted provided that the following conditions are met:
87243 + * * Redistributions of source code must retain the above copyright
87244 + * notice, this list of conditions and the following disclaimer.
87245 + * * Redistributions in binary form must reproduce the above copyright
87246 + * notice, this list of conditions and the following disclaimer in the
87247 + * documentation and/or other materials provided with the distribution.
87248 + * * Neither the name of Freescale Semiconductor nor the
87249 + * names of its contributors may be used to endorse or promote products
87250 + * derived from this software without specific prior written permission.
87251 + *
87252 + *
87253 + * ALTERNATIVELY, this software may be distributed under the terms of the
87254 + * GNU General Public License ("GPL") as published by the Free Software
87255 + * Foundation, either version 2 of that License or (at your option) any
87256 + * later version.
87257 + *
87258 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87259 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87260 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87261 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87262 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87263 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87264 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87265 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87266 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87267 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87268 + */
87269 +
87270 +
87271 +/**************************************************************************//**
87272 + @File fm_rtc_ext.h
87273 +
87274 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
87275 +
87276 + @Cautions None.
87277 +*//***************************************************************************/
87278 +
87279 +#ifndef __FM_RTC_EXT_H__
87280 +#define __FM_RTC_EXT_H__
87281 +
87282 +
87283 +#include "error_ext.h"
87284 +#include "std_ext.h"
87285 +#include "fsl_fman_rtc.h"
87286 +
87287 +/**************************************************************************//**
87288 +
87289 + @Group FM_grp Frame Manager API
87290 +
87291 + @Description FM API functions, definitions and enums
87292 +
87293 + @{
87294 +*//***************************************************************************/
87295 +
87296 +/**************************************************************************//**
87297 + @Group fm_rtc_grp FM RTC
87298 +
87299 + @Description FM RTC functions, definitions and enums.
87300 +
87301 + @{
87302 +*//***************************************************************************/
87303 +
87304 +/**************************************************************************//**
87305 + @Group fm_rtc_init_grp FM RTC Initialization Unit
87306 +
87307 + @Description FM RTC initialization API.
87308 +
87309 + @{
87310 +*//***************************************************************************/
87311 +
87312 +/**************************************************************************//**
87313 + @Description FM RTC Alarm Polarity Options.
87314 +*//***************************************************************************/
87315 +typedef enum e_FmRtcAlarmPolarity
87316 +{
87317 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
87318 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
87319 +} e_FmRtcAlarmPolarity;
87320 +
87321 +/**************************************************************************//**
87322 + @Description FM RTC Trigger Polarity Options.
87323 +*//***************************************************************************/
87324 +typedef enum e_FmRtcTriggerPolarity
87325 +{
87326 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
87327 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
87328 +} e_FmRtcTriggerPolarity;
87329 +
87330 +/**************************************************************************//**
87331 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
87332 +*//***************************************************************************/
87333 +typedef enum e_FmSrcClock
87334 +{
87335 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
87336 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
87337 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
87338 +}e_FmSrcClk;
87339 +
87340 +/**************************************************************************//**
87341 + @Description FM RTC configuration parameters structure.
87342 +
87343 + This structure should be passed to FM_RTC_Config().
87344 +*//***************************************************************************/
87345 +typedef struct t_FmRtcParams
87346 +{
87347 + t_Handle h_Fm; /**< FM Handle*/
87348 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
87349 + t_Handle h_App; /**< A handle to an application layer object; This handle will
87350 + be passed by the driver upon calling the above callbacks */
87351 +} t_FmRtcParams;
87352 +
87353 +
87354 +/**************************************************************************//**
87355 + @Function FM_RTC_Config
87356 +
87357 + @Description Configures the FM RTC module according to user's parameters.
87358 +
87359 + The driver assigns default values to some FM RTC parameters.
87360 + These parameters can be overwritten using the advanced
87361 + configuration routines.
87362 +
87363 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
87364 +
87365 + @Return Handle to the new FM RTC object; NULL pointer on failure.
87366 +
87367 + @Cautions None
87368 +*//***************************************************************************/
87369 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
87370 +
87371 +/**************************************************************************//**
87372 + @Function FM_RTC_Init
87373 +
87374 + @Description Initializes the FM RTC driver and hardware.
87375 +
87376 + @Param[in] h_FmRtc - Handle to FM RTC object.
87377 +
87378 + @Return E_OK on success; Error code otherwise.
87379 +
87380 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87381 +*//***************************************************************************/
87382 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
87383 +
87384 +/**************************************************************************//**
87385 + @Function FM_RTC_Free
87386 +
87387 + @Description Frees the FM RTC object and all allocated resources.
87388 +
87389 + @Param[in] h_FmRtc - Handle to FM RTC object.
87390 +
87391 + @Return E_OK on success; Error code otherwise.
87392 +
87393 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87394 +*//***************************************************************************/
87395 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
87396 +
87397 +
87398 +/**************************************************************************//**
87399 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
87400 +
87401 + @Description FM RTC advanced configuration functions.
87402 +
87403 + @{
87404 +*//***************************************************************************/
87405 +
87406 +/**************************************************************************//**
87407 + @Function FM_RTC_ConfigPeriod
87408 +
87409 + @Description Configures the period of the timestamp if different than
87410 + default [DEFAULT_clockPeriod].
87411 +
87412 + @Param[in] h_FmRtc - Handle to FM RTC object.
87413 + @Param[in] period - Period in nano-seconds.
87414 +
87415 + @Return E_OK on success; Error code otherwise.
87416 +
87417 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87418 +*//***************************************************************************/
87419 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
87420 +
87421 +/**************************************************************************//**
87422 + @Function FM_RTC_ConfigSourceClock
87423 +
87424 + @Description Configures the source clock of the RTC.
87425 +
87426 + @Param[in] h_FmRtc - Handle to FM RTC object.
87427 + @Param[in] srcClk - Source clock selection.
87428 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
87429 +
87430 + @Return E_OK on success; Error code otherwise.
87431 +
87432 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87433 +*//***************************************************************************/
87434 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
87435 + e_FmSrcClk srcClk,
87436 + uint32_t freqInMhz);
87437 +
87438 +/**************************************************************************//**
87439 + @Function FM_RTC_ConfigPulseRealignment
87440 +
87441 + @Description Configures the RTC to automatic FIPER pulse realignment in
87442 + response to timer adjustments [DEFAULT_pulseRealign]
87443 +
87444 + In this mode, the RTC clock is identical to the source clock.
87445 + This feature can be useful when the system contains an external
87446 + RTC with inherent frequency compensation.
87447 +
87448 + @Param[in] h_FmRtc - Handle to FM RTC object.
87449 + @Param[in] enable - TRUE to enable automatic realignment.
87450 +
87451 + @Return E_OK on success; Error code otherwise.
87452 +
87453 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87454 +*//***************************************************************************/
87455 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
87456 +
87457 +/**************************************************************************//**
87458 + @Function FM_RTC_ConfigFrequencyBypass
87459 +
87460 + @Description Configures the RTC to bypass the frequency compensation
87461 + mechanism. [DEFAULT_bypass]
87462 +
87463 + In this mode, the RTC clock is identical to the source clock.
87464 + This feature can be useful when the system contains an external
87465 + RTC with inherent frequency compensation.
87466 +
87467 + @Param[in] h_FmRtc - Handle to FM RTC object.
87468 + @Param[in] enabled - TRUE to bypass frequency compensation;
87469 + FALSE otherwise.
87470 +
87471 + @Return E_OK on success; Error code otherwise.
87472 +
87473 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87474 +*//***************************************************************************/
87475 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
87476 +
87477 +/**************************************************************************//**
87478 + @Function FM_RTC_ConfigInvertedInputClockPhase
87479 +
87480 + @Description Configures the RTC to invert the source clock phase on input.
87481 + [DEFAULT_invertInputClkPhase]
87482 +
87483 + @Param[in] h_FmRtc - Handle to FM RTC object.
87484 + @Param[in] inverted - TRUE to invert the source clock phase on input.
87485 + FALSE otherwise.
87486 +
87487 + @Return E_OK on success; Error code otherwise.
87488 +
87489 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87490 +*//***************************************************************************/
87491 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
87492 +
87493 +/**************************************************************************//**
87494 + @Function FM_RTC_ConfigInvertedOutputClockPhase
87495 +
87496 + @Description Configures the RTC to invert the output clock phase.
87497 + [DEFAULT_invertOutputClkPhase]
87498 +
87499 + @Param[in] h_FmRtc - Handle to FM RTC object.
87500 + @Param[in] inverted - TRUE to invert the output clock phase.
87501 + FALSE otherwise.
87502 +
87503 + @Return E_OK on success; Error code otherwise.
87504 +
87505 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87506 +*//***************************************************************************/
87507 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
87508 +
87509 +/**************************************************************************//**
87510 + @Function FM_RTC_ConfigOutputClockDivisor
87511 +
87512 + @Description Configures the divisor for generating the output clock from
87513 + the RTC clock. [DEFAULT_outputClockDivisor]
87514 +
87515 + @Param[in] h_FmRtc - Handle to FM RTC object.
87516 + @Param[in] divisor - Divisor for generation of the output clock.
87517 +
87518 + @Return E_OK on success; Error code otherwise.
87519 +
87520 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87521 +*//***************************************************************************/
87522 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
87523 +
87524 +/**************************************************************************//**
87525 + @Function FM_RTC_ConfigAlarmPolarity
87526 +
87527 + @Description Configures the polarity (active-high/active-low) of a specific
87528 + alarm signal. [DEFAULT_alarmPolarity]
87529 +
87530 + @Param[in] h_FmRtc - Handle to FM RTC object.
87531 + @Param[in] alarmId - Alarm ID.
87532 + @Param[in] alarmPolarity - Alarm polarity.
87533 +
87534 + @Return E_OK on success; Error code otherwise.
87535 +
87536 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87537 +*//***************************************************************************/
87538 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
87539 + uint8_t alarmId,
87540 + e_FmRtcAlarmPolarity alarmPolarity);
87541 +
87542 +/**************************************************************************//**
87543 + @Function FM_RTC_ConfigExternalTriggerPolarity
87544 +
87545 + @Description Configures the polarity (rising/falling edge) of a specific
87546 + external trigger signal. [DEFAULT_triggerPolarity]
87547 +
87548 + @Param[in] h_FmRtc - Handle to FM RTC object.
87549 + @Param[in] triggerId - Trigger ID.
87550 + @Param[in] triggerPolarity - Trigger polarity.
87551 +
87552 + @Return E_OK on success; Error code otherwise.
87553 +
87554 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
87555 +*//***************************************************************************/
87556 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
87557 + uint8_t triggerId,
87558 + e_FmRtcTriggerPolarity triggerPolarity);
87559 +
87560 +/** @} */ /* end of fm_rtc_adv_config_grp */
87561 +/** @} */ /* end of fm_rtc_init_grp */
87562 +
87563 +
87564 +/**************************************************************************//**
87565 + @Group fm_rtc_control_grp FM RTC Control Unit
87566 +
87567 + @Description FM RTC runtime control API.
87568 +
87569 + @{
87570 +*//***************************************************************************/
87571 +
87572 +/**************************************************************************//**
87573 + @Function t_FmRtcExceptionsCallback
87574 +
87575 + @Description Exceptions user callback routine, used for RTC different mechanisms.
87576 +
87577 + @Param[in] h_App - User's application descriptor.
87578 + @Param[in] id - source id.
87579 +*//***************************************************************************/
87580 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
87581 +
87582 +/**************************************************************************//**
87583 + @Description FM RTC alarm parameters.
87584 +*//***************************************************************************/
87585 +typedef struct t_FmRtcAlarmParams {
87586 + uint8_t alarmId; /**< 0 or 1 */
87587 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
87588 + should go off - must be a multiple of
87589 + the RTC period */
87590 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
87591 + reaches alarmTime */
87592 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
87593 +} t_FmRtcAlarmParams;
87594 +
87595 +/**************************************************************************//**
87596 + @Description FM RTC Periodic Pulse parameters.
87597 +*//***************************************************************************/
87598 +typedef struct t_FmRtcPeriodicPulseParams {
87599 + uint8_t periodicPulseId; /**< 0 or 1 */
87600 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
87601 + a multiple of the RTC period */
87602 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
87603 + periodicPulsePeriod. */
87604 +} t_FmRtcPeriodicPulseParams;
87605 +
87606 +/**************************************************************************//**
87607 + @Description FM RTC Periodic Pulse parameters.
87608 +*//***************************************************************************/
87609 +typedef struct t_FmRtcExternalTriggerParams {
87610 + uint8_t externalTriggerId; /**< 0 or 1 */
87611 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
87612 + an external signal */
87613 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
87614 + periodicPulsePeriod. */
87615 +} t_FmRtcExternalTriggerParams;
87616 +
87617 +
87618 +/**************************************************************************//**
87619 + @Function FM_RTC_Enable
87620 +
87621 + @Description Enable the RTC (time count is started).
87622 +
87623 + The user can select to resume the time count from previous
87624 + point, or to restart the time count.
87625 +
87626 + @Param[in] h_FmRtc - Handle to FM RTC object.
87627 + @Param[in] resetClock - Restart the time count from zero.
87628 +
87629 + @Return E_OK on success; Error code otherwise.
87630 +
87631 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87632 +*//***************************************************************************/
87633 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
87634 +
87635 +/**************************************************************************//**
87636 + @Function FM_RTC_Disable
87637 +
87638 + @Description Disables the RTC (time count is stopped).
87639 +
87640 + @Param[in] h_FmRtc - Handle to FM RTC object.
87641 +
87642 + @Return E_OK on success; Error code otherwise.
87643 +
87644 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87645 +*//***************************************************************************/
87646 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
87647 +
87648 +/**************************************************************************//**
87649 + @Function FM_RTC_SetClockOffset
87650 +
87651 + @Description Sets the clock offset (usually relative to another clock).
87652 +
87653 + The user can pass a negative offset value.
87654 +
87655 + @Param[in] h_FmRtc - Handle to FM RTC object.
87656 + @Param[in] offset - New clock offset (in nanoseconds).
87657 +
87658 + @Return E_OK on success; Error code otherwise.
87659 +
87660 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87661 +*//***************************************************************************/
87662 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
87663 +
87664 +/**************************************************************************//**
87665 + @Function FM_RTC_SetAlarm
87666 +
87667 + @Description Schedules an alarm event to a given RTC time.
87668 +
87669 + @Param[in] h_FmRtc - Handle to FM RTC object.
87670 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
87671 +
87672 + @Return E_OK on success; Error code otherwise.
87673 +
87674 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87675 + Must be called only prior to FM_RTC_Enable().
87676 +*//***************************************************************************/
87677 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
87678 +
87679 +/**************************************************************************//**
87680 + @Function FM_RTC_SetPeriodicPulse
87681 +
87682 + @Description Sets a periodic pulse.
87683 +
87684 + @Param[in] h_FmRtc - Handle to FM RTC object.
87685 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
87686 +
87687 + @Return E_OK on success; Error code otherwise.
87688 +
87689 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87690 + Must be called only prior to FM_RTC_Enable().
87691 +*//***************************************************************************/
87692 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
87693 +
87694 +/**************************************************************************//**
87695 + @Function FM_RTC_ClearPeriodicPulse
87696 +
87697 + @Description Clears a periodic pulse.
87698 +
87699 + @Param[in] h_FmRtc - Handle to FM RTC object.
87700 + @Param[in] periodicPulseId - Periodic pulse id.
87701 +
87702 + @Return E_OK on success; Error code otherwise.
87703 +
87704 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87705 +*//***************************************************************************/
87706 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
87707 +
87708 +/**************************************************************************//**
87709 + @Function FM_RTC_SetExternalTrigger
87710 +
87711 + @Description Sets an external trigger indication and define a callback
87712 + routine to be called on such event.
87713 +
87714 + @Param[in] h_FmRtc - Handle to FM RTC object.
87715 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
87716 +
87717 + @Return E_OK on success; Error code otherwise.
87718 +
87719 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87720 +*//***************************************************************************/
87721 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
87722 +
87723 +/**************************************************************************//**
87724 + @Function FM_RTC_ClearExternalTrigger
87725 +
87726 + @Description Clears external trigger indication.
87727 +
87728 + @Param[in] h_FmRtc - Handle to FM RTC object.
87729 + @Param[in] id - External Trigger id.
87730 +
87731 + @Return E_OK on success; Error code otherwise.
87732 +
87733 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87734 +*//***************************************************************************/
87735 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
87736 +
87737 +/**************************************************************************//**
87738 + @Function FM_RTC_GetExternalTriggerTimeStamp
87739 +
87740 + @Description Reads the External Trigger TimeStamp.
87741 +
87742 + @Param[in] h_FmRtc - Handle to FM RTC object.
87743 + @Param[in] triggerId - External Trigger id.
87744 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
87745 +
87746 + @Return E_OK on success; Error code otherwise.
87747 +
87748 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87749 +*//***************************************************************************/
87750 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
87751 + uint8_t triggerId,
87752 + uint64_t *p_TimeStamp);
87753 +
87754 +/**************************************************************************//**
87755 + @Function FM_RTC_GetCurrentTime
87756 +
87757 + @Description Returns the current RTC time.
87758 +
87759 + @Param[in] h_FmRtc - Handle to FM RTC object.
87760 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
87761 +
87762 + @Return E_OK on success; Error code otherwise.
87763 +
87764 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87765 +*//***************************************************************************/
87766 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
87767 +
87768 +/**************************************************************************//**
87769 + @Function FM_RTC_SetCurrentTime
87770 +
87771 + @Description Sets the current RTC time.
87772 +
87773 + @Param[in] h_FmRtc - Handle to FM RTC object.
87774 + @Param[in] ts - The new time stamp (in nanoseconds).
87775 +
87776 + @Return E_OK on success; Error code otherwise.
87777 +
87778 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87779 +*//***************************************************************************/
87780 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
87781 +
87782 +/**************************************************************************//**
87783 + @Function FM_RTC_GetFreqCompensation
87784 +
87785 + @Description Retrieves the frequency compensation value
87786 +
87787 + @Param[in] h_FmRtc - Handle to FM RTC object.
87788 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
87789 +
87790 + @Return E_OK on success; Error code otherwise.
87791 +
87792 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87793 +*//***************************************************************************/
87794 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
87795 +
87796 +/**************************************************************************//**
87797 + @Function FM_RTC_SetFreqCompensation
87798 +
87799 + @Description Sets a new frequency compensation value.
87800 +
87801 + @Param[in] h_FmRtc - Handle to FM RTC object.
87802 + @Param[in] freqCompensation - The new frequency compensation value to set.
87803 +
87804 + @Return E_OK on success; Error code otherwise.
87805 +
87806 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
87807 +*//***************************************************************************/
87808 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
87809 +
87810 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
87811 +/**************************************************************************//**
87812 +*@Function FM_RTC_EnableInterrupt
87813 +*
87814 +*@Description Enable interrupt of FM RTC.
87815 +*
87816 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87817 +*@Param[in] events - Interrupt events.
87818 +*
87819 +*@Return E_OK on success; Error code otherwise.
87820 +*//***************************************************************************/
87821 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
87822 +
87823 +/**************************************************************************//**
87824 +*@Function FM_RTC_DisableInterrupt
87825 +*
87826 +*@Description Disable interrupt of FM RTC.
87827 +*
87828 +*@Param[in] h_FmRtc - Handle to FM RTC object.
87829 +*@Param[in] events - Interrupt events.
87830 +*
87831 +*@Return E_OK on success; Error code otherwise.
87832 +*//***************************************************************************/
87833 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
87834 +#endif
87835 +
87836 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87837 +/**************************************************************************//**
87838 + @Function FM_RTC_DumpRegs
87839 +
87840 + @Description Dumps all FM registers
87841 +
87842 + @Param[in] h_FmRtc A handle to an FM RTC Module.
87843 +
87844 + @Return E_OK on success;
87845 +
87846 + @Cautions Allowed only FM_Init().
87847 +*//***************************************************************************/
87848 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
87849 +#endif /* (defined(DEBUG_ERRORS) && ... */
87850 +
87851 +/** @} */ /* end of fm_rtc_control_grp */
87852 +/** @} */ /* end of fm_rtc_grp */
87853 +/** @} */ /* end of FM_grp group */
87854 +
87855 +
87856 +#endif /* __FM_RTC_EXT_H__ */
87857 --- /dev/null
87858 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
87859 @@ -0,0 +1,411 @@
87860 +/*
87861 + * Copyright 2008-2012 Freescale Semiconductor Inc.
87862 + *
87863 + * Redistribution and use in source and binary forms, with or without
87864 + * modification, are permitted provided that the following conditions are met:
87865 + * * Redistributions of source code must retain the above copyright
87866 + * notice, this list of conditions and the following disclaimer.
87867 + * * Redistributions in binary form must reproduce the above copyright
87868 + * notice, this list of conditions and the following disclaimer in the
87869 + * documentation and/or other materials provided with the distribution.
87870 + * * Neither the name of Freescale Semiconductor nor the
87871 + * names of its contributors may be used to endorse or promote products
87872 + * derived from this software without specific prior written permission.
87873 + *
87874 + *
87875 + * ALTERNATIVELY, this software may be distributed under the terms of the
87876 + * GNU General Public License ("GPL") as published by the Free Software
87877 + * Foundation, either version 2 of that License or (at your option) any
87878 + * later version.
87879 + *
87880 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
87881 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
87882 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
87883 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
87884 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
87885 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
87886 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
87887 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
87888 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
87889 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87890 + */
87891 +
87892 +
87893 +/**************************************************************************//**
87894 + @File fm_vsp_ext.h
87895 +
87896 + @Description FM Virtual Storage-Profile ...
87897 +*//***************************************************************************/
87898 +#ifndef __FM_VSP_EXT_H
87899 +#define __FM_VSP_EXT_H
87900 +
87901 +#include "std_ext.h"
87902 +#include "error_ext.h"
87903 +#include "string_ext.h"
87904 +#include "debug_ext.h"
87905 +
87906 +#include "fm_ext.h"
87907 +
87908 +
87909 +/**************************************************************************//**
87910 +
87911 + @Group FM_grp Frame Manager API
87912 +
87913 + @Description FM API functions, definitions and enums
87914 +
87915 + @{
87916 +*//***************************************************************************/
87917 +
87918 +/**************************************************************************//**
87919 + @Group FM_VSP_grp FM Virtual-Storage-Profile
87920 +
87921 + @Description FM Virtual-Storage-Profile API
87922 +
87923 + @{
87924 +*//***************************************************************************/
87925 +
87926 +/**************************************************************************//**
87927 + @Group FM_VSP_init_grp FM VSP Initialization Unit
87928 +
87929 + @Description FM VSP initialization API.
87930 +
87931 + @{
87932 +*//***************************************************************************/
87933 +
87934 +/**************************************************************************//**
87935 + @Description Virtual Storage Profile
87936 +*//***************************************************************************/
87937 +typedef struct t_FmVspParams {
87938 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
87939 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
87940 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
87941 + parameter associated with Rx / OP port */
87942 + uint16_t liodnOffset; /**< VSP's LIODN offset */
87943 + struct {
87944 + e_FmPortType portType; /**< Port type */
87945 + uint8_t portId; /**< Port Id - relative to type */
87946 + } portParams;
87947 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
87948 + defined in relevant FM object */
87949 +} t_FmVspParams;
87950 +
87951 +
87952 +/**************************************************************************//**
87953 + @Function FM_VSP_Config
87954 +
87955 + @Description Creates descriptor for the FM VSP module.
87956 +
87957 + The routine returns a handle (descriptor) to the FM VSP object.
87958 + This descriptor must be passed as first parameter to all other
87959 + FM VSP function calls.
87960 +
87961 + No actual initialization or configuration of FM hardware is
87962 + done by this routine.
87963 +
87964 +@Param[in] p_FmVspParams Pointer to data structure of parameters
87965 +
87966 + @Retval Handle to FM VSP object, or NULL for Failure.
87967 +*//***************************************************************************/
87968 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
87969 +
87970 +/**************************************************************************//**
87971 + @Function FM_VSP_Init
87972 +
87973 + @Description Initializes the FM VSP module
87974 +
87975 + @Param[in] h_FmVsp - FM VSP module descriptor
87976 +
87977 + @Return E_OK on success; Error code otherwise.
87978 +*//***************************************************************************/
87979 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
87980 +
87981 +/**************************************************************************//**
87982 + @Function FM_VSP_Free
87983 +
87984 + @Description Frees all resources that were assigned to FM VSP module.
87985 +
87986 + Calling this routine invalidates the descriptor.
87987 +
87988 + @Param[in] h_FmVsp - FM VSP module descriptor
87989 +
87990 + @Return E_OK on success; Error code otherwise.
87991 +*//***************************************************************************/
87992 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
87993 +
87994 +
87995 +/**************************************************************************//**
87996 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
87997 +
87998 + @Description FM VSP advanced configuration functions.
87999 +
88000 + @{
88001 +*//***************************************************************************/
88002 +
88003 +/**************************************************************************//**
88004 + @Function FM_VSP_ConfigBufferPrefixContent
88005 +
88006 + @Description Defines the structure, size and content of the application buffer.
88007 +
88008 + The prefix will
88009 + In VSPs defined for Tx ports, if 'passPrsResult', the application
88010 + should set a value to their offsets in the prefix of
88011 + the FM will save the first 'privDataSize', than,
88012 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
88013 + and timeStamp, and the packet itself (in this order), to the
88014 + application buffer, and to offset.
88015 +
88016 + Calling this routine changes the buffer margins definitions
88017 + in the internal driver data base from its default
88018 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
88019 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
88020 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
88021 +
88022 + @Param[in] h_FmVsp A handle to a FM VSP module.
88023 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
88024 + structure of the buffer.
88025 + Out parameter: Start margin - offset
88026 + of data from start of external buffer.
88027 +
88028 + @Return E_OK on success; Error code otherwise.
88029 +
88030 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88031 +*//***************************************************************************/
88032 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
88033 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
88034 +
88035 +/**************************************************************************//**
88036 + @Function FM_VSP_ConfigDmaSwapData
88037 +
88038 + @Description Calling this routine changes the DMA swap data parameter
88039 + in the internal driver data base from its default
88040 + configuration [DEFAULT_FM_SP_dmaSwapData]
88041 +
88042 + @Param[in] h_FmVsp A handle to a FM VSP module.
88043 + @Param[in] swapData New selection
88044 +
88045 + @Return E_OK on success; Error code otherwise.
88046 +
88047 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88048 +*//***************************************************************************/
88049 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
88050 +
88051 +/**************************************************************************//**
88052 + @Function FM_VSP_ConfigDmaIcCacheAttr
88053 +
88054 + @Description Calling this routine changes the internal context cache
88055 + attribute parameter in the internal driver data base
88056 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
88057 +
88058 + @Param[in] h_FmVsp A handle to a FM VSP module.
88059 + @Param[in] intContextCacheAttr New selection
88060 +
88061 + @Return E_OK on success; Error code otherwise.
88062 +
88063 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88064 +*//***************************************************************************/
88065 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
88066 + e_FmDmaCacheOption intContextCacheAttr);
88067 +
88068 +/**************************************************************************//**
88069 + @Function FM_VSP_ConfigDmaHdrAttr
88070 +
88071 + @Description Calling this routine changes the header cache
88072 + attribute parameter in the internal driver data base
88073 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
88074 +
88075 + @Param[in] h_FmVsp A handle to a FM VSP module.
88076 + @Param[in] headerCacheAttr New selection
88077 +
88078 + @Return E_OK on success; Error code otherwise.
88079 +
88080 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88081 +*//***************************************************************************/
88082 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
88083 +
88084 +/**************************************************************************//**
88085 + @Function FM_VSP_ConfigDmaScatterGatherAttr
88086 +
88087 + @Description Calling this routine changes the scatter gather cache
88088 + attribute parameter in the internal driver data base
88089 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
88090 +
88091 + @Param[in] h_FmVsp A handle to a FM VSP module.
88092 + @Param[in] scatterGatherCacheAttr New selection
88093 +
88094 + @Return E_OK on success; Error code otherwise.
88095 +
88096 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88097 +*//***************************************************************************/
88098 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
88099 + e_FmDmaCacheOption scatterGatherCacheAttr);
88100 +
88101 +/**************************************************************************//**
88102 + @Function FM_VSP_ConfigDmaWriteOptimize
88103 +
88104 + @Description Calling this routine changes the write optimization
88105 + parameter in the internal driver data base
88106 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
88107 +
88108 + @Param[in] h_FmVsp A handle to a FM VSP module.
88109 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
88110 +
88111 + @Return E_OK on success; Error code otherwise.
88112 +
88113 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88114 +*//***************************************************************************/
88115 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
88116 +
88117 +/**************************************************************************//**
88118 + @Function FM_VSP_ConfigNoScatherGather
88119 +
88120 + @Description Calling this routine changes the possibility to receive S/G frame
88121 + in the internal driver data base
88122 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
88123 +
88124 + @Param[in] h_FmVsp A handle to a FM VSP module.
88125 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
88126 +
88127 + @Return E_OK on success; Error code otherwise.
88128 +
88129 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88130 +*//***************************************************************************/
88131 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
88132 +
88133 +/**************************************************************************//**
88134 + @Function FM_VSP_ConfigPoolDepletion
88135 +
88136 + @Description Calling this routine enables pause frame generation depending on the
88137 + depletion status of BM pools. It also defines the conditions to activate
88138 + this functionality. By default, this functionality is disabled.
88139 +
88140 + @Param[in] h_FmVsp A handle to a FM VSP module.
88141 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
88142 +
88143 + @Return E_OK on success; Error code otherwise.
88144 +
88145 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88146 +*//***************************************************************************/
88147 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
88148 +
88149 +/**************************************************************************//**
88150 + @Function FM_VSP_ConfigBackupPools
88151 +
88152 + @Description Calling this routine allows the configuration of some of the BM pools
88153 + defined for this port as backup pools.
88154 + A pool configured to be a backup pool will be used only if all other
88155 + enabled non-backup pools are depleted.
88156 +
88157 + @Param[in] h_FmVsp A handle to a FM VSP module.
88158 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
88159 + be defined as backup pools.
88160 +
88161 + @Return E_OK on success; Error code otherwise.
88162 +
88163 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
88164 +*//***************************************************************************/
88165 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
88166 +
88167 +/** @} */ /* end of FM_VSP_adv_config_grp group */
88168 +/** @} */ /* end of FM_VSP_init_grp group */
88169 +
88170 +
88171 +/**************************************************************************//**
88172 + @Group FM_VSP_control_grp FM VSP Control Unit
88173 +
88174 + @Description FM VSP runtime control API.
88175 +
88176 + @{
88177 +*//***************************************************************************/
88178 +
88179 +/**************************************************************************//**
88180 + @Function FM_VSP_GetBufferDataOffset
88181 +
88182 + @Description Relevant for Rx ports.
88183 + Returns the data offset from the beginning of the data buffer
88184 +
88185 + @Param[in] h_FmVsp - FM PORT module descriptor
88186 +
88187 + @Return data offset.
88188 +
88189 + @Cautions Allowed only following FM_VSP_Init().
88190 +*//***************************************************************************/
88191 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
88192 +
88193 +/**************************************************************************//**
88194 + @Function FM_VSP_GetBufferICInfo
88195 +
88196 + @Description Returns the Internal Context offset from the beginning of the data buffer
88197 +
88198 + @Param[in] h_FmVsp - FM PORT module descriptor
88199 + @Param[in] p_Data - A pointer to the data buffer.
88200 +
88201 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
88202 + configured for this port.
88203 +
88204 + @Cautions Allowed only following FM_VSP_Init().
88205 +*//***************************************************************************/
88206 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
88207 +
88208 +/**************************************************************************//**
88209 + @Function FM_VSP_GetBufferPrsResult
88210 +
88211 + @Description Returns the pointer to the parse result in the data buffer.
88212 + In Rx ports this is relevant after reception, if parse
88213 + result is configured to be part of the data passed to the
88214 + application. For non Rx ports it may be used to get the pointer
88215 + of the area in the buffer where parse result should be
88216 + initialized - if so configured.
88217 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88218 + configuration.
88219 +
88220 + @Param[in] h_FmVsp - FM PORT module descriptor
88221 + @Param[in] p_Data - A pointer to the data buffer.
88222 +
88223 + @Return Parse result pointer on success, NULL if parse result was not
88224 + configured for this port.
88225 +
88226 + @Cautions Allowed only following FM_VSP_Init().
88227 +*//***************************************************************************/
88228 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
88229 +
88230 +/**************************************************************************//**
88231 + @Function FM_VSP_GetBufferTimeStamp
88232 +
88233 + @Description Returns the time stamp in the data buffer.
88234 + Relevant for Rx ports for getting the buffer time stamp.
88235 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
88236 + configuration.
88237 +
88238 + @Param[in] h_FmVsp - FM PORT module descriptor
88239 + @Param[in] p_Data - A pointer to the data buffer.
88240 +
88241 + @Return A pointer to the hash result on success, NULL otherwise.
88242 +
88243 + @Cautions Allowed only following FM_VSP_Init().
88244 +*//***************************************************************************/
88245 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
88246 +
88247 +/**************************************************************************//**
88248 + @Function FM_VSP_GetBufferHashResult
88249 +
88250 + @Description Given a data buffer, on the condition that hash result was defined
88251 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
88252 + this routine will return the pointer to the hash result location in the
88253 + buffer prefix.
88254 +
88255 + @Param[in] h_FmVsp - FM PORT module descriptor
88256 + @Param[in] p_Data - A pointer to the data buffer.
88257 +
88258 + @Return A pointer to the hash result on success, NULL otherwise.
88259 +
88260 + @Cautions Allowed only following FM_VSP_Init().
88261 +*//***************************************************************************/
88262 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
88263 +
88264 +
88265 +/** @} */ /* end of FM_VSP_control_grp group */
88266 +/** @} */ /* end of FM_VSP_grp group */
88267 +/** @} */ /* end of FM_grp group */
88268 +
88269 +
88270 +#endif /* __FM_VSP_EXT_H */
88271 --- /dev/null
88272 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
88273 @@ -0,0 +1,76 @@
88274 +/*
88275 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88276 + *
88277 + * Redistribution and use in source and binary forms, with or without
88278 + * modification, are permitted provided that the following conditions are met:
88279 + * * Redistributions of source code must retain the above copyright
88280 + * notice, this list of conditions and the following disclaimer.
88281 + * * Redistributions in binary form must reproduce the above copyright
88282 + * notice, this list of conditions and the following disclaimer in the
88283 + * documentation and/or other materials provided with the distribution.
88284 + * * Neither the name of Freescale Semiconductor nor the
88285 + * names of its contributors may be used to endorse or promote products
88286 + * derived from this software without specific prior written permission.
88287 + *
88288 + *
88289 + * ALTERNATIVELY, this software may be distributed under the terms of the
88290 + * GNU General Public License ("GPL") as published by the Free Software
88291 + * Foundation, either version 2 of that License or (at your option) any
88292 + * later version.
88293 + *
88294 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88295 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88296 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88297 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88298 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88299 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88300 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88301 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88302 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88303 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88304 + */
88305 +
88306 +
88307 +
88308 +#ifndef __MII_ACC_EXT_H
88309 +#define __MII_ACC_EXT_H
88310 +
88311 +
88312 +/**************************************************************************//**
88313 + @Function MII_ReadPhyReg
88314 +
88315 + @Description This routine is called to read a specified PHY
88316 + register value.
88317 +
88318 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88319 + @Param[in] phyAddr - PHY address (0-31).
88320 + @Param[in] reg - PHY register to read
88321 + @Param[out] p_Data - Gets the register value.
88322 +
88323 + @Return Always zero (success).
88324 +*//***************************************************************************/
88325 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
88326 + uint8_t phyAddr,
88327 + uint8_t reg,
88328 + uint16_t *p_Data);
88329 +
88330 +/**************************************************************************//**
88331 + @Function MII_WritePhyReg
88332 +
88333 + @Description This routine is called to write data to a specified PHY
88334 + register.
88335 +
88336 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
88337 + @Param[in] phyAddr - PHY address (0-31).
88338 + @Param[in] reg - PHY register to write
88339 + @Param[in] data - Data to write in register.
88340 +
88341 + @Return Always zero (success).
88342 +*//***************************************************************************/
88343 +int MII_WritePhyReg(t_Handle h_MiiAccess,
88344 + uint8_t phyAddr,
88345 + uint8_t reg,
88346 + uint16_t data);
88347 +
88348 +
88349 +#endif /* __MII_ACC_EXT_H */
88350 --- /dev/null
88351 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
88352 @@ -0,0 +1,90 @@
88353 +/*
88354 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88355 + *
88356 + * Redistribution and use in source and binary forms, with or without
88357 + * modification, are permitted provided that the following conditions are met:
88358 + * * Redistributions of source code must retain the above copyright
88359 + * notice, this list of conditions and the following disclaimer.
88360 + * * Redistributions in binary form must reproduce the above copyright
88361 + * notice, this list of conditions and the following disclaimer in the
88362 + * documentation and/or other materials provided with the distribution.
88363 + * * Neither the name of Freescale Semiconductor nor the
88364 + * names of its contributors may be used to endorse or promote products
88365 + * derived from this software without specific prior written permission.
88366 + *
88367 + *
88368 + * ALTERNATIVELY, this software may be distributed under the terms of the
88369 + * GNU General Public License ("GPL") as published by the Free Software
88370 + * Foundation, either version 2 of that License or (at your option) any
88371 + * later version.
88372 + *
88373 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88374 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88375 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88376 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88377 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88378 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88379 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88380 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88381 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88382 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88383 + */
88384 +
88385 +
88386 +/**************************************************************************//**
88387 + @File core_ext.h
88388 +
88389 + @Description Generic interface to basic core operations.
88390 +
88391 + The system integrator must ensure that this interface is
88392 + mapped to a specific core implementation, by including the
88393 + appropriate header file.
88394 +*//***************************************************************************/
88395 +#ifndef __CORE_EXT_H
88396 +#define __CORE_EXT_H
88397 +
88398 +#ifdef CONFIG_FMAN_ARM
88399 +#include "arm_ext.h"
88400 +#include <linux/smp.h>
88401 +#else
88402 +#ifdef NCSW_PPC_CORE
88403 +#include "ppc_ext.h"
88404 +#elif defined(NCSW_VXWORKS)
88405 +#include "core_vxw_ext.h"
88406 +#else
88407 +#error "Core is not defined!"
88408 +#endif /* NCSW_CORE */
88409 +
88410 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
88411 +#error "Must define core as little-endian or big-endian!"
88412 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
88413 +
88414 +#ifndef CORE_CACHELINE_SIZE
88415 +#error "Must define the core cache-line size!"
88416 +#endif /* !CORE_CACHELINE_SIZE */
88417 +
88418 +#endif /* CONFIG_FMAN_ARM */
88419 +
88420 +
88421 +/**************************************************************************//**
88422 + @Function CORE_GetId
88423 +
88424 + @Description Returns the core ID in the system.
88425 +
88426 + @Return Core ID.
88427 +*//***************************************************************************/
88428 +uint32_t CORE_GetId(void);
88429 +
88430 +/**************************************************************************//**
88431 + @Function CORE_MemoryBarrier
88432 +
88433 + @Description This routine will cause the core to stop executing any commands
88434 + until all previous memory read/write commands are completely out
88435 + of the core's pipeline.
88436 +
88437 + @Return None.
88438 +*//***************************************************************************/
88439 +void CORE_MemoryBarrier(void);
88440 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
88441 +
88442 +#endif /* __CORE_EXT_H */
88443 --- /dev/null
88444 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
88445 @@ -0,0 +1,55 @@
88446 +/*
88447 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88448 + *
88449 + * Redistribution and use in source and binary forms, with or without
88450 + * modification, are permitted provided that the following conditions are met:
88451 + * * Redistributions of source code must retain the above copyright
88452 + * notice, this list of conditions and the following disclaimer.
88453 + * * Redistributions in binary form must reproduce the above copyright
88454 + * notice, this list of conditions and the following disclaimer in the
88455 + * documentation and/or other materials provided with the distribution.
88456 + * * Neither the name of Freescale Semiconductor nor the
88457 + * names of its contributors may be used to endorse or promote products
88458 + * derived from this software without specific prior written permission.
88459 + *
88460 + *
88461 + * ALTERNATIVELY, this software may be distributed under the terms of the
88462 + * GNU General Public License ("GPL") as published by the Free Software
88463 + * Foundation, either version 2 of that License or (at your option) any
88464 + * later version.
88465 + *
88466 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88467 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88468 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88469 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88470 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88471 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88472 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88473 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88474 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88475 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88476 + */
88477 +
88478 +
88479 +/**************************************************************************//**
88480 + @File arm_ext.h
88481 +
88482 + @Description Core API for ARM cores
88483 +
88484 + These routines must be implemented by each specific PowerPC
88485 + core driver.
88486 +*//***************************************************************************/
88487 +#ifndef __ARM_EXT_H
88488 +#define __ARM_EXT_H
88489 +
88490 +#include "part_ext.h"
88491 +
88492 +
88493 +#define CORE_IS_LITTLE_ENDIAN
88494 +
88495 +static __inline__ void CORE_MemoryBarrier(void)
88496 +{
88497 + mb();
88498 +}
88499 +
88500 +#endif /* __PPC_EXT_H */
88501 --- /dev/null
88502 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
88503 @@ -0,0 +1,476 @@
88504 +/*
88505 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88506 + *
88507 + * Redistribution and use in source and binary forms, with or without
88508 + * modification, are permitted provided that the following conditions are met:
88509 + * * Redistributions of source code must retain the above copyright
88510 + * notice, this list of conditions and the following disclaimer.
88511 + * * Redistributions in binary form must reproduce the above copyright
88512 + * notice, this list of conditions and the following disclaimer in the
88513 + * documentation and/or other materials provided with the distribution.
88514 + * * Neither the name of Freescale Semiconductor nor the
88515 + * names of its contributors may be used to endorse or promote products
88516 + * derived from this software without specific prior written permission.
88517 + *
88518 + *
88519 + * ALTERNATIVELY, this software may be distributed under the terms of the
88520 + * GNU General Public License ("GPL") as published by the Free Software
88521 + * Foundation, either version 2 of that License or (at your option) any
88522 + * later version.
88523 + *
88524 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88525 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88526 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88527 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88528 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88529 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88530 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88531 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88532 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88533 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88534 + */
88535 +
88536 +
88537 +/**************************************************************************//**
88538 + @File e500v2_ext.h
88539 +
88540 + @Description E500 external definitions prototypes
88541 + This file is not included by the E500
88542 + source file as it is an assembly file. It is used
88543 + only for prototypes exposure, for inclusion
88544 + by user and other modules.
88545 +*//***************************************************************************/
88546 +
88547 +#ifndef __E500V2_EXT_H
88548 +#define __E500V2_EXT_H
88549 +
88550 +#include "std_ext.h"
88551 +
88552 +
88553 +/* Layer 1 Cache Manipulations
88554 + *==============================
88555 + * Should not be called directly by the user.
88556 + */
88557 +void L1DCache_Invalidate (void);
88558 +void L1ICache_Invalidate(void);
88559 +void L1DCache_Enable(void);
88560 +void L1ICache_Enable(void);
88561 +void L1DCache_Disable(void);
88562 +void L1ICache_Disable(void);
88563 +void L1DCache_Flush(void);
88564 +void L1ICache_Flush(void);
88565 +uint32_t L1ICache_IsEnabled(void);
88566 +uint32_t L1DCache_IsEnabled(void);
88567 +/*
88568 + *
88569 + */
88570 +uint32_t L1DCache_LineLock(uint32_t addr);
88571 +uint32_t L1ICache_LineLock(uint32_t addr);
88572 +void L1Cache_BroadCastEnable(void);
88573 +void L1Cache_BroadCastDisable(void);
88574 +
88575 +
88576 +#define CORE_DCacheEnable E500_DCacheEnable
88577 +#define CORE_ICacheEnable E500_ICacheEnable
88578 +#define CORE_DCacheDisable E500_DCacheDisable
88579 +#define CORE_ICacheDisable E500_ICacheDisable
88580 +#define CORE_GetId E500_GetId
88581 +#define CORE_TestAndSet E500_TestAndSet
88582 +#define CORE_MemoryBarrier E500_MemoryBarrier
88583 +#define CORE_InstructionSync E500_InstructionSync
88584 +
88585 +#define CORE_SetDozeMode E500_SetDozeMode
88586 +#define CORE_SetNapMode E500_SetNapMode
88587 +#define CORE_SetSleepMode E500_SetSleepMode
88588 +#define CORE_SetJogMode E500_SetJogMode
88589 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
88590 +
88591 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
88592 +#define CORE_RecoverNapMode E500_RecoverNapMode
88593 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
88594 +#define CORE_RecoverJogMode E500_RecoverJogMode
88595 +
88596 +void E500_SetDozeMode(void);
88597 +void E500_SetNapMode(void);
88598 +void E500_SetSleepMode(void);
88599 +void E500_SetJogMode(void);
88600 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
88601 +
88602 +void E500_RecoverDozeMode(void);
88603 +void E500_RecoverNapMode(void);
88604 +void E500_RecoverSleepMode(void);
88605 +void E500_RecoverJogMode(void);
88606 +
88607 +
88608 +/**************************************************************************//**
88609 + @Group E500_id E500 Application Programming Interface
88610 +
88611 + @Description E500 API functions, definitions and enums
88612 +
88613 + @{
88614 +*//***************************************************************************/
88615 +
88616 +/**************************************************************************//**
88617 + @Group E500_init_grp E500 Initialization Unit
88618 +
88619 + @Description E500 initialization unit API functions, definitions and enums
88620 +
88621 + @{
88622 +*//***************************************************************************/
88623 +
88624 +
88625 +/**************************************************************************//**
88626 + @Function E500_DCacheEnable
88627 +
88628 + @Description Enables the data cache for memory pages that are
88629 + not cache inhibited.
88630 +
88631 + @Return None.
88632 +*//***************************************************************************/
88633 +void E500_DCacheEnable(void);
88634 +
88635 +/**************************************************************************//**
88636 + @Function E500_ICacheEnable
88637 +
88638 + @Description Enables the instruction cache for memory pages that are
88639 + not cache inhibited.
88640 +
88641 + @Return None.
88642 +*//***************************************************************************/
88643 +void E500_ICacheEnable(void);
88644 +
88645 +/**************************************************************************//**
88646 + @Function E500_DCacheDisable
88647 +
88648 + @Description Disables the data cache.
88649 +
88650 + @Return None.
88651 +*//***************************************************************************/
88652 +void E500_DCacheDisable(void);
88653 +
88654 +/**************************************************************************//**
88655 + @Function E500_ICacheDisable
88656 +
88657 + @Description Disables the instruction cache.
88658 +
88659 + @Return None.
88660 +*//***************************************************************************/
88661 +void E500_ICacheDisable(void);
88662 +
88663 +/**************************************************************************//**
88664 + @Function E500_DCacheFlush
88665 +
88666 + @Description Flushes the data cache
88667 +
88668 + @Return None.
88669 +*//***************************************************************************/
88670 +void E500_DCacheFlush(void);
88671 +
88672 +/**************************************************************************//**
88673 + @Function E500_ICacheFlush
88674 +
88675 + @Description Flushes the instruction cache.
88676 +
88677 + @Return None.
88678 +*//***************************************************************************/
88679 +void E500_ICacheFlush(void);
88680 +
88681 +/**************************************************************************//**
88682 + @Function E500_DCacheSetStashId
88683 +
88684 + @Description Set Stash Id for data cache
88685 +
88686 + @Param[in] stashId the stash id to be set.
88687 +
88688 + @Return None.
88689 +*//***************************************************************************/
88690 +void E500_DCacheSetStashId(uint8_t stashId);
88691 +
88692 +/**************************************************************************//**
88693 + @Description E500mc L2 Cache Operation Mode
88694 +*//***************************************************************************/
88695 +typedef enum e_E500mcL2CacheMode
88696 +{
88697 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
88698 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
88699 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
88700 +} e_E500mcL2CacheMode;
88701 +
88702 +#if defined(CORE_E500MC) || defined(CORE_E5500)
88703 +/**************************************************************************//**
88704 + @Function E500_L2CacheEnable
88705 +
88706 + @Description Enables the cache for memory pages that are not cache inhibited.
88707 +
88708 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
88709 +
88710 + @Return None.
88711 +
88712 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88713 + not possible to call this routine for i-cache and than to call
88714 + again for d-cache; The second call will override the first one.
88715 +*//***************************************************************************/
88716 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
88717 +
88718 +/**************************************************************************//**
88719 + @Function E500_L2CacheDisable
88720 +
88721 + @Description Disables the cache (data instruction or both).
88722 +
88723 + @Return None.
88724 +
88725 +*//***************************************************************************/
88726 +void E500_L2CacheDisable(void);
88727 +
88728 +/**************************************************************************//**
88729 + @Function E500_L2CacheFlush
88730 +
88731 + @Description Flushes the cache.
88732 +
88733 + @Return None.
88734 +*//***************************************************************************/
88735 +void E500_L2CacheFlush(void);
88736 +
88737 +/**************************************************************************//**
88738 + @Function E500_L2SetStashId
88739 +
88740 + @Description Set Stash Id
88741 +
88742 + @Param[in] stashId the stash id to be set.
88743 +
88744 + @Return None.
88745 +*//***************************************************************************/
88746 +void E500_L2SetStashId(uint8_t stashId);
88747 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
88748 +
88749 +#ifdef CORE_E6500
88750 +/**************************************************************************//**
88751 + @Function E6500_L2CacheEnable
88752 +
88753 + @Description Enables the cache for memory pages that are not cache inhibited.
88754 +
88755 + @param[in] mode - L2 cache mode: support data & instruction only.
88756 +
88757 + @Return None.
88758 +
88759 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
88760 + not possible to call this routine for i-cache and than to call
88761 + again for d-cache; The second call will override the first one.
88762 +*//***************************************************************************/
88763 +void E6500_L2CacheEnable(uintptr_t clusterBase);
88764 +
88765 +/**************************************************************************//**
88766 + @Function E6500_L2CacheDisable
88767 +
88768 + @Description Disables the cache (data instruction or both).
88769 +
88770 + @Return None.
88771 +
88772 +*//***************************************************************************/
88773 +void E6500_L2CacheDisable(uintptr_t clusterBase);
88774 +
88775 +/**************************************************************************//**
88776 + @Function E6500_L2CacheFlush
88777 +
88778 + @Description Flushes the cache.
88779 +
88780 + @Return None.
88781 +*//***************************************************************************/
88782 +void E6500_L2CacheFlush(uintptr_t clusterBase);
88783 +
88784 +/**************************************************************************//**
88785 + @Function E6500_L2SetStashId
88786 +
88787 + @Description Set Stash Id
88788 +
88789 + @Param[in] stashId the stash id to be set.
88790 +
88791 + @Return None.
88792 +*//***************************************************************************/
88793 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
88794 +
88795 +/**************************************************************************//**
88796 + @Function E6500_GetCcsrBase
88797 +
88798 + @Description Obtain SoC CCSR base address
88799 +
88800 + @Param[in] None.
88801 +
88802 + @Return Physical CCSR base address.
88803 +*//***************************************************************************/
88804 +physAddress_t E6500_GetCcsrBase(void);
88805 +#endif /* CORE_E6500 */
88806 +
88807 +/**************************************************************************//**
88808 + @Function E500_AddressBusStreamingEnable
88809 +
88810 + @Description Enables address bus streaming on the CCB.
88811 +
88812 + This setting, along with the ECM streaming configuration
88813 + parameters, enables address bus streaming on the CCB.
88814 +
88815 + @Return None.
88816 +*//***************************************************************************/
88817 +void E500_AddressBusStreamingEnable(void);
88818 +
88819 +/**************************************************************************//**
88820 + @Function E500_AddressBusStreamingDisable
88821 +
88822 + @Description Disables address bus streaming on the CCB.
88823 +
88824 + @Return None.
88825 +*//***************************************************************************/
88826 +void E500_AddressBusStreamingDisable(void);
88827 +
88828 +/**************************************************************************//**
88829 + @Function E500_AddressBroadcastEnable
88830 +
88831 + @Description Enables address broadcast.
88832 +
88833 + The e500 broadcasts cache management instructions (dcbst, dcblc
88834 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88835 + based on ABE. ABE must be set to allow management of external
88836 + L2 caches.
88837 +
88838 + @Return None.
88839 +*//***************************************************************************/
88840 +void E500_AddressBroadcastEnable(void);
88841 +
88842 +/**************************************************************************//**
88843 + @Function E500_AddressBroadcastDisable
88844 +
88845 + @Description Disables address broadcast.
88846 +
88847 + The e500 broadcasts cache management instructions (dcbst, dcblc
88848 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
88849 + based on ABE. ABE must be set to allow management of external
88850 + L2 caches.
88851 +
88852 + @Return None.
88853 +*//***************************************************************************/
88854 +void E500_AddressBroadcastDisable(void);
88855 +
88856 +/**************************************************************************//**
88857 + @Function E500_IsTaskletSupported
88858 +
88859 + @Description Checks if tasklets are supported by the e500 interrupt handler.
88860 +
88861 + @Retval TRUE - Tasklets are supported.
88862 + @Retval FALSE - Tasklets are not supported.
88863 +*//***************************************************************************/
88864 +bool E500_IsTaskletSupported(void);
88865 +
88866 +void E500_EnableTimeBase(void);
88867 +void E500_DisableTimeBase(void);
88868 +
88869 +uint64_t E500_GetTimeBaseTime(void);
88870 +
88871 +void E500_GenericIntrInit(void);
88872 +
88873 +t_Error E500_SetIntr(int ppcIntrSrc,
88874 + void (* Isr)(t_Handle handle),
88875 + t_Handle handle);
88876 +
88877 +t_Error E500_ClearIntr(int ppcIntrSrc);
88878 +
88879 +/**************************************************************************//**
88880 + @Function E500_GenericIntrHandler
88881 +
88882 + @Description This is the general e500 interrupt handler.
88883 +
88884 + It is called by the main assembly interrupt handler
88885 + when an exception occurs and no other function has been
88886 + assigned to this exception.
88887 +
88888 + @Param intrEntry - (In) The exception interrupt vector entry.
88889 +*//***************************************************************************/
88890 +void E500_GenericIntrHandler(uint32_t intrEntry);
88891 +
88892 +/**************************************************************************//**
88893 + @Function CriticalIntr
88894 +
88895 + @Description This is the specific critical e500 interrupt handler.
88896 +
88897 + It is called by the main assembly interrupt handler
88898 + when an critical interrupt.
88899 +
88900 + @Param intrEntry - (In) The exception interrupt vector entry.
88901 +*//***************************************************************************/
88902 +void CriticalIntr(uint32_t intrEntry);
88903 +
88904 +
88905 +/**************************************************************************//**
88906 + @Function E500_GetId
88907 +
88908 + @Description Returns the core ID in the system.
88909 +
88910 + @Return Core ID.
88911 +*//***************************************************************************/
88912 +uint32_t E500_GetId(void);
88913 +
88914 +/**************************************************************************//**
88915 + @Function E500_TestAndSet
88916 +
88917 + @Description This routine tries to atomically test-and-set an integer
88918 + in memory to a non-zero value.
88919 +
88920 + The memory will be set only if it is tested as zero, in which
88921 + case the routine returns the new non-zero value; otherwise the
88922 + routine returns zero.
88923 +
88924 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
88925 + operation should be made.
88926 +
88927 + @Retval Zero - Operation failed - memory was already set.
88928 + @Retval Non-zero - Operation succeeded - memory has been set.
88929 +*//***************************************************************************/
88930 +int E500_TestAndSet(volatile int *p);
88931 +
88932 +/**************************************************************************//**
88933 + @Function E500_MemoryBarrier
88934 +
88935 + @Description This routine will cause the core to stop executing any commands
88936 + until all previous memory read/write commands are completely out
88937 + of the core's pipeline.
88938 +
88939 + @Return None.
88940 +*//***************************************************************************/
88941 +static __inline__ void E500_MemoryBarrier(void)
88942 +{
88943 +#ifndef CORE_E500V2
88944 + __asm__ ("mbar 1");
88945 +#else /* CORE_E500V2 */
88946 + /**** ERRATA WORK AROUND START ****/
88947 + /* ERRATA num: CPU1 */
88948 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
88949 + guarded loads and stores. */
88950 +
88951 + /* "msync" instruction is used instead */
88952 +
88953 + __asm__ ("msync");
88954 +
88955 + /**** ERRATA WORK AROUND END ****/
88956 +#endif /* CORE_E500V2 */
88957 +}
88958 +
88959 +/**************************************************************************//**
88960 + @Function E500_InstructionSync
88961 +
88962 + @Description This routine will cause the core to wait for previous instructions
88963 + (including any interrupts they generate) to complete before the
88964 + synchronization command executes, which purges all instructions
88965 + from the processor's pipeline and refetches the next instruction.
88966 +
88967 + @Return None.
88968 +*//***************************************************************************/
88969 +static __inline__ void E500_InstructionSync(void)
88970 +{
88971 + __asm__ ("isync");
88972 +}
88973 +
88974 +
88975 +/** @} */ /* end of E500_init_grp group */
88976 +/** @} */ /* end of E500_grp group */
88977 +
88978 +
88979 +#endif /* __E500V2_EXT_H */
88980 --- /dev/null
88981 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
88982 @@ -0,0 +1,141 @@
88983 +/*
88984 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88985 + *
88986 + * Redistribution and use in source and binary forms, with or without
88987 + * modification, are permitted provided that the following conditions are met:
88988 + * * Redistributions of source code must retain the above copyright
88989 + * notice, this list of conditions and the following disclaimer.
88990 + * * Redistributions in binary form must reproduce the above copyright
88991 + * notice, this list of conditions and the following disclaimer in the
88992 + * documentation and/or other materials provided with the distribution.
88993 + * * Neither the name of Freescale Semiconductor nor the
88994 + * names of its contributors may be used to endorse or promote products
88995 + * derived from this software without specific prior written permission.
88996 + *
88997 + *
88998 + * ALTERNATIVELY, this software may be distributed under the terms of the
88999 + * GNU General Public License ("GPL") as published by the Free Software
89000 + * Foundation, either version 2 of that License or (at your option) any
89001 + * later version.
89002 + *
89003 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89004 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89005 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89006 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89007 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89008 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89009 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89010 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89011 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89012 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89013 + */
89014 +
89015 +
89016 +/**************************************************************************//**
89017 + @File ppc_ext.h
89018 +
89019 + @Description Core API for PowerPC cores
89020 +
89021 + These routines must be implemented by each specific PowerPC
89022 + core driver.
89023 +*//***************************************************************************/
89024 +#ifndef __PPC_EXT_H
89025 +#define __PPC_EXT_H
89026 +
89027 +#include "part_ext.h"
89028 +
89029 +
89030 +#define CORE_IS_BIG_ENDIAN
89031 +
89032 +#if defined(CORE_E300) || defined(CORE_E500V2)
89033 +#define CORE_CACHELINE_SIZE 32
89034 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89035 +#define CORE_CACHELINE_SIZE 64
89036 +#else
89037 +#error "Core not defined!"
89038 +#endif /* defined(CORE_E300) || ... */
89039 +
89040 +
89041 +/**************************************************************************//**
89042 + @Function CORE_TestAndSet
89043 +
89044 + @Description This routine tries to atomically test-and-set an integer
89045 + in memory to a non-zero value.
89046 +
89047 + The memory will be set only if it is tested as zero, in which
89048 + case the routine returns the new non-zero value; otherwise the
89049 + routine returns zero.
89050 +
89051 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
89052 + operation should be made.
89053 +
89054 + @Retval Zero - Operation failed - memory was already set.
89055 + @Retval Non-zero - Operation succeeded - memory has been set.
89056 +*//***************************************************************************/
89057 +int CORE_TestAndSet(volatile int *p);
89058 +
89059 +/**************************************************************************//**
89060 + @Function CORE_InstructionSync
89061 +
89062 + @Description This routine will cause the core to wait for previous instructions
89063 + (including any interrupts they generate) to complete before the
89064 + synchronization command executes, which purges all instructions
89065 + from the processor's pipeline and refetches the next instruction.
89066 +
89067 + @Return None.
89068 +*//***************************************************************************/
89069 +void CORE_InstructionSync(void);
89070 +
89071 +/**************************************************************************//**
89072 + @Function CORE_DCacheEnable
89073 +
89074 + @Description Enables the data cache for memory pages that are
89075 + not cache inhibited.
89076 +
89077 + @Return None.
89078 +*//***************************************************************************/
89079 +void CORE_DCacheEnable(void);
89080 +
89081 +/**************************************************************************//**
89082 + @Function CORE_ICacheEnable
89083 +
89084 + @Description Enables the instruction cache for memory pages that are
89085 + not cache inhibited.
89086 +
89087 + @Return None.
89088 +*//***************************************************************************/
89089 +void CORE_ICacheEnable(void);
89090 +
89091 +/**************************************************************************//**
89092 + @Function CORE_DCacheDisable
89093 +
89094 + @Description Disables the data cache.
89095 +
89096 + @Return None.
89097 +*//***************************************************************************/
89098 +void CORE_DCacheDisable(void);
89099 +
89100 +/**************************************************************************//**
89101 + @Function CORE_ICacheDisable
89102 +
89103 + @Description Disables the instruction cache.
89104 +
89105 + @Return None.
89106 +*//***************************************************************************/
89107 +void CORE_ICacheDisable(void);
89108 +
89109 +
89110 +
89111 +#if defined(CORE_E300)
89112 +#include "e300_ext.h"
89113 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
89114 +#include "e500v2_ext.h"
89115 +#if !defined(NCSW_LINUX)
89116 +#include "e500v2_asm_ext.h"
89117 +#endif
89118 +#else
89119 +#error "Core not defined!"
89120 +#endif
89121 +
89122 +
89123 +#endif /* __PPC_EXT_H */
89124 --- /dev/null
89125 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
89126 @@ -0,0 +1,77 @@
89127 +/*
89128 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89129 + *
89130 + * Redistribution and use in source and binary forms, with or without
89131 + * modification, are permitted provided that the following conditions are met:
89132 + * * Redistributions of source code must retain the above copyright
89133 + * notice, this list of conditions and the following disclaimer.
89134 + * * Redistributions in binary form must reproduce the above copyright
89135 + * notice, this list of conditions and the following disclaimer in the
89136 + * documentation and/or other materials provided with the distribution.
89137 + * * Neither the name of Freescale Semiconductor nor the
89138 + * names of its contributors may be used to endorse or promote products
89139 + * derived from this software without specific prior written permission.
89140 + *
89141 + *
89142 + * ALTERNATIVELY, this software may be distributed under the terms of the
89143 + * GNU General Public License ("GPL") as published by the Free Software
89144 + * Foundation, either version 2 of that License or (at your option) any
89145 + * later version.
89146 + *
89147 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89148 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89149 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89150 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89151 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89152 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89153 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89154 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89155 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89156 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89157 + */
89158 +
89159 +#ifndef __DDR_SDT_EXT_H
89160 +#define __DDR_SDT_EXT_H
89161 +
89162 +
89163 +/**************************************************************************//**
89164 + @Group ddr_Generic_Resources
89165 +
89166 + @Description ddr generic functions, definitions and enums.
89167 +
89168 + @{
89169 +*//***************************************************************************/
89170 +
89171 +
89172 +/**************************************************************************//**
89173 + @Description SPD maximum size
89174 +*//***************************************************************************/
89175 +#define SPD_MAX_SIZE 256
89176 +
89177 +/**************************************************************************//**
89178 + @Description DDR types select
89179 +*//***************************************************************************/
89180 +typedef enum e_DdrType
89181 +{
89182 + e_DDR_DDR1,
89183 + e_DDR_DDR2,
89184 + e_DDR_DDR3,
89185 + e_DDR_DDR3L,
89186 + e_DDR_DDR4
89187 +} e_DdrType;
89188 +
89189 +/**************************************************************************//**
89190 + @Description DDR Mode.
89191 +*//***************************************************************************/
89192 +typedef enum e_DdrMode
89193 +{
89194 + e_DDR_BUS_WIDTH_32BIT,
89195 + e_DDR_BUS_WIDTH_64BIT
89196 +} e_DdrMode;
89197 +
89198 +/** @} */ /* end of ddr_Generic_Resources group */
89199 +
89200 +
89201 +
89202 +#endif /* __DDR_SDT_EXT_H */
89203 +
89204 --- /dev/null
89205 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
89206 @@ -0,0 +1,233 @@
89207 +/*
89208 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89209 + *
89210 + * Redistribution and use in source and binary forms, with or without
89211 + * modification, are permitted provided that the following conditions are met:
89212 + * * Redistributions of source code must retain the above copyright
89213 + * notice, this list of conditions and the following disclaimer.
89214 + * * Redistributions in binary form must reproduce the above copyright
89215 + * notice, this list of conditions and the following disclaimer in the
89216 + * documentation and/or other materials provided with the distribution.
89217 + * * Neither the name of Freescale Semiconductor nor the
89218 + * names of its contributors may be used to endorse or promote products
89219 + * derived from this software without specific prior written permission.
89220 + *
89221 + *
89222 + * ALTERNATIVELY, this software may be distributed under the terms of the
89223 + * GNU General Public License ("GPL") as published by the Free Software
89224 + * Foundation, either version 2 of that License or (at your option) any
89225 + * later version.
89226 + *
89227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89237 + */
89238 +
89239 +
89240 +/**************************************************************************//**
89241 + @File debug_ext.h
89242 +
89243 + @Description Debug mode definitions.
89244 +*//***************************************************************************/
89245 +
89246 +#ifndef __DEBUG_EXT_H
89247 +#define __DEBUG_EXT_H
89248 +
89249 +#include "std_ext.h"
89250 +#include "xx_ext.h"
89251 +#include "memcpy_ext.h"
89252 +#if (DEBUG_ERRORS > 0)
89253 +#include "sprint_ext.h"
89254 +#include "string_ext.h"
89255 +#endif /* DEBUG_ERRORS > 0 */
89256 +
89257 +
89258 +#if (DEBUG_ERRORS > 0)
89259 +
89260 +/* Internally used macros */
89261 +
89262 +#define DUMP_Print XX_Print
89263 +#define DUMP_MAX_LEVELS 6
89264 +#define DUMP_IDX_LEN 6
89265 +#define DUMP_MAX_STR 64
89266 +
89267 +
89268 +#define _CREATE_DUMP_SUBSTR(phrase) \
89269 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
89270 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
89271 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
89272 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
89273 + { \
89274 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
89275 + if (dumpIsArr[dumpTmpLevel]) \
89276 + { \
89277 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
89278 + p_DumpToken = strtok(NULL, "."); \
89279 + } \
89280 + if ((p_DumpToken != NULL) && \
89281 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
89282 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
89283 + }
89284 +
89285 +
89286 +/**************************************************************************//**
89287 + @Group gen_id General Drivers Utilities
89288 +
89289 + @Description External routines.
89290 +
89291 + @{
89292 +*//***************************************************************************/
89293 +
89294 +/**************************************************************************//**
89295 + @Group dump_id Memory and Registers Dump Mechanism
89296 +
89297 + @Description Macros for dumping memory mapped structures.
89298 +
89299 + @{
89300 +*//***************************************************************************/
89301 +
89302 +/**************************************************************************//**
89303 + @Description Declaration of dump mechanism variables.
89304 +
89305 + This macro must be declared at the beginning of each routine
89306 + which uses the dump mechanism macros, before the routine's code
89307 + starts.
89308 +*//***************************************************************************/
89309 +#define DECLARE_DUMP \
89310 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
89311 + char dumpSubStr[DUMP_MAX_STR] = ""; \
89312 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
89313 + char *p_DumpToken = NULL; \
89314 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
89315 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
89316 + /* Prevent warnings if not all used */ \
89317 + UNUSED(dumpIdxStr[0][0]); \
89318 + UNUSED(dumpSubStr[0]); \
89319 + UNUSED(dumpTmpStr[0]); \
89320 + UNUSED(p_DumpToken); \
89321 + UNUSED(dumpArrIdx); \
89322 + UNUSED(dumpArrSize); \
89323 + UNUSED(dumpLevel); \
89324 + UNUSED(dumpTmpLevel); \
89325 + UNUSED(dumpIsArr[0]);
89326 +
89327 +
89328 +/**************************************************************************//**
89329 + @Description Prints a title for a subsequent dumped structure or memory.
89330 +
89331 + The inputs for this macro are the structure/memory title and
89332 + its base addresses.
89333 +*//***************************************************************************/
89334 +#define DUMP_TITLE(addr, msg) \
89335 + DUMP_Print("\r\n"); DUMP_Print msg; \
89336 + if (addr) \
89337 + DUMP_Print(" (%p)", (addr)); \
89338 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
89339 +
89340 +/**************************************************************************//**
89341 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
89342 +
89343 + The inputs for this macro are the sub-structure subtitle.
89344 + A separating line with this subtitle will be printed.
89345 +*//***************************************************************************/
89346 +#define DUMP_SUBTITLE(subtitle) \
89347 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
89348 +
89349 +
89350 +/**************************************************************************//**
89351 + @Description Dumps a memory region in 4-bytes aligned format.
89352 +
89353 + The inputs for this macro are the base addresses and size
89354 + (in bytes) of the memory region.
89355 +*//***************************************************************************/
89356 +#define DUMP_MEMORY(addr, size) \
89357 + MemDisp((uint8_t *)(addr), (int)(size))
89358 +
89359 +
89360 +/**************************************************************************//**
89361 + @Description Declares a dump loop, for dumping a sub-structure array.
89362 +
89363 + The inputs for this macro are:
89364 + - idx: an index variable, for indexing the sub-structure items
89365 + inside the loop. This variable must be declared separately
89366 + in the beginning of the routine.
89367 + - cnt: the number of times to repeat the loop. This number should
89368 + equal the number of items in the sub-structures array.
89369 +
89370 + Note, that the body of the loop must be written inside brackets.
89371 +*//***************************************************************************/
89372 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
89373 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
89374 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
89375 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
89376 +
89377 +
89378 +/**************************************************************************//**
89379 + @Description Dumps a structure's member variable.
89380 +
89381 + The input for this macro is the full reference for the member
89382 + variable, where the structure is referenced using a pointer.
89383 +
89384 + Note, that a members array must be dumped using DUMP_ARR macro,
89385 + rather than using this macro.
89386 +
89387 + If the member variable is part of a sub-structure hierarchy,
89388 + the full hierarchy (including array indexing) must be specified.
89389 +
89390 + Examples: p_Struct->member
89391 + p_Struct->sub.member
89392 + p_Struct->sub[i].member
89393 +*//***************************************************************************/
89394 +#define DUMP_VAR(st, phrase) \
89395 + do { \
89396 + void *addr = (void *)&((st)->phrase); \
89397 + physAddress_t physAddr = XX_VirtToPhys(addr); \
89398 + _CREATE_DUMP_SUBSTR(phrase); \
89399 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
89400 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
89401 + } while (0)
89402 +
89403 +
89404 +/**************************************************************************//**
89405 + @Description Dumps a structure's members array.
89406 +
89407 + The input for this macro is the full reference for the members
89408 + array, where the structure is referenced using a pointer.
89409 +
89410 + If the members array is part of a sub-structure hierarchy,
89411 + the full hierarchy (including array indexing) must be specified.
89412 +
89413 + Examples: p_Struct->array
89414 + p_Struct->sub.array
89415 + p_Struct->sub[i].array
89416 +*//***************************************************************************/
89417 +#define DUMP_ARR(st, phrase) \
89418 + do { \
89419 + physAddress_t physAddr; \
89420 + _CREATE_DUMP_SUBSTR(phrase); \
89421 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
89422 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
89423 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
89424 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
89425 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
89426 + } \
89427 + } while (0)
89428 +
89429 +
89430 +
89431 +#endif /* DEBUG_ERRORS > 0 */
89432 +
89433 +
89434 +/** @} */ /* end of dump_id group */
89435 +/** @} */ /* end of gen_id group */
89436 +
89437 +
89438 +#endif /* __DEBUG_EXT_H */
89439 +
89440 --- /dev/null
89441 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
89442 @@ -0,0 +1,447 @@
89443 +/*
89444 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89445 + *
89446 + * Redistribution and use in source and binary forms, with or without
89447 + * modification, are permitted provided that the following conditions are met:
89448 + * * Redistributions of source code must retain the above copyright
89449 + * notice, this list of conditions and the following disclaimer.
89450 + * * Redistributions in binary form must reproduce the above copyright
89451 + * notice, this list of conditions and the following disclaimer in the
89452 + * documentation and/or other materials provided with the distribution.
89453 + * * Neither the name of Freescale Semiconductor nor the
89454 + * names of its contributors may be used to endorse or promote products
89455 + * derived from this software without specific prior written permission.
89456 + *
89457 + *
89458 + * ALTERNATIVELY, this software may be distributed under the terms of the
89459 + * GNU General Public License ("GPL") as published by the Free Software
89460 + * Foundation, either version 2 of that License or (at your option) any
89461 + * later version.
89462 + *
89463 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89464 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89466 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89467 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89468 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89469 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89470 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89471 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89472 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89473 + */
89474 +
89475 +
89476 +/**************************************************************************//**
89477 +
89478 + @File endian_ext.h
89479 +
89480 + @Description Big/little endian swapping routines.
89481 +*//***************************************************************************/
89482 +
89483 +#ifndef __ENDIAN_EXT_H
89484 +#define __ENDIAN_EXT_H
89485 +
89486 +#include "std_ext.h"
89487 +
89488 +
89489 +/**************************************************************************//**
89490 + @Group gen_id General Drivers Utilities
89491 +
89492 + @Description General usage API. This API is intended for usage by both the
89493 + internal modules and the user's application.
89494 +
89495 + @{
89496 +*//***************************************************************************/
89497 +
89498 +/**************************************************************************//**
89499 + @Group endian_id Big/Little-Endian Conversion
89500 +
89501 + @Description Routines and macros for Big/Little-Endian conversion and
89502 + general byte swapping.
89503 +
89504 + All routines and macros are expecting unsigned values as
89505 + parameters, but will generate the correct result also for
89506 + signed values. Therefore, signed/unsigned casting is allowed.
89507 + @{
89508 +*//***************************************************************************/
89509 +
89510 +/**************************************************************************//**
89511 + @Collection Byte-Swap Macros
89512 +
89513 + Macros for swapping byte order.
89514 +
89515 + @Cautions The parameters of these macros are evaluated multiple times.
89516 + For calculated expressions or expressions that contain function
89517 + calls it is recommended to use the byte-swap routines.
89518 +
89519 + @{
89520 +*//***************************************************************************/
89521 +
89522 +/**************************************************************************//**
89523 + @Description Swaps the byte order of a given 16-bit value.
89524 +
89525 + @Param[in] val - The 16-bit value to swap.
89526 +
89527 + @Return The byte-swapped value..
89528 +
89529 + @Cautions The given value is evaluated multiple times by this macro.
89530 + For calculated expressions or expressions that contain function
89531 + calls it is recommended to use the SwapUint16() routine.
89532 +
89533 + @hideinitializer
89534 +*//***************************************************************************/
89535 +#define SWAP_UINT16(val) \
89536 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
89537 +
89538 +/**************************************************************************//**
89539 + @Description Swaps the byte order of a given 32-bit value.
89540 +
89541 + @Param[in] val - The 32-bit value to swap.
89542 +
89543 + @Return The byte-swapped value..
89544 +
89545 + @Cautions The given value is evaluated multiple times by this macro.
89546 + For calculated expressions or expressions that contain function
89547 + calls it is recommended to use the SwapUint32() routine.
89548 +
89549 + @hideinitializer
89550 +*//***************************************************************************/
89551 +#define SWAP_UINT32(val) \
89552 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
89553 + (((val) & 0x0000FF00) << 8) | \
89554 + (((val) & 0x00FF0000) >> 8) | \
89555 + (((val) & 0xFF000000) >> 24)))
89556 +
89557 +/**************************************************************************//**
89558 + @Description Swaps the byte order of a given 64-bit value.
89559 +
89560 + @Param[in] val - The 64-bit value to swap.
89561 +
89562 + @Return The byte-swapped value..
89563 +
89564 + @Cautions The given value is evaluated multiple times by this macro.
89565 + For calculated expressions or expressions that contain function
89566 + calls it is recommended to use the SwapUint64() routine.
89567 +
89568 + @hideinitializer
89569 +*//***************************************************************************/
89570 +#define SWAP_UINT64(val) \
89571 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
89572 + (((val) & 0x000000000000FF00ULL) << 40) | \
89573 + (((val) & 0x0000000000FF0000ULL) << 24) | \
89574 + (((val) & 0x00000000FF000000ULL) << 8) | \
89575 + (((val) & 0x000000FF00000000ULL) >> 8) | \
89576 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
89577 + (((val) & 0x00FF000000000000ULL) >> 40) | \
89578 + (((val) & 0xFF00000000000000ULL) >> 56)))
89579 +
89580 +/* @} */
89581 +
89582 +/**************************************************************************//**
89583 + @Collection Byte-Swap Routines
89584 +
89585 + Routines for swapping the byte order of a given parameter and
89586 + returning the swapped value.
89587 +
89588 + These inline routines are safer than the byte-swap macros,
89589 + because they evaluate the parameter expression only once.
89590 + @{
89591 +*//***************************************************************************/
89592 +
89593 +/**************************************************************************//**
89594 + @Function SwapUint16
89595 +
89596 + @Description Returns the byte-swapped value of a given 16-bit value.
89597 +
89598 + @Param[in] val - The 16-bit value.
89599 +
89600 + @Return The byte-swapped value of the parameter.
89601 +*//***************************************************************************/
89602 +static __inline__ uint16_t SwapUint16(uint16_t val)
89603 +{
89604 + return (uint16_t)(((val & 0x00FF) << 8) |
89605 + ((val & 0xFF00) >> 8));
89606 +}
89607 +
89608 +/**************************************************************************//**
89609 + @Function SwapUint32
89610 +
89611 + @Description Returns the byte-swapped value of a given 32-bit value.
89612 +
89613 + @Param[in] val - The 32-bit value.
89614 +
89615 + @Return The byte-swapped value of the parameter.
89616 +*//***************************************************************************/
89617 +static __inline__ uint32_t SwapUint32(uint32_t val)
89618 +{
89619 + return (uint32_t)(((val & 0x000000FF) << 24) |
89620 + ((val & 0x0000FF00) << 8) |
89621 + ((val & 0x00FF0000) >> 8) |
89622 + ((val & 0xFF000000) >> 24));
89623 +}
89624 +
89625 +/**************************************************************************//**
89626 + @Function SwapUint64
89627 +
89628 + @Description Returns the byte-swapped value of a given 64-bit value.
89629 +
89630 + @Param[in] val - The 64-bit value.
89631 +
89632 + @Return The byte-swapped value of the parameter.
89633 +*//***************************************************************************/
89634 +static __inline__ uint64_t SwapUint64(uint64_t val)
89635 +{
89636 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
89637 + ((val & 0x000000000000FF00ULL) << 40) |
89638 + ((val & 0x0000000000FF0000ULL) << 24) |
89639 + ((val & 0x00000000FF000000ULL) << 8) |
89640 + ((val & 0x000000FF00000000ULL) >> 8) |
89641 + ((val & 0x0000FF0000000000ULL) >> 24) |
89642 + ((val & 0x00FF000000000000ULL) >> 40) |
89643 + ((val & 0xFF00000000000000ULL) >> 56));
89644 +}
89645 +
89646 +/* @} */
89647 +
89648 +/**************************************************************************//**
89649 + @Collection In-place Byte-Swap-And-Set Routines
89650 +
89651 + Routines for swapping the byte order of a given variable and
89652 + setting the swapped value back to the same variable.
89653 + @{
89654 +*//***************************************************************************/
89655 +
89656 +/**************************************************************************//**
89657 + @Function SwapUint16P
89658 +
89659 + @Description Swaps the byte order of a given 16-bit variable.
89660 +
89661 + @Param[in] p_Val - Pointer to the 16-bit variable.
89662 +
89663 + @Return None.
89664 +*//***************************************************************************/
89665 +static __inline__ void SwapUint16P(uint16_t *p_Val)
89666 +{
89667 + *p_Val = SwapUint16(*p_Val);
89668 +}
89669 +
89670 +/**************************************************************************//**
89671 + @Function SwapUint32P
89672 +
89673 + @Description Swaps the byte order of a given 32-bit variable.
89674 +
89675 + @Param[in] p_Val - Pointer to the 32-bit variable.
89676 +
89677 + @Return None.
89678 +*//***************************************************************************/
89679 +static __inline__ void SwapUint32P(uint32_t *p_Val)
89680 +{
89681 + *p_Val = SwapUint32(*p_Val);
89682 +}
89683 +
89684 +/**************************************************************************//**
89685 + @Function SwapUint64P
89686 +
89687 + @Description Swaps the byte order of a given 64-bit variable.
89688 +
89689 + @Param[in] p_Val - Pointer to the 64-bit variable.
89690 +
89691 + @Return None.
89692 +*//***************************************************************************/
89693 +static __inline__ void SwapUint64P(uint64_t *p_Val)
89694 +{
89695 + *p_Val = SwapUint64(*p_Val);
89696 +}
89697 +
89698 +/* @} */
89699 +
89700 +
89701 +/**************************************************************************//**
89702 + @Collection Little-Endian Conversion Macros
89703 +
89704 + These macros convert given parameters to or from Little-Endian
89705 + format. Use these macros when you want to read or write a specific
89706 + Little-Endian value in memory, without a-priori knowing the CPU
89707 + byte order.
89708 +
89709 + These macros use the byte-swap routines. For conversion of
89710 + constants in initialization structures, you may use the CONST
89711 + versions of these macros (see below), which are using the
89712 + byte-swap macros instead.
89713 + @{
89714 +*//***************************************************************************/
89715 +
89716 +/**************************************************************************//**
89717 + @Description Converts a given 16-bit value from CPU byte order to
89718 + Little-Endian byte order.
89719 +
89720 + @Param[in] val - The 16-bit value to convert.
89721 +
89722 + @Return The converted value.
89723 +
89724 + @hideinitializer
89725 +*//***************************************************************************/
89726 +#define CPU_TO_LE16(val) SwapUint16(val)
89727 +
89728 +/**************************************************************************//**
89729 + @Description Converts a given 32-bit value from CPU byte order to
89730 + Little-Endian byte order.
89731 +
89732 + @Param[in] val - The 32-bit value to convert.
89733 +
89734 + @Return The converted value.
89735 +
89736 + @hideinitializer
89737 +*//***************************************************************************/
89738 +#define CPU_TO_LE32(val) SwapUint32(val)
89739 +
89740 +/**************************************************************************//**
89741 + @Description Converts a given 64-bit value from CPU byte order to
89742 + Little-Endian byte order.
89743 +
89744 + @Param[in] val - The 64-bit value to convert.
89745 +
89746 + @Return The converted value.
89747 +
89748 + @hideinitializer
89749 +*//***************************************************************************/
89750 +#define CPU_TO_LE64(val) SwapUint64(val)
89751 +
89752 +
89753 +/**************************************************************************//**
89754 + @Description Converts a given 16-bit value from Little-Endian byte order to
89755 + CPU byte order.
89756 +
89757 + @Param[in] val - The 16-bit value to convert.
89758 +
89759 + @Return The converted value.
89760 +
89761 + @hideinitializer
89762 +*//***************************************************************************/
89763 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
89764 +
89765 +/**************************************************************************//**
89766 + @Description Converts a given 32-bit value from Little-Endian byte order to
89767 + CPU byte order.
89768 +
89769 + @Param[in] val - The 32-bit value to convert.
89770 +
89771 + @Return The converted value.
89772 +
89773 + @hideinitializer
89774 +*//***************************************************************************/
89775 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
89776 +
89777 +/**************************************************************************//**
89778 + @Description Converts a given 64-bit value from Little-Endian byte order to
89779 + CPU byte order.
89780 +
89781 + @Param[in] val - The 64-bit value to convert.
89782 +
89783 + @Return The converted value.
89784 +
89785 + @hideinitializer
89786 +*//***************************************************************************/
89787 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
89788 +
89789 +/* @} */
89790 +
89791 +/**************************************************************************//**
89792 + @Collection Little-Endian Constant Conversion Macros
89793 +
89794 + These macros convert given constants to or from Little-Endian
89795 + format. Use these macros when you want to read or write a specific
89796 + Little-Endian constant in memory, without a-priori knowing the
89797 + CPU byte order.
89798 +
89799 + These macros use the byte-swap macros, therefore can be used for
89800 + conversion of constants in initialization structures.
89801 +
89802 + @Cautions The parameters of these macros are evaluated multiple times.
89803 + For non-constant expressions, use the non-CONST macro versions.
89804 +
89805 + @{
89806 +*//***************************************************************************/
89807 +
89808 +/**************************************************************************//**
89809 + @Description Converts a given 16-bit constant from CPU byte order to
89810 + Little-Endian byte order.
89811 +
89812 + @Param[in] val - The 16-bit value to convert.
89813 +
89814 + @Return The converted value.
89815 +
89816 + @hideinitializer
89817 +*//***************************************************************************/
89818 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
89819 +
89820 +/**************************************************************************//**
89821 + @Description Converts a given 32-bit constant from CPU byte order to
89822 + Little-Endian byte order.
89823 +
89824 + @Param[in] val - The 32-bit value to convert.
89825 +
89826 + @Return The converted value.
89827 +
89828 + @hideinitializer
89829 +*//***************************************************************************/
89830 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
89831 +
89832 +/**************************************************************************//**
89833 + @Description Converts a given 64-bit constant from CPU byte order to
89834 + Little-Endian byte order.
89835 +
89836 + @Param[in] val - The 64-bit value to convert.
89837 +
89838 + @Return The converted value.
89839 +
89840 + @hideinitializer
89841 +*//***************************************************************************/
89842 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
89843 +
89844 +
89845 +/**************************************************************************//**
89846 + @Description Converts a given 16-bit constant from Little-Endian byte order
89847 + to CPU byte order.
89848 +
89849 + @Param[in] val - The 16-bit value to convert.
89850 +
89851 + @Return The converted value.
89852 +
89853 + @hideinitializer
89854 +*//***************************************************************************/
89855 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
89856 +
89857 +/**************************************************************************//**
89858 + @Description Converts a given 32-bit constant from Little-Endian byte order
89859 + to CPU byte order.
89860 +
89861 + @Param[in] val - The 32-bit value to convert.
89862 +
89863 + @Return The converted value.
89864 +
89865 + @hideinitializer
89866 +*//***************************************************************************/
89867 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
89868 +
89869 +/**************************************************************************//**
89870 + @Description Converts a given 64-bit constant from Little-Endian byte order
89871 + to CPU byte order.
89872 +
89873 + @Param[in] val - The 64-bit value to convert.
89874 +
89875 + @Return The converted value.
89876 +
89877 + @hideinitializer
89878 +*//***************************************************************************/
89879 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
89880 +
89881 +/* @} */
89882 +
89883 +
89884 +/** @} */ /* end of endian_id group */
89885 +/** @} */ /* end of gen_id group */
89886 +
89887 +
89888 +#endif /* __ENDIAN_EXT_H */
89889 +
89890 --- /dev/null
89891 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
89892 @@ -0,0 +1,205 @@
89893 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
89894 + * All rights reserved.
89895 + *
89896 + * Redistribution and use in source and binary forms, with or without
89897 + * modification, are permitted provided that the following conditions are met:
89898 + * * Redistributions of source code must retain the above copyright
89899 + * notice, this list of conditions and the following disclaimer.
89900 + * * Redistributions in binary form must reproduce the above copyright
89901 + * notice, this list of conditions and the following disclaimer in the
89902 + * documentation and/or other materials provided with the distribution.
89903 + * * Neither the name of Freescale Semiconductor nor the
89904 + * names of its contributors may be used to endorse or promote products
89905 + * derived from this software without specific prior written permission.
89906 + *
89907 + *
89908 + * ALTERNATIVELY, this software may be distributed under the terms of the
89909 + * GNU General Public License ("GPL") as published by the Free Software
89910 + * Foundation, either version 2 of that License or (at your option) any
89911 + * later version.
89912 + *
89913 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89914 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89915 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89916 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89917 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89918 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89919 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89920 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89921 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89922 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89923 + */
89924 +
89925 +
89926 +/**************************************************************************//**
89927 + @File enet_ext.h
89928 +
89929 + @Description Ethernet generic definitions and enums.
89930 +*//***************************************************************************/
89931 +
89932 +#ifndef __ENET_EXT_H
89933 +#define __ENET_EXT_H
89934 +
89935 +#include "fsl_enet.h"
89936 +
89937 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
89938 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
89939 +
89940 +
89941 +/**************************************************************************//**
89942 + @Description Ethernet Address
89943 +*//***************************************************************************/
89944 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
89945 +
89946 +/**************************************************************************//**
89947 + @Description Ethernet Address Type.
89948 +*//***************************************************************************/
89949 +typedef enum e_EnetAddrType
89950 +{
89951 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
89952 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
89953 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
89954 +} e_EnetAddrType;
89955 +
89956 +/**************************************************************************//**
89957 + @Description Ethernet MAC-PHY Interface
89958 +*//***************************************************************************/
89959 +typedef enum e_EnetInterface
89960 +{
89961 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
89962 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
89963 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
89964 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
89965 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
89966 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
89967 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
89968 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
89969 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
89970 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
89971 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
89972 +} e_EnetInterface;
89973 +
89974 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
89975 + auto-negotiation between MAC and phy
89976 + or backplane;
89977 + Note: 1000BaseX auto-negotiation relates
89978 + only to interface between MAC and phy/backplane,
89979 + SGMII phy can still synchronize with far-end phy
89980 + at 10Mbps, 100Mbps or 1000Mbps */
89981 +
89982 +/**************************************************************************//**
89983 + @Description Ethernet Duplex Mode
89984 +*//***************************************************************************/
89985 +typedef enum e_EnetDuplexMode
89986 +{
89987 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
89988 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
89989 +} e_EnetDuplexMode;
89990 +
89991 +/**************************************************************************//**
89992 + @Description Ethernet Speed (nominal data rate)
89993 +*//***************************************************************************/
89994 +typedef enum e_EnetSpeed
89995 +{
89996 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
89997 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
89998 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
89999 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
90000 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
90001 +} e_EnetSpeed;
90002 +
90003 +/**************************************************************************//**
90004 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
90005 +*//***************************************************************************/
90006 +typedef enum e_EnetMode
90007 +{
90008 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
90009 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
90010 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
90011 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
90012 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
90013 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
90014 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
90015 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
90016 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
90017 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
90018 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
90019 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
90020 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
90021 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
90022 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
90023 + SGMII phy according to Cisco SGMII specification */
90024 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
90025 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
90026 + SGMII phy according to Cisco SGMII specification */
90027 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90028 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
90029 + SGMII phy according to Cisco SGMII specification */
90030 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
90031 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
90032 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
90033 + MAC and SGMII phy or backplane */
90034 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
90035 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
90036 + MAC and SGMII phy or backplane */
90037 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
90038 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
90039 + MAC and SGMII phy or backplane */
90040 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90041 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
90042 + QSGMII phy according to Cisco QSGMII specification */
90043 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
90044 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
90045 + MAC and QSGMII phy or backplane */
90046 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
90047 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
90048 +} e_EnetMode;
90049 +
90050 +
90051 +#define IS_ENET_MODE_VALID(mode) \
90052 + (((mode) == e_ENET_MODE_MII_10 ) || \
90053 + ((mode) == e_ENET_MODE_MII_100 ) || \
90054 + ((mode) == e_ENET_MODE_RMII_10 ) || \
90055 + ((mode) == e_ENET_MODE_RMII_100 ) || \
90056 + ((mode) == e_ENET_MODE_SMII_10 ) || \
90057 + ((mode) == e_ENET_MODE_SMII_100 ) || \
90058 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
90059 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
90060 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
90061 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
90062 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
90063 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
90064 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
90065 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
90066 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
90067 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
90068 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
90069 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
90070 + ((mode) == e_ENET_MODE_XGMII_10000) || \
90071 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
90072 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
90073 + ((mode) == e_ENET_MODE_XFI_10000))
90074 +
90075 +
90076 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
90077 +
90078 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
90079 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
90080 +
90081 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
90082 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
90083 + ((uint64_t)(_enetAddr)[1] << 32) | \
90084 + ((uint64_t)(_enetAddr)[2] << 24) | \
90085 + ((uint64_t)(_enetAddr)[3] << 16) | \
90086 + ((uint64_t)(_enetAddr)[4] << 8) | \
90087 + ((uint64_t)(_enetAddr)[5]))
90088 +
90089 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
90090 + do { \
90091 + int i; \
90092 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
90093 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
90094 + } while (0)
90095 +
90096 +
90097 +#endif /* __ENET_EXT_H */
90098 --- /dev/null
90099 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
90100 @@ -0,0 +1,529 @@
90101 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90102 + * All rights reserved.
90103 + *
90104 + * Redistribution and use in source and binary forms, with or without
90105 + * modification, are permitted provided that the following conditions are met:
90106 + * * Redistributions of source code must retain the above copyright
90107 + * notice, this list of conditions and the following disclaimer.
90108 + * * Redistributions in binary form must reproduce the above copyright
90109 + * notice, this list of conditions and the following disclaimer in the
90110 + * documentation and/or other materials provided with the distribution.
90111 + * * Neither the name of Freescale Semiconductor nor the
90112 + * names of its contributors may be used to endorse or promote products
90113 + * derived from this software without specific prior written permission.
90114 + *
90115 + *
90116 + * ALTERNATIVELY, this software may be distributed under the terms of the
90117 + * GNU General Public License ("GPL") as published by the Free Software
90118 + * Foundation, either version 2 of that License or (at your option) any
90119 + * later version.
90120 + *
90121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90131 + */
90132 +
90133 +
90134 +/**************************************************************************//**
90135 + @File error_ext.h
90136 +
90137 + @Description Error definitions.
90138 +*//***************************************************************************/
90139 +
90140 +#ifndef __ERROR_EXT_H
90141 +#define __ERROR_EXT_H
90142 +
90143 +#if !defined(NCSW_LINUX)
90144 +#include <errno.h>
90145 +#endif
90146 +
90147 +#include "std_ext.h"
90148 +#include "xx_ext.h"
90149 +#include "core_ext.h"
90150 +
90151 +
90152 +
90153 +
90154 +/**************************************************************************//**
90155 + @Group gen_id General Drivers Utilities
90156 +
90157 + @Description External routines.
90158 +
90159 + @{
90160 +*//***************************************************************************/
90161 +
90162 +/**************************************************************************//**
90163 + @Group gen_error_id Errors, Events and Debug
90164 +
90165 + @Description External routines.
90166 +
90167 + @{
90168 +*//***************************************************************************/
90169 +
90170 +/******************************************************************************
90171 +The scheme below provides the bits description for error codes:
90172 +
90173 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
90174 +| Reserved (should be zero) | Module ID |
90175 +
90176 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
90177 +| Error Type |
90178 +******************************************************************************/
90179 +
90180 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
90181 +
90182 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
90183 + /**< Extract module code from error code (#t_Error) */
90184 +
90185 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
90186 + /**< Extract error type (#e_ErrorType) from
90187 + error code (#t_Error) */
90188 +
90189 +
90190 +/**************************************************************************//**
90191 + @Description Error Type Enumeration
90192 +*//***************************************************************************/
90193 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
90194 +{ /* ------------------------------------------------------------ */
90195 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
90196 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
90197 + /* String: none, or device name. */
90198 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
90199 + /* String: none. */
90200 + ,E_NOT_AVAILABLE = EAGAIN
90201 + /**< Resource is unavailable. */
90202 + /* String: none, unless the operation is not the main goal
90203 + of the function (in this case add resource description). */
90204 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
90205 + /* String: description of item for which allocation failed. */
90206 + ,E_INVALID_ADDRESS = EFAULT
90207 + /**< Invalid address. */
90208 + /* String: description of the specific violation. */
90209 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
90210 + /* String: none, unless the operation is not the main goal
90211 + of the function (in this case add resource description). */
90212 + ,E_ALREADY_EXISTS = EEXIST
90213 + /**< Requested resource or item already exists. */
90214 + /* Use when resource duplication or sharing are not allowed.
90215 + String: none, unless the operation is not the main goal
90216 + of the function (in this case add item description). */
90217 + ,E_INVALID_OPERATION = ENODEV
90218 + /**< The operation/command is invalid (unrecognized). */
90219 + /* String: none. */
90220 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
90221 + /* Use for non-enumeration parameters, and
90222 + only when other error types are not suitable.
90223 + String: parameter description + "(should be <attribute>)",
90224 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
90225 + "Channel number (should be even)". */
90226 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
90227 + /* Don't use this error for enumeration parameters.
90228 + String: parameter description + "(should be %d-%d)",
90229 + e.g: "Number of pad characters (should be 0-15)". */
90230 + ,E_NOT_SUPPORTED = ENOSYS
90231 + /**< The function is not supported or not implemented. */
90232 + /* String: none. */
90233 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
90234 + /* String: none. */
90235 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
90236 + /* String: none, unless the function takes in more than one
90237 + handle (in this case add the handle description) */
90238 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
90239 + /* String: none, unless the function takes in more than one
90240 + ID (in this case add the ID description) */
90241 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
90242 + /* String: pointer description. */
90243 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
90244 + /* Use for enumeration values, only when other error types
90245 + are not suitable.
90246 + String: parameter description. */
90247 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
90248 + /* String: none, unless the function takes in more than one
90249 + communication mode indications (in this case add
90250 + parameter description). */
90251 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
90252 + /* String: none, unless the function takes in more than one
90253 + memory types (in this case add memory description,
90254 + e.g: "Data memory", "Buffer descriptors memory"). */
90255 + ,E_INVALID_CLOCK /**< Invalid clock. */
90256 + /* String: none, unless the function takes in more than one
90257 + clocks (in this case add clock description,
90258 + e.g: "Rx clock", "Tx clock"). */
90259 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
90260 + /* String: description of the conflicting settings. */
90261 + ,E_NOT_ALIGNED /**< Non-aligned address. */
90262 + /* String: parameter description + "(should be %d-bytes aligned)",
90263 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
90264 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
90265 + /* Use only when the resource/item is uniquely identified.
90266 + String: none, unless the operation is not the main goal
90267 + of the function (in this case add item description). */
90268 + ,E_FULL /**< Resource is full. */
90269 + /* String: none, unless the operation is not the main goal
90270 + of the function (in this case add resource description). */
90271 + ,E_EMPTY /**< Resource is empty. */
90272 + /* String: none, unless the operation is not the main goal
90273 + of the function (in this case add resource description). */
90274 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
90275 + /* String: none, unless the operation is not the main goal
90276 + of the function (in this case add item description). */
90277 + ,E_READ_FAILED /**< Read access failed on memory/device. */
90278 + /* String: none, or device name. */
90279 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
90280 + /* String: none. */
90281 + ,E_SEND_FAILED /**< Send operation failed on device. */
90282 + /* String: none, or device name. */
90283 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
90284 + /* String: none, or device name. */
90285 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
90286 + /* String: none. */
90287 +
90288 + ,E_DUMMY_LAST /* NEVER USED */
90289 +
90290 +} e_ErrorType;
90291 +
90292 +/**************************************************************************//**
90293 + @Description Event Type Enumeration
90294 +*//***************************************************************************/
90295 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
90296 +{ /* ------------------------------------------------------------ */
90297 + EV_NO_EVENT = 0 /**< No event; Never used. */
90298 +
90299 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
90300 + complete packets);
90301 + Flags: error flags in case of error, zero otherwise. */
90302 + /* String: reason for discard, e.g: "Error in frame",
90303 + "Disordered frame", "Incomplete frame", "No frame object". */
90304 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
90305 + Flags: usually status flags from the buffer descriptor. */
90306 + /* String: none. */
90307 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
90308 + Flags: usually status flags from the buffer descriptor. */
90309 + /* String: none. */
90310 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
90311 + Flags: zero. */
90312 + /* String: none. */
90313 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
90314 + Flags: zero. */
90315 + /* String: none. */
90316 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
90317 + Flags: zero. */
90318 + /* String: none. */
90319 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
90320 + Flags: zero. */
90321 + /* String: none. */
90322 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
90323 + Flags: zero. */
90324 + /* String: none. */
90325 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
90326 + Flags: zero. */
90327 + /* String: none. */
90328 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
90329 + Flags: zero. */
90330 + /* String: none. */
90331 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
90332 + Flags: zero. */
90333 + /* String: object description (name). */
90334 + ,EV_BUS_ERROR /**< Illegal access on bus;
90335 + Flags: the address (if available) or bus identifier */
90336 + /* String: bus/address/module description. */
90337 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
90338 + Flags: zero. */
90339 + /* String: none. */
90340 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
90341 + Flags: zero. */
90342 + /* String: none. */
90343 + ,EV_DUMMY_LAST
90344 +
90345 +} e_Event;
90346 +
90347 +
90348 +/**************************************************************************//**
90349 + @Collection Debug Levels for Errors and Events
90350 +
90351 + The level description refers to errors only.
90352 + For events, classification is done by the user.
90353 +
90354 + The TRACE, INFO and WARNING levels are allowed only when using
90355 + the DBG macro, and are not allowed when using the error macros
90356 + (RETURN_ERROR or REPORT_ERROR).
90357 + @{
90358 +*//***************************************************************************/
90359 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
90360 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
90361 + configuration. */
90362 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
90363 + parameters may be successful. */
90364 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
90365 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
90366 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
90367 +
90368 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
90369 +
90370 +/* @} */
90371 +
90372 +
90373 +
90374 +#define NO_MSG ("")
90375 +
90376 +#ifndef DEBUG_GLOBAL_LEVEL
90377 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
90378 +#endif /* DEBUG_GLOBAL_LEVEL */
90379 +
90380 +#ifndef ERROR_GLOBAL_LEVEL
90381 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
90382 +#endif /* ERROR_GLOBAL_LEVEL */
90383 +
90384 +#ifndef EVENT_GLOBAL_LEVEL
90385 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
90386 +#endif /* EVENT_GLOBAL_LEVEL */
90387 +
90388 +#ifdef EVENT_LOCAL_LEVEL
90389 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
90390 +#else
90391 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
90392 +#endif /* EVENT_LOCAL_LEVEL */
90393 +
90394 +
90395 +#ifndef DEBUG_DYNAMIC_LEVEL
90396 +#define DEBUG_USING_STATIC_LEVEL
90397 +
90398 +#ifdef DEBUG_STATIC_LEVEL
90399 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
90400 +#else
90401 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
90402 +#endif /* DEBUG_STATIC_LEVEL */
90403 +
90404 +#else /* DEBUG_DYNAMIC_LEVEL */
90405 +#ifdef DEBUG_STATIC_LEVEL
90406 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
90407 +#else
90408 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
90409 +#endif /* DEBUG_STATIC_LEVEL */
90410 +#endif /* !DEBUG_DYNAMIC_LEVEL */
90411 +
90412 +
90413 +#ifndef ERROR_DYNAMIC_LEVEL
90414 +
90415 +#ifdef ERROR_STATIC_LEVEL
90416 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
90417 +#else
90418 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
90419 +#endif /* ERROR_STATIC_LEVEL */
90420 +
90421 +#else /* ERROR_DYNAMIC_LEVEL */
90422 +#ifdef ERROR_STATIC_LEVEL
90423 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
90424 +#else
90425 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
90426 +#endif /* ERROR_STATIC_LEVEL */
90427 +#endif /* !ERROR_DYNAMIC_LEVEL */
90428 +
90429 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
90430 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
90431 +
90432 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
90433 +/* No debug/error/event messages at all */
90434 +#define DBG(_level, _vmsg)
90435 +
90436 +#define REPORT_ERROR(_level, _err, _vmsg)
90437 +
90438 +#define RETURN_ERROR(_level, _err, _vmsg) \
90439 + return ERROR_CODE(_err)
90440 +
90441 +#if (REPORT_EVENTS > 0)
90442 +
90443 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90444 + do { \
90445 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90446 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90447 + } \
90448 + } while (0)
90449 +
90450 +#else
90451 +
90452 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90453 +
90454 +#endif /* (REPORT_EVENTS > 0) */
90455 +
90456 +
90457 +#else /* DEBUG_ERRORS > 0 */
90458 +
90459 +extern const char *dbgLevelStrings[];
90460 +extern const char *moduleStrings[];
90461 +#if (REPORT_EVENTS > 0)
90462 +extern const char *eventStrings[];
90463 +#endif /* (REPORT_EVENTS > 0) */
90464 +
90465 +char * ErrTypeStrings (e_ErrorType err);
90466 +
90467 +
90468 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
90469 +/* No need for DBG macro - debug level is higher anyway */
90470 +#define DBG(_level, _vmsg)
90471 +#else
90472 +#define DBG(_level, _vmsg) \
90473 + do { \
90474 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
90475 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
90476 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90477 + moduleStrings[__ERR_MODULE__ >> 16], \
90478 + PRINT_FMT_PARAMS); \
90479 + XX_Print _vmsg; \
90480 + XX_Print("\r\n"); \
90481 + } \
90482 + } while (0)
90483 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
90484 +
90485 +
90486 +#define REPORT_ERROR(_level, _err, _vmsg) \
90487 + do { \
90488 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
90489 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
90490 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
90491 + moduleStrings[__ERR_MODULE__ >> 16], \
90492 + PRINT_FMT_PARAMS, \
90493 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
90494 + XX_Print _vmsg; \
90495 + XX_Print("\r\n"); \
90496 + } \
90497 + } while (0)
90498 +
90499 +
90500 +#define RETURN_ERROR(_level, _err, _vmsg) \
90501 + do { \
90502 + REPORT_ERROR(_level, (_err), _vmsg); \
90503 + return ERROR_CODE(_err); \
90504 + } while (0)
90505 +
90506 +
90507 +#if (REPORT_EVENTS > 0)
90508 +
90509 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
90510 + do { \
90511 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
90512 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
90513 + dbgLevelStrings[_ev##_LEVEL - 1], \
90514 + moduleStrings[__ERR_MODULE__ >> 16], \
90515 + PRINT_FMT_PARAMS, \
90516 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
90517 + (uint16_t)(_flg)); \
90518 + XX_Print _vmsg; \
90519 + XX_Print("\r\n"); \
90520 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
90521 + } \
90522 + } while (0)
90523 +
90524 +#else /* not REPORT_EVENTS */
90525 +
90526 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
90527 +
90528 +#endif /* (REPORT_EVENTS > 0) */
90529 +
90530 +#endif /* (DEBUG_ERRORS > 0) */
90531 +
90532 +
90533 +/**************************************************************************//**
90534 + @Function ASSERT_COND
90535 +
90536 + @Description Assertion macro.
90537 +
90538 + @Param[in] _cond - The condition being checked, in positive form;
90539 + Failure of the condition triggers the assert.
90540 +*//***************************************************************************/
90541 +#ifdef DISABLE_ASSERTIONS
90542 +#define ASSERT_COND(_cond)
90543 +#else
90544 +#define ASSERT_COND(_cond) \
90545 + do { \
90546 + if (!(_cond)) { \
90547 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
90548 + PRINT_FMT_PARAMS); \
90549 + XX_Exit(1); \
90550 + } \
90551 + } while (0)
90552 +#endif /* DISABLE_ASSERTIONS */
90553 +
90554 +
90555 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
90556 +
90557 +#define CHECK_INIT_PARAMETERS(handle, f_check)
90558 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
90559 +
90560 +#else
90561 +
90562 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
90563 + do { \
90564 + t_Error err = f_check(handle); \
90565 + if (err != E_OK) { \
90566 + RETURN_ERROR(MAJOR, err, NO_MSG); \
90567 + } \
90568 + } while (0)
90569 +
90570 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
90571 + do { \
90572 + t_Error err = f_check(handle); \
90573 + if (err != E_OK) { \
90574 + REPORT_ERROR(MAJOR, err, NO_MSG); \
90575 + return (retval); \
90576 + } \
90577 + } while (0)
90578 +
90579 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
90580 +
90581 +#ifdef DISABLE_SANITY_CHECKS
90582 +
90583 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
90584 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
90585 +#define SANITY_CHECK_RETURN(_cond, _err)
90586 +#define SANITY_CHECK_EXIT(_cond, _err)
90587 +
90588 +#else /* DISABLE_SANITY_CHECKS */
90589 +
90590 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
90591 + do { \
90592 + if (!(_cond)) { \
90593 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
90594 + } \
90595 + } while (0)
90596 +
90597 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
90598 + do { \
90599 + if (!(_cond)) { \
90600 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90601 + return (retval); \
90602 + } \
90603 + } while (0)
90604 +
90605 +#define SANITY_CHECK_RETURN(_cond, _err) \
90606 + do { \
90607 + if (!(_cond)) { \
90608 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90609 + return; \
90610 + } \
90611 + } while (0)
90612 +
90613 +#define SANITY_CHECK_EXIT(_cond, _err) \
90614 + do { \
90615 + if (!(_cond)) { \
90616 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
90617 + XX_Exit(1); \
90618 + } \
90619 + } while (0)
90620 +
90621 +#endif /* DISABLE_SANITY_CHECKS */
90622 +
90623 +/** @} */ /* end of Debug/error Utils group */
90624 +
90625 +/** @} */ /* end of General Utils group */
90626 +
90627 +#endif /* __ERROR_EXT_H */
90628 +
90629 +
90630 --- /dev/null
90631 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
90632 @@ -0,0 +1,358 @@
90633 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90634 + * All rights reserved.
90635 + *
90636 + * Redistribution and use in source and binary forms, with or without
90637 + * modification, are permitted provided that the following conditions are met:
90638 + * * Redistributions of source code must retain the above copyright
90639 + * notice, this list of conditions and the following disclaimer.
90640 + * * Redistributions in binary form must reproduce the above copyright
90641 + * notice, this list of conditions and the following disclaimer in the
90642 + * documentation and/or other materials provided with the distribution.
90643 + * * Neither the name of Freescale Semiconductor nor the
90644 + * names of its contributors may be used to endorse or promote products
90645 + * derived from this software without specific prior written permission.
90646 + *
90647 + *
90648 + * ALTERNATIVELY, this software may be distributed under the terms of the
90649 + * GNU General Public License ("GPL") as published by the Free Software
90650 + * Foundation, either version 2 of that License or (at your option) any
90651 + * later version.
90652 + *
90653 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90654 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90655 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90656 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90657 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90658 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90659 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90660 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90661 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90662 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90663 + */
90664 +
90665 +
90666 +/**************************************************************************//**
90667 +
90668 + @File list_ext.h
90669 +
90670 + @Description External prototypes for list.c
90671 +*//***************************************************************************/
90672 +
90673 +#ifndef __LIST_EXT_H
90674 +#define __LIST_EXT_H
90675 +
90676 +
90677 +#include "std_ext.h"
90678 +
90679 +
90680 +/**************************************************************************//**
90681 + @Group etc_id Utility Library Application Programming Interface
90682 +
90683 + @Description External routines.
90684 +
90685 + @{
90686 +*//***************************************************************************/
90687 +
90688 +/**************************************************************************//**
90689 + @Group list_id List
90690 +
90691 + @Description List module functions,definitions and enums.
90692 +
90693 + @{
90694 +*//***************************************************************************/
90695 +
90696 +/**************************************************************************//**
90697 + @Description List structure.
90698 +*//***************************************************************************/
90699 +typedef struct List
90700 +{
90701 + struct List *p_Next; /**< A pointer to the next list object */
90702 + struct List *p_Prev; /**< A pointer to the previous list object */
90703 +} t_List;
90704 +
90705 +
90706 +/**************************************************************************//**
90707 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
90708 +
90709 + @Description Macro to get first/last/next/previous entry in a list.
90710 +
90711 + @Param[in] p_List - A pointer to a list.
90712 +*//***************************************************************************/
90713 +#define LIST_FIRST(p_List) (p_List)->p_Next
90714 +#define LIST_LAST(p_List) (p_List)->p_Prev
90715 +#define LIST_NEXT LIST_FIRST
90716 +#define LIST_PREV LIST_LAST
90717 +
90718 +
90719 +/**************************************************************************//**
90720 + @Function LIST_INIT
90721 +
90722 + @Description Macro for initialization of a list struct.
90723 +
90724 + @Param[in] lst - The t_List object to initialize.
90725 +*//***************************************************************************/
90726 +#define LIST_INIT(lst) {&(lst), &(lst)}
90727 +
90728 +
90729 +/**************************************************************************//**
90730 + @Function LIST
90731 +
90732 + @Description Macro to declare of a list.
90733 +
90734 + @Param[in] listName - The list object name.
90735 +*//***************************************************************************/
90736 +#define LIST(listName) t_List listName = LIST_INIT(listName)
90737 +
90738 +
90739 +/**************************************************************************//**
90740 + @Function INIT_LIST
90741 +
90742 + @Description Macro to initialize a list pointer.
90743 +
90744 + @Param[in] p_List - The list pointer.
90745 +*//***************************************************************************/
90746 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
90747 +
90748 +
90749 +/**************************************************************************//**
90750 + @Function LIST_OBJECT
90751 +
90752 + @Description Macro to get the struct (object) for this entry.
90753 +
90754 + @Param[in] type - The type of the struct (object) this list is embedded in.
90755 + @Param[in] member - The name of the t_List object within the struct.
90756 +
90757 + @Return The structure pointer for this entry.
90758 +*//***************************************************************************/
90759 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
90760 +#define LIST_OBJECT(p_List, type, member) \
90761 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
90762 +
90763 +
90764 +/**************************************************************************//**
90765 + @Function LIST_FOR_EACH
90766 +
90767 + @Description Macro to iterate over a list.
90768 +
90769 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90770 + @Param[in] p_Head - A pointer to the head for your list pointer.
90771 +
90772 + @Cautions You can't delete items with this routine.
90773 + For deletion use LIST_FOR_EACH_SAFE().
90774 +*//***************************************************************************/
90775 +#define LIST_FOR_EACH(p_Pos, p_Head) \
90776 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
90777 +
90778 +
90779 +/**************************************************************************//**
90780 + @Function LIST_FOR_EACH_SAFE
90781 +
90782 + @Description Macro to iterate over a list safe against removal of list entry.
90783 +
90784 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90785 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90786 + @Param[in] p_Head - A pointer to the head for your list pointer.
90787 +*//***************************************************************************/
90788 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
90789 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
90790 + p_Pos != (p_Head); \
90791 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
90792 +
90793 +
90794 +/**************************************************************************//**
90795 + @Function LIST_FOR_EACH_OBJECT_SAFE
90796 +
90797 + @Description Macro to iterate over list of given type safely.
90798 +
90799 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90800 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
90801 + @Param[in] type - The type of the struct this is embedded in.
90802 + @Param[in] p_Head - A pointer to the head for your list pointer.
90803 + @Param[in] member - The name of the list_struct within the struct.
90804 +
90805 + @Cautions You can't delete items with this routine.
90806 + For deletion use LIST_FOR_EACH_SAFE().
90807 +*//***************************************************************************/
90808 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
90809 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
90810 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
90811 + &p_Pos->member != (p_Head); \
90812 + p_Pos = p_Tmp, \
90813 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
90814 +
90815 +/**************************************************************************//**
90816 + @Function LIST_FOR_EACH_OBJECT
90817 +
90818 + @Description Macro to iterate over list of given type.
90819 +
90820 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
90821 + @Param[in] type - The type of the struct this is embedded in.
90822 + @Param[in] p_Head - A pointer to the head for your list pointer.
90823 + @Param[in] member - The name of the list_struct within the struct.
90824 +
90825 + @Cautions You can't delete items with this routine.
90826 + For deletion use LIST_FOR_EACH_SAFE().
90827 +*//***************************************************************************/
90828 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
90829 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
90830 + &p_Pos->member != (p_Head); \
90831 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
90832 +
90833 +
90834 +/**************************************************************************//**
90835 + @Function LIST_Add
90836 +
90837 + @Description Add a new entry to a list.
90838 +
90839 + Insert a new entry after the specified head.
90840 + This is good for implementing stacks.
90841 +
90842 + @Param[in] p_New - A pointer to a new list entry to be added.
90843 + @Param[in] p_Head - A pointer to a list head to add it after.
90844 +
90845 + @Return none.
90846 +*//***************************************************************************/
90847 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
90848 +{
90849 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
90850 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
90851 + LIST_PREV(p_New) = p_Head;
90852 + LIST_NEXT(p_Head) = p_New;
90853 +}
90854 +
90855 +
90856 +/**************************************************************************//**
90857 + @Function LIST_AddToTail
90858 +
90859 + @Description Add a new entry to a list.
90860 +
90861 + Insert a new entry before the specified head.
90862 + This is useful for implementing queues.
90863 +
90864 + @Param[in] p_New - A pointer to a new list entry to be added.
90865 + @Param[in] p_Head - A pointer to a list head to add it before.
90866 +
90867 + @Return none.
90868 +*//***************************************************************************/
90869 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
90870 +{
90871 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
90872 + LIST_PREV(p_New) = LIST_PREV(p_Head);
90873 + LIST_NEXT(p_New) = p_Head;
90874 + LIST_PREV(p_Head) = p_New;
90875 +}
90876 +
90877 +
90878 +/**************************************************************************//**
90879 + @Function LIST_Del
90880 +
90881 + @Description Deletes entry from a list.
90882 +
90883 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90884 +
90885 + @Return none.
90886 +
90887 + @Cautions LIST_IsEmpty() on entry does not return true after this,
90888 + the entry is in an undefined state.
90889 +*//***************************************************************************/
90890 +static __inline__ void LIST_Del(t_List *p_Entry)
90891 +{
90892 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
90893 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
90894 +}
90895 +
90896 +
90897 +/**************************************************************************//**
90898 + @Function LIST_DelAndInit
90899 +
90900 + @Description Deletes entry from list and reinitialize it.
90901 +
90902 + @Param[in] p_Entry - A pointer to the element to delete from the list.
90903 +
90904 + @Return none.
90905 +*//***************************************************************************/
90906 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
90907 +{
90908 + LIST_Del(p_Entry);
90909 + INIT_LIST(p_Entry);
90910 +}
90911 +
90912 +
90913 +/**************************************************************************//**
90914 + @Function LIST_Move
90915 +
90916 + @Description Delete from one list and add as another's head.
90917 +
90918 + @Param[in] p_Entry - A pointer to the list entry to move.
90919 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
90920 +
90921 + @Return none.
90922 +*//***************************************************************************/
90923 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
90924 +{
90925 + LIST_Del(p_Entry);
90926 + LIST_Add(p_Entry, p_Head);
90927 +}
90928 +
90929 +
90930 +/**************************************************************************//**
90931 + @Function LIST_MoveToTail
90932 +
90933 + @Description Delete from one list and add as another's tail.
90934 +
90935 + @Param[in] p_Entry - A pointer to the entry to move.
90936 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
90937 +
90938 + @Return none.
90939 +*//***************************************************************************/
90940 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
90941 +{
90942 + LIST_Del(p_Entry);
90943 + LIST_AddToTail(p_Entry, p_Head);
90944 +}
90945 +
90946 +
90947 +/**************************************************************************//**
90948 + @Function LIST_IsEmpty
90949 +
90950 + @Description Tests whether a list is empty.
90951 +
90952 + @Param[in] p_List - A pointer to the list to test.
90953 +
90954 + @Return 1 if the list is empty, 0 otherwise.
90955 +*//***************************************************************************/
90956 +static __inline__ int LIST_IsEmpty(t_List *p_List)
90957 +{
90958 + return (LIST_FIRST(p_List) == p_List);
90959 +}
90960 +
90961 +
90962 +/**************************************************************************//**
90963 + @Function LIST_Append
90964 +
90965 + @Description Join two lists.
90966 +
90967 + @Param[in] p_NewList - A pointer to the new list to add.
90968 + @Param[in] p_Head - A pointer to the place to add it in the first list.
90969 +
90970 + @Return none.
90971 +*//***************************************************************************/
90972 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
90973 +
90974 +
90975 +/**************************************************************************//**
90976 + @Function LIST_NumOfObjs
90977 +
90978 + @Description Counts number of objects in the list
90979 +
90980 + @Param[in] p_List - A pointer to the list which objects are to be counted.
90981 +
90982 + @Return Number of objects in the list.
90983 +*//***************************************************************************/
90984 +int LIST_NumOfObjs(t_List *p_List);
90985 +
90986 +/** @} */ /* end of list_id group */
90987 +/** @} */ /* end of etc_id group */
90988 +
90989 +
90990 +#endif /* __LIST_EXT_H */
90991 --- /dev/null
90992 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
90993 @@ -0,0 +1,318 @@
90994 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
90995 + * All rights reserved.
90996 + *
90997 + * Redistribution and use in source and binary forms, with or without
90998 + * modification, are permitted provided that the following conditions are met:
90999 + * * Redistributions of source code must retain the above copyright
91000 + * notice, this list of conditions and the following disclaimer.
91001 + * * Redistributions in binary form must reproduce the above copyright
91002 + * notice, this list of conditions and the following disclaimer in the
91003 + * documentation and/or other materials provided with the distribution.
91004 + * * Neither the name of Freescale Semiconductor nor the
91005 + * names of its contributors may be used to endorse or promote products
91006 + * derived from this software without specific prior written permission.
91007 + *
91008 + *
91009 + * ALTERNATIVELY, this software may be distributed under the terms of the
91010 + * GNU General Public License ("GPL") as published by the Free Software
91011 + * Foundation, either version 2 of that License or (at your option) any
91012 + * later version.
91013 + *
91014 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91015 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91016 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91017 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91018 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91019 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91020 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91021 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91022 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91023 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91024 + */
91025 +
91026 +
91027 +/**************************************************************************//**
91028 +
91029 + @File mem_ext.h
91030 +
91031 + @Description External prototypes for the memory manager object
91032 +*//***************************************************************************/
91033 +
91034 +#ifndef __MEM_EXT_H
91035 +#define __MEM_EXT_H
91036 +
91037 +#include "std_ext.h"
91038 +#include "part_ext.h"
91039 +
91040 +
91041 +/**************************************************************************//**
91042 + @Group etc_id Utility Library Application Programming Interface
91043 +
91044 + @Description External routines.
91045 +
91046 + @{
91047 +*//***************************************************************************/
91048 +
91049 +/**************************************************************************//**
91050 + @Group mem_id Slab Memory Manager
91051 +
91052 + @Description Slab Memory Manager module functions, definitions and enums.
91053 +
91054 + @{
91055 +*//***************************************************************************/
91056 +
91057 +/* Each block is of the following structure:
91058 + *
91059 + *
91060 + * +-----------+----------+---------------------------+-----------+-----------+
91061 + * | Alignment | Prefix | Data | Postfix | Alignment |
91062 + * | field | field | field | field | Padding |
91063 + * | | | | | |
91064 + * +-----------+----------+---------------------------+-----------+-----------+
91065 + * and at the beginning of all bytes, an additional optional padding might reside
91066 + * to ensure that the first blocks data field is aligned as requested.
91067 + */
91068 +
91069 +
91070 +#define MEM_MAX_NAME_LENGTH 8
91071 +
91072 +/**************************************************************************//*
91073 + @Description Memory Segment structure
91074 +*//***************************************************************************/
91075 +
91076 +typedef struct
91077 +{
91078 + char name[MEM_MAX_NAME_LENGTH];
91079 + /* The segment's name */
91080 + uint8_t **p_Bases; /* Base addresses of the segments */
91081 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
91082 + t_Handle h_Spinlock;
91083 + uint16_t dataSize; /* Size of each data block */
91084 + uint16_t prefixSize; /* How many bytes to reserve before the data */
91085 + uint16_t postfixSize; /* How many bytes to reserve after the data */
91086 + uint16_t alignment; /* Requested alignment for the data field */
91087 + int allocOwner; /* Memory allocation owner */
91088 + uint32_t getFailures; /* Number of times get failed */
91089 + uint32_t num; /* Number of blocks in segment */
91090 + uint32_t current; /* Current block */
91091 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
91092 +#ifdef DEBUG_MEM_LEAKS
91093 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
91094 + uint32_t blockOffset;
91095 + uint32_t blockSize;
91096 +#endif /* DEBUG_MEM_LEAKS */
91097 +} t_MemorySegment;
91098 +
91099 +
91100 +
91101 +/**************************************************************************//**
91102 + @Function MEM_Init
91103 +
91104 + @Description Create a new memory segment.
91105 +
91106 + @Param[in] name - Name of memory partition.
91107 + @Param[in] p_Handle - Handle to new segment is returned through here.
91108 + @Param[in] num - Number of blocks in new segment.
91109 + @Param[in] dataSize - Size of blocks in segment.
91110 + @Param[in] prefixSize - How many bytes to allocate before the data.
91111 + @Param[in] postfixSize - How many bytes to allocate after the data.
91112 + @Param[in] alignment - Requested alignment for data field (in bytes).
91113 +
91114 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91115 +*//***************************************************************************/
91116 +t_Error MEM_Init(char name[],
91117 + t_Handle *p_Handle,
91118 + uint32_t num,
91119 + uint16_t dataSize,
91120 + uint16_t prefixSize,
91121 + uint16_t postfixSize,
91122 + uint16_t alignment);
91123 +
91124 +/**************************************************************************//**
91125 + @Function MEM_InitSmart
91126 +
91127 + @Description Create a new memory segment.
91128 +
91129 + @Param[in] name - Name of memory partition.
91130 + @Param[in] p_Handle - Handle to new segment is returned through here.
91131 + @Param[in] num - Number of blocks in new segment.
91132 + @Param[in] dataSize - Size of blocks in segment.
91133 + @Param[in] prefixSize - How many bytes to allocate before the data.
91134 + @Param[in] postfixSize - How many bytes to allocate after the data.
91135 + @Param[in] alignment - Requested alignment for data field (in bytes).
91136 + @Param[in] memPartitionId - Memory partition ID for allocation.
91137 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
91138 + continuously or not.
91139 +
91140 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91141 +*//***************************************************************************/
91142 +t_Error MEM_InitSmart(char name[],
91143 + t_Handle *p_Handle,
91144 + uint32_t num,
91145 + uint16_t dataSize,
91146 + uint16_t prefixSize,
91147 + uint16_t postfixSize,
91148 + uint16_t alignment,
91149 + uint8_t memPartitionId,
91150 + bool consecutiveMem);
91151 +
91152 +/**************************************************************************//**
91153 + @Function MEM_InitByAddress
91154 +
91155 + @Description Create a new memory segment with a specified base address.
91156 +
91157 + @Param[in] name - Name of memory partition.
91158 + @Param[in] p_Handle - Handle to new segment is returned through here.
91159 + @Param[in] num - Number of blocks in new segment.
91160 + @Param[in] dataSize - Size of blocks in segment.
91161 + @Param[in] prefixSize - How many bytes to allocate before the data.
91162 + @Param[in] postfixSize - How many bytes to allocate after the data.
91163 + @Param[in] alignment - Requested alignment for data field (in bytes).
91164 + @Param[in] address - The required base address.
91165 +
91166 + @Return E_OK - success, E_NO_MEMORY - out of memory.
91167 + *//***************************************************************************/
91168 +t_Error MEM_InitByAddress(char name[],
91169 + t_Handle *p_Handle,
91170 + uint32_t num,
91171 + uint16_t dataSize,
91172 + uint16_t prefixSize,
91173 + uint16_t postfixSize,
91174 + uint16_t alignment,
91175 + uint8_t *address);
91176 +
91177 +/**************************************************************************//**
91178 + @Function MEM_Free
91179 +
91180 + @Description Free a specific memory segment.
91181 +
91182 + @Param[in] h_Mem - Handle to memory segment.
91183 +
91184 + @Return None.
91185 +*//***************************************************************************/
91186 +void MEM_Free(t_Handle h_Mem);
91187 +
91188 +/**************************************************************************//**
91189 + @Function MEM_Get
91190 +
91191 + @Description Get a block of memory from a segment.
91192 +
91193 + @Param[in] h_Mem - Handle to memory segment.
91194 +
91195 + @Return Pointer to new memory block on success,0 otherwise.
91196 +*//***************************************************************************/
91197 +void * MEM_Get(t_Handle h_Mem);
91198 +
91199 +/**************************************************************************//**
91200 + @Function MEM_GetN
91201 +
91202 + @Description Get up to N blocks of memory from a segment.
91203 +
91204 + The blocks are assumed to be of a fixed size (one size per segment).
91205 +
91206 + @Param[in] h_Mem - Handle to memory segment.
91207 + @Param[in] num - Number of blocks to allocate.
91208 + @Param[out] array - Array of at least num pointers to which the addresses
91209 + of the allocated blocks are written.
91210 +
91211 + @Return The number of blocks actually allocated.
91212 +
91213 + @Cautions Interrupts are disabled for all of the allocation loop.
91214 + Although this loop is very short for each block (several machine
91215 + instructions), you should not allocate a very large number
91216 + of blocks via this routine.
91217 +*//***************************************************************************/
91218 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
91219 +
91220 +/**************************************************************************//**
91221 + @Function MEM_Put
91222 +
91223 + @Description Put a block of memory back to a segment.
91224 +
91225 + @Param[in] h_Mem - Handle to memory segment.
91226 + @Param[in] p_Block - The block to return.
91227 +
91228 + @Return Pointer to new memory block on success,0 otherwise.
91229 +*//***************************************************************************/
91230 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
91231 +
91232 +/**************************************************************************//**
91233 + @Function MEM_ComputePartitionSize
91234 +
91235 + @Description calculate a tight upper boundary of the size of a partition with
91236 + given attributes.
91237 +
91238 + The returned value is suitable if one wants to use MEM_InitByAddress().
91239 +
91240 + @Param[in] num - The number of blocks in the segment.
91241 + @Param[in] dataSize - Size of block to get.
91242 + @Param[in] prefixSize - The prefix size
91243 + @Param postfixSize - The postfix size
91244 + @Param[in] alignment - The requested alignment value (in bytes)
91245 +
91246 + @Return The memory block size a segment with the given attributes needs.
91247 +*//***************************************************************************/
91248 +uint32_t MEM_ComputePartitionSize(uint32_t num,
91249 + uint16_t dataSize,
91250 + uint16_t prefixSize,
91251 + uint16_t postfixSize,
91252 + uint16_t alignment);
91253 +
91254 +#ifdef DEBUG_MEM_LEAKS
91255 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
91256 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
91257 +#endif /* !(defined(__MWERKS__) && ... */
91258 +
91259 +/**************************************************************************//**
91260 + @Function MEM_CheckLeaks
91261 +
91262 + @Description Report MEM object leaks.
91263 +
91264 + This routine is automatically called by the MEM_Free() routine,
91265 + but it can also be invoked while the MEM object is alive.
91266 +
91267 + @Param[in] h_Mem - Handle to memory segment.
91268 +
91269 + @Return None.
91270 +*//***************************************************************************/
91271 +void MEM_CheckLeaks(t_Handle h_Mem);
91272 +
91273 +#else /* not DEBUG_MEM_LEAKS */
91274 +#define MEM_CheckLeaks(h_Mem)
91275 +#endif /* not DEBUG_MEM_LEAKS */
91276 +
91277 +/**************************************************************************//**
91278 + @Description Get base of MEM
91279 +*//***************************************************************************/
91280 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
91281 +
91282 +/**************************************************************************//**
91283 + @Description Get size of MEM block
91284 +*//***************************************************************************/
91285 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
91286 +
91287 +/**************************************************************************//**
91288 + @Description Get prefix size of MEM block
91289 +*//***************************************************************************/
91290 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
91291 +
91292 +/**************************************************************************//**
91293 + @Description Get postfix size of MEM block
91294 +*//***************************************************************************/
91295 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
91296 +
91297 +/**************************************************************************//**
91298 + @Description Get alignment of MEM block (in bytes)
91299 +*//***************************************************************************/
91300 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
91301 +
91302 +/**************************************************************************//**
91303 + @Description Get the number of blocks in the segment
91304 +*//***************************************************************************/
91305 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
91306 +
91307 +/** @} */ /* end of MEM group */
91308 +/** @} */ /* end of etc_id group */
91309 +
91310 +
91311 +#endif /* __MEM_EXT_H */
91312 --- /dev/null
91313 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
91314 @@ -0,0 +1,208 @@
91315 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91316 + * All rights reserved.
91317 + *
91318 + * Redistribution and use in source and binary forms, with or without
91319 + * modification, are permitted provided that the following conditions are met:
91320 + * * Redistributions of source code must retain the above copyright
91321 + * notice, this list of conditions and the following disclaimer.
91322 + * * Redistributions in binary form must reproduce the above copyright
91323 + * notice, this list of conditions and the following disclaimer in the
91324 + * documentation and/or other materials provided with the distribution.
91325 + * * Neither the name of Freescale Semiconductor nor the
91326 + * names of its contributors may be used to endorse or promote products
91327 + * derived from this software without specific prior written permission.
91328 + *
91329 + *
91330 + * ALTERNATIVELY, this software may be distributed under the terms of the
91331 + * GNU General Public License ("GPL") as published by the Free Software
91332 + * Foundation, either version 2 of that License or (at your option) any
91333 + * later version.
91334 + *
91335 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91336 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91337 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91338 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91339 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91340 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91341 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91342 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91343 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91344 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91345 + */
91346 +
91347 +
91348 +/**************************************************************************//**
91349 +
91350 + @File memcpy_ext.h
91351 +
91352 + @Description Efficient functions for copying and setting blocks of memory.
91353 +*//***************************************************************************/
91354 +
91355 +#ifndef __MEMCPY_EXT_H
91356 +#define __MEMCPY_EXT_H
91357 +
91358 +#include "std_ext.h"
91359 +
91360 +
91361 +/**************************************************************************//**
91362 + @Group etc_id Utility Library Application Programming Interface
91363 +
91364 + @Description External routines.
91365 +
91366 + @{
91367 +*//***************************************************************************/
91368 +
91369 +/**************************************************************************//**
91370 + @Group mem_cpy Memory Copy
91371 +
91372 + @Description Memory Copy module functions,definitions and enums.
91373 +
91374 + @{
91375 +*//***************************************************************************/
91376 +
91377 +/**************************************************************************//**
91378 + @Function MemCpy32
91379 +
91380 + @Description Copies one memory buffer into another one in 4-byte chunks!
91381 + Which should be more efficient than byte by byte.
91382 +
91383 + For large buffers (over 60 bytes) this function is about 4 times
91384 + more efficient than the trivial memory copy. For short buffers
91385 + it is reduced to the trivial copy and may be a bit worse.
91386 +
91387 + @Param[in] pDst - The address of the destination buffer.
91388 + @Param[in] pSrc - The address of the source buffer.
91389 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91390 +
91391 + @Return pDst (the address of the destination buffer).
91392 +
91393 + @Cautions There is no parameter or boundary checking! It is up to the user
91394 + to supply non-null parameters as source & destination and size
91395 + that actually fits into the destination buffer.
91396 +*//***************************************************************************/
91397 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
91398 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91399 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
91400 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
91401 +
91402 +/**************************************************************************//**
91403 + @Function MemCpy64
91404 +
91405 + @Description Copies one memory buffer into another one in 8-byte chunks!
91406 + Which should be more efficient than byte by byte.
91407 +
91408 + For large buffers (over 60 bytes) this function is about 8 times
91409 + more efficient than the trivial memory copy. For short buffers
91410 + it is reduced to the trivial copy and may be a bit worse.
91411 +
91412 + Some testing suggests that MemCpy32() preforms better than
91413 + MemCpy64() over small buffers. On average they break even at
91414 + 100 byte buffers. For buffers larger than that MemCpy64 is
91415 + superior.
91416 +
91417 + @Param[in] pDst - The address of the destination buffer.
91418 + @Param[in] pSrc - The address of the source buffer.
91419 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91420 +
91421 + @Return pDst (the address of the destination buffer).
91422 +
91423 + @Cautions There is no parameter or boundary checking! It is up to the user
91424 + to supply non null parameters as source & destination and size
91425 + that actually fits into their buffer.
91426 +
91427 + Do not use under Linux.
91428 +*//***************************************************************************/
91429 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
91430 +
91431 +/**************************************************************************//**
91432 + @Function MemSet32
91433 +
91434 + @Description Sets all bytes of a memory buffer to a specific value, in
91435 + 4-byte chunks.
91436 +
91437 + @Param[in] pDst - The address of the destination buffer.
91438 + @Param[in] val - Value to set destination bytes to.
91439 + @Param[in] size - The number of bytes that will be set to val.
91440 +
91441 + @Return pDst (the address of the destination buffer).
91442 +
91443 + @Cautions There is no parameter or boundary checking! It is up to the user
91444 + to supply non null parameter as destination and size
91445 + that actually fits into the destination buffer.
91446 +*//***************************************************************************/
91447 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
91448 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
91449 +
91450 +/**************************************************************************//**
91451 + @Function MemSet64
91452 +
91453 + @Description Sets all bytes of a memory buffer to a specific value, in
91454 + 8-byte chunks.
91455 +
91456 + @Param[in] pDst - The address of the destination buffer.
91457 + @Param[in] val - Value to set destination bytes to.
91458 + @Param[in] size - The number of bytes that will be set to val.
91459 +
91460 + @Return pDst (the address of the destination buffer).
91461 +
91462 + @Cautions There is no parameter or boundary checking! It is up to the user
91463 + to supply non null parameter as destination and size
91464 + that actually fits into the destination buffer.
91465 +*//***************************************************************************/
91466 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
91467 +
91468 +/**************************************************************************//**
91469 + @Function MemDisp
91470 +
91471 + @Description Displays a block of memory in chunks of 32 bits.
91472 +
91473 + @Param[in] addr - The address of the memory to display.
91474 + @Param[in] size - The number of bytes that will be displayed.
91475 +
91476 + @Return None.
91477 +
91478 + @Cautions There is no parameter or boundary checking! It is up to the user
91479 + to supply non null parameter as destination and size
91480 + that actually fits into the destination buffer.
91481 +*//***************************************************************************/
91482 +void MemDisp(uint8_t *addr, int size);
91483 +
91484 +/**************************************************************************//**
91485 + @Function MemCpy8
91486 +
91487 + @Description Trivial copy one memory buffer into another byte by byte
91488 +
91489 + @Param[in] pDst - The address of the destination buffer.
91490 + @Param[in] pSrc - The address of the source buffer.
91491 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
91492 +
91493 + @Return pDst (the address of the destination buffer).
91494 +
91495 + @Cautions There is no parameter or boundary checking! It is up to the user
91496 + to supply non-null parameters as source & destination and size
91497 + that actually fits into the destination buffer.
91498 +*//***************************************************************************/
91499 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
91500 +
91501 +/**************************************************************************//**
91502 + @Function MemSet8
91503 +
91504 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
91505 +
91506 + @Param[in] pDst - The address of the destination buffer.
91507 + @Param[in] c - Value to set destination bytes to.
91508 + @Param[in] size - The number of bytes that will be set to val.
91509 +
91510 + @Return pDst (the address of the destination buffer).
91511 +
91512 + @Cautions There is no parameter or boundary checking! It is up to the user
91513 + to supply non null parameter as destination and size
91514 + that actually fits into the destination buffer.
91515 +*//***************************************************************************/
91516 +void * MemSet8(void* pDst, int c, uint32_t size);
91517 +
91518 +/** @} */ /* end of mem_cpy group */
91519 +/** @} */ /* end of etc_id group */
91520 +
91521 +
91522 +#endif /* __MEMCPY_EXT_H */
91523 --- /dev/null
91524 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
91525 @@ -0,0 +1,310 @@
91526 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91527 + * All rights reserved.
91528 + *
91529 + * Redistribution and use in source and binary forms, with or without
91530 + * modification, are permitted provided that the following conditions are met:
91531 + * * Redistributions of source code must retain the above copyright
91532 + * notice, this list of conditions and the following disclaimer.
91533 + * * Redistributions in binary form must reproduce the above copyright
91534 + * notice, this list of conditions and the following disclaimer in the
91535 + * documentation and/or other materials provided with the distribution.
91536 + * * Neither the name of Freescale Semiconductor nor the
91537 + * names of its contributors may be used to endorse or promote products
91538 + * derived from this software without specific prior written permission.
91539 + *
91540 + *
91541 + * ALTERNATIVELY, this software may be distributed under the terms of the
91542 + * GNU General Public License ("GPL") as published by the Free Software
91543 + * Foundation, either version 2 of that License or (at your option) any
91544 + * later version.
91545 + *
91546 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91547 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91548 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91549 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91550 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91551 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91552 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91553 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91554 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91555 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91556 + */
91557 +
91558 +
91559 +/**************************************************************************//**
91560 + @File mm_ext.h
91561 +
91562 + @Description Memory Manager Application Programming Interface
91563 +*//***************************************************************************/
91564 +#ifndef __MM_EXT
91565 +#define __MM_EXT
91566 +
91567 +#include "std_ext.h"
91568 +
91569 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
91570 + where maximum alignment defined as
91571 + MM_MAX_ALIGNMENT power of 2 */
91572 +
91573 +#define MM_MAX_NAME_LEN 32
91574 +
91575 +/**************************************************************************//**
91576 + @Group etc_id Utility Library Application Programming Interface
91577 +
91578 + @Description External routines.
91579 +
91580 + @{
91581 +*//***************************************************************************/
91582 +
91583 +/**************************************************************************//**
91584 + @Group mm_grp Flexible Memory Manager
91585 +
91586 + @Description Flexible Memory Manager module functions,definitions and enums.
91587 + (All of the following functions,definitions and enums can be found in mm_ext.h)
91588 +
91589 + @{
91590 +*//***************************************************************************/
91591 +
91592 +
91593 +/**************************************************************************//**
91594 + @Function MM_Init
91595 +
91596 + @Description Initializes a new MM object.
91597 +
91598 + It initializes a new memory block consisting of base address
91599 + and size of the available memory by calling to MemBlock_Init
91600 + routine. It is also initializes a new free block for each
91601 + by calling FreeBlock_Init routine, which is pointed to
91602 + the almost all memory started from the required alignment
91603 + from the base address and to the end of the memory.
91604 + The handle to the new MM object is returned via "MM"
91605 + argument (passed by reference).
91606 +
91607 + @Param[in] h_MM - Handle to the MM object.
91608 + @Param[in] base - Base address of the MM.
91609 + @Param[in] size - Size of the MM.
91610 +
91611 + @Return E_OK is returned on success. E_NOMEMORY is returned if the new MM object or a new free block can not be initialized.
91612 +*//***************************************************************************/
91613 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
91614 +
91615 +/**************************************************************************//**
91616 + @Function MM_Get
91617 +
91618 + @Description Allocates a block of memory according to the given size and the alignment.
91619 +
91620 + The Alignment argument tells from which
91621 + free list allocate a block of memory. 2^alignment indicates
91622 + the alignment that the base address of the allocated block
91623 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91624 + are available for the alignment argument.
91625 + The routine passes through the specific free list of free
91626 + blocks and seeks for a first block that have anough memory
91627 + that is required (best fit).
91628 + After the block is found and data is allocated, it calls
91629 + the internal MM_CutFree routine to update all free lists
91630 + do not include a just allocated block. Of course, each
91631 + free list contains a free blocks with the same alignment.
91632 + It is also creates a busy block that holds
91633 + information about an allocated block.
91634 +
91635 + @Param[in] h_MM - Handle to the MM object.
91636 + @Param[in] size - Size of the MM.
91637 + @Param[in] alignment - Index as a power of two defines a required
91638 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91639 + @Param[in] name - The name that specifies an allocated block.
91640 +
91641 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
91642 +*//***************************************************************************/
91643 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
91644 +
91645 +/**************************************************************************//**
91646 + @Function MM_GetBase
91647 +
91648 + @Description Gets the base address of the required MM objects.
91649 +
91650 + @Param[in] h_MM - Handle to the MM object.
91651 +
91652 + @Return base address of the block.
91653 +*//***************************************************************************/
91654 +uint64_t MM_GetBase(t_Handle h_MM);
91655 +
91656 +/**************************************************************************//**
91657 + @Function MM_GetForce
91658 +
91659 + @Description Force memory allocation.
91660 +
91661 + It means to allocate a block of memory of the given
91662 + size from the given base address.
91663 + The routine checks if the required block can be allocated
91664 + (that is it is free) and then, calls the internal MM_CutFree
91665 + routine to update all free lists do not include that block.
91666 +
91667 + @Param[in] h_MM - Handle to the MM object.
91668 + @Param[in] base - Base address of the MM.
91669 + @Param[in] size - Size of the MM.
91670 + @Param[in] name - Name that specifies an allocated block.
91671 +
91672 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
91673 +*//***************************************************************************/
91674 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
91675 +
91676 +/**************************************************************************//**
91677 + @Function MM_GetForceMin
91678 +
91679 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
91680 +
91681 + The Alignment argument tells from which
91682 + free list allocate a block of memory. 2^alignment indicates
91683 + the alignment that the base address of the allocated block
91684 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
91685 + are available for the alignment argument.
91686 + The minimum baser address forces the location of the block
91687 + to be from a given address onward.
91688 + The routine passes through the specific free list of free
91689 + blocks and seeks for the first base address equal or smaller
91690 + than the required minimum address and end address larger than
91691 + than the required base + its size - i.e. that may contain
91692 + the required block.
91693 + After the block is found and data is allocated, it calls
91694 + the internal MM_CutFree routine to update all free lists
91695 + do not include a just allocated block. Of course, each
91696 + free list contains a free blocks with the same alignment.
91697 + It is also creates a busy block that holds
91698 + information about an allocated block.
91699 +
91700 + @Param[in] h_MM - Handle to the MM object.
91701 + @Param[in] size - Size of the MM.
91702 + @Param[in] alignment - Index as a power of two defines a required
91703 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
91704 + @Param[in] min - The minimum base address of the block.
91705 + @Param[in] name - Name that specifies an allocated block.
91706 +
91707 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
91708 +*//***************************************************************************/
91709 +uint64_t MM_GetForceMin(t_Handle h_MM,
91710 + uint64_t size,
91711 + uint64_t alignment,
91712 + uint64_t min,
91713 + char *name);
91714 +
91715 +/**************************************************************************//**
91716 + @Function MM_Put
91717 +
91718 + @Description Puts a block of memory of the given base address back to the memory.
91719 +
91720 + It checks if there is a busy block with the
91721 + given base address. If not, it returns 0, that
91722 + means can't free a block. Otherwise, it gets parameters of
91723 + the busy block and after it updates lists of free blocks,
91724 + removes that busy block from the list by calling to MM_CutBusy
91725 + routine.
91726 + After that it calls to MM_AddFree routine to add a new free
91727 + block to the free lists.
91728 +
91729 + @Param[in] h_MM - Handle to the MM object.
91730 + @Param[in] base - Base address of the MM.
91731 +
91732 + @Return The size of bytes released, 0 if failed.
91733 +*//***************************************************************************/
91734 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
91735 +
91736 +/**************************************************************************//**
91737 + @Function MM_PutForce
91738 +
91739 + @Description Releases a block of memory of the required size from the required base address.
91740 +
91741 + First, it calls to MM_CutBusy routine
91742 + to cut a free block from the busy list. And then, calls to
91743 + MM_AddFree routine to add the free block to the free lists.
91744 +
91745 + @Param[in] h_MM - Handle to the MM object.
91746 + @Param[in] base - Base address of of a block to free.
91747 + @Param[in] size - Size of a block to free.
91748 +
91749 + @Return The number of bytes released, 0 on failure.
91750 +*//***************************************************************************/
91751 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
91752 +
91753 +/**************************************************************************//**
91754 + @Function MM_Add
91755 +
91756 + @Description Adds a new memory block for memory allocation.
91757 +
91758 + When a new memory block is initialized and added to the
91759 + memory list, it calls to MM_AddFree routine to add the
91760 + new free block to the free lists.
91761 +
91762 + @Param[in] h_MM - Handle to the MM object.
91763 + @Param[in] base - Base address of the memory block.
91764 + @Param[in] size - Size of the memory block.
91765 +
91766 + @Return E_OK on success, otherwise returns an error code.
91767 +*//***************************************************************************/
91768 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
91769 +
91770 +/**************************************************************************//**
91771 + @Function MM_Dump
91772 +
91773 + @Description Prints results of free and busy lists.
91774 +
91775 + @Param[in] h_MM - Handle to the MM object.
91776 +*//***************************************************************************/
91777 +void MM_Dump(t_Handle h_MM);
91778 +
91779 +/**************************************************************************//**
91780 + @Function MM_Free
91781 +
91782 + @Description Releases memory allocated for MM object.
91783 +
91784 + @Param[in] h_MM - Handle of the MM object.
91785 +*//***************************************************************************/
91786 +void MM_Free(t_Handle h_MM);
91787 +
91788 +/**************************************************************************//**
91789 + @Function MM_GetMemBlock
91790 +
91791 + @Description Returns base address of the memory block specified by the index.
91792 +
91793 + If index is 0, returns base address
91794 + of the first memory block, 1 - returns base address
91795 + of the second memory block, etc.
91796 + Note, those memory blocks are allocated by the
91797 + application before MM_Init or MM_Add and have to
91798 + be released by the application before or after invoking
91799 + the MM_Free routine.
91800 +
91801 + @Param[in] h_MM - Handle to the MM object.
91802 + @Param[in] index - Index of the memory block.
91803 +
91804 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
91805 +*//***************************************************************************/
91806 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
91807 +
91808 +/**************************************************************************//**
91809 + @Function MM_InRange
91810 +
91811 + @Description Checks if a specific address is in the memory range of the passed MM object.
91812 +
91813 + @Param[in] h_MM - Handle to the MM object.
91814 + @Param[in] addr - The address to be checked.
91815 +
91816 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
91817 +*//***************************************************************************/
91818 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
91819 +
91820 +/**************************************************************************//**
91821 + @Function MM_GetFreeMemSize
91822 +
91823 + @Description Returns the size (in bytes) of free memory.
91824 +
91825 + @Param[in] h_MM - Handle to the MM object.
91826 +
91827 + @Return Free memory size in bytes.
91828 +*//***************************************************************************/
91829 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
91830 +
91831 +
91832 +/** @} */ /* end of mm_grp group */
91833 +/** @} */ /* end of etc_id group */
91834 +
91835 +#endif /* __MM_EXT_H */
91836 --- /dev/null
91837 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
91838 @@ -0,0 +1,118 @@
91839 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91840 + * All rights reserved.
91841 + *
91842 + * Redistribution and use in source and binary forms, with or without
91843 + * modification, are permitted provided that the following conditions are met:
91844 + * * Redistributions of source code must retain the above copyright
91845 + * notice, this list of conditions and the following disclaimer.
91846 + * * Redistributions in binary form must reproduce the above copyright
91847 + * notice, this list of conditions and the following disclaimer in the
91848 + * documentation and/or other materials provided with the distribution.
91849 + * * Neither the name of Freescale Semiconductor nor the
91850 + * names of its contributors may be used to endorse or promote products
91851 + * derived from this software without specific prior written permission.
91852 + *
91853 + *
91854 + * ALTERNATIVELY, this software may be distributed under the terms of the
91855 + * GNU General Public License ("GPL") as published by the Free Software
91856 + * Foundation, either version 2 of that License or (at your option) any
91857 + * later version.
91858 + *
91859 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91860 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91861 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91862 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91863 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91864 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91865 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91866 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91867 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91868 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91869 + */
91870 +
91871 +
91872 +/**************************************************************************//**
91873 + @File sprint_ext.h
91874 +
91875 + @Description Debug routines (externals).
91876 +
91877 +*//***************************************************************************/
91878 +
91879 +#ifndef __SPRINT_EXT_H
91880 +#define __SPRINT_EXT_H
91881 +
91882 +
91883 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
91884 +#include <linux/kernel.h>
91885 +
91886 +#elif defined(NCSW_VXWORKS)
91887 +#include "private/stdioP.h"
91888 +
91889 +#else
91890 +#include <stdio.h>
91891 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
91892 +
91893 +#include "std_ext.h"
91894 +
91895 +
91896 +/**************************************************************************//**
91897 + @Group etc_id Utility Library Application Programming Interface
91898 +
91899 + @Description External routines.
91900 +
91901 + @{
91902 +*//***************************************************************************/
91903 +
91904 +/**************************************************************************//**
91905 + @Group sprint_id Sprint
91906 +
91907 + @Description Sprint & Sscan module functions,definitions and enums.
91908 +
91909 + @{
91910 +*//***************************************************************************/
91911 +
91912 +/**************************************************************************//**
91913 + @Function Sprint
91914 +
91915 + @Description Format a string and place it in a buffer.
91916 +
91917 + @Param[in] buff - The buffer to place the result into.
91918 + @Param[in] str - The format string to use.
91919 + @Param[in] ... - Arguments for the format string.
91920 +
91921 + @Return Number of bytes formatted.
91922 +*//***************************************************************************/
91923 +int Sprint(char *buff, const char *str, ...);
91924 +
91925 +/**************************************************************************//**
91926 + @Function Snprint
91927 +
91928 + @Description Format a string and place it in a buffer.
91929 +
91930 + @Param[in] buf - The buffer to place the result into.
91931 + @Param[in] size - The size of the buffer, including the trailing null space.
91932 + @Param[in] fmt - The format string to use.
91933 + @Param[in] ... - Arguments for the format string.
91934 +
91935 + @Return Number of bytes formatted.
91936 +*//***************************************************************************/
91937 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
91938 +
91939 +/**************************************************************************//**
91940 + @Function Sscan
91941 +
91942 + @Description Unformat a buffer into a list of arguments.
91943 +
91944 + @Param[in] buf - input buffer.
91945 + @Param[in] fmt - formatting of buffer.
91946 + @Param[out] ... - resulting arguments.
91947 +
91948 + @Return Number of bytes unformatted.
91949 +*//***************************************************************************/
91950 +int Sscan(const char * buf, const char * fmt, ...);
91951 +
91952 +/** @} */ /* end of sprint_id group */
91953 +/** @} */ /* end of etc_id group */
91954 +
91955 +
91956 +#endif /* __SPRINT_EXT_H */
91957 --- /dev/null
91958 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
91959 @@ -0,0 +1,37 @@
91960 +/*
91961 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91962 + *
91963 + * Redistribution and use in source and binary forms, with or without
91964 + * modification, are permitted provided that the following conditions are met:
91965 + * * Redistributions of source code must retain the above copyright
91966 + * notice, this list of conditions and the following disclaimer.
91967 + * * Redistributions in binary form must reproduce the above copyright
91968 + * notice, this list of conditions and the following disclaimer in the
91969 + * documentation and/or other materials provided with the distribution.
91970 + * * Neither the name of Freescale Semiconductor nor the
91971 + * names of its contributors may be used to endorse or promote products
91972 + * derived from this software without specific prior written permission.
91973 + *
91974 + *
91975 + * ALTERNATIVELY, this software may be distributed under the terms of the
91976 + * GNU General Public License ("GPL") as published by the Free Software
91977 + * Foundation, either version 2 of that License or (at your option) any
91978 + * later version.
91979 + *
91980 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91981 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91982 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91983 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91984 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91985 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91986 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91987 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91988 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91989 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91990 + */
91991 +
91992 +#ifndef FL_E500_MACROS_H
91993 +#define FL_E500_MACROS_H
91994 +
91995 +#endif /* FL_E500_MACROS_H */
91996 +
91997 --- /dev/null
91998 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
91999 @@ -0,0 +1,52 @@
92000 +/*
92001 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92002 + *
92003 + * Redistribution and use in source and binary forms, with or without
92004 + * modification, are permitted provided that the following conditions are met:
92005 + * * Redistributions of source code must retain the above copyright
92006 + * notice, this list of conditions and the following disclaimer.
92007 + * * Redistributions in binary form must reproduce the above copyright
92008 + * notice, this list of conditions and the following disclaimer in the
92009 + * documentation and/or other materials provided with the distribution.
92010 + * * Neither the name of Freescale Semiconductor nor the
92011 + * names of its contributors may be used to endorse or promote products
92012 + * derived from this software without specific prior written permission.
92013 + *
92014 + *
92015 + * ALTERNATIVELY, this software may be distributed under the terms of the
92016 + * GNU General Public License ("GPL") as published by the Free Software
92017 + * Foundation, either version 2 of that License or (at your option) any
92018 + * later version.
92019 + *
92020 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92021 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92022 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92023 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92024 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92025 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92026 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92027 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92028 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92029 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92030 + */
92031 +
92032 +#ifndef __GENERAL_H
92033 +#define __GENERAL_H
92034 +
92035 +#include "std_ext.h"
92036 +#if !defined(NCSW_LINUX)
92037 +#include "errno.h"
92038 +#endif
92039 +
92040 +
92041 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
92042 +
92043 +#ifndef CONFIG_FMAN_ARM
92044 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
92045 +#define ioread32be(addr) GET_UINT32(*addr)
92046 +#endif
92047 +
92048 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
92049 +
92050 +
92051 +#endif /* __GENERAL_H */
92052 --- /dev/null
92053 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
92054 @@ -0,0 +1,78 @@
92055 +/*
92056 + * Copyright 2008-2013 Freescale Semiconductor Inc.
92057 + *
92058 + * Redistribution and use in source and binary forms, with or without
92059 + * modification, are permitted provided that the following conditions are met:
92060 + * * Redistributions of source code must retain the above copyright
92061 + * notice, this list of conditions and the following disclaimer.
92062 + * * Redistributions in binary form must reproduce the above copyright
92063 + * notice, this list of conditions and the following disclaimer in the
92064 + * documentation and/or other materials provided with the distribution.
92065 + * * Neither the name of Freescale Semiconductor nor the
92066 + * names of its contributors may be used to endorse or promote products
92067 + * derived from this software without specific prior written permission.
92068 + *
92069 + *
92070 + * ALTERNATIVELY, this software may be distributed under the terms of the
92071 + * GNU General Public License ("GPL") as published by the Free Software
92072 + * Foundation, either version 2 of that License or (at your option) any
92073 + * later version.
92074 + *
92075 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92076 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92077 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92078 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92079 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92080 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92081 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92082 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92083 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92084 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92085 + */
92086 +
92087 +
92088 +#ifndef __FMAN_COMMON_H
92089 +#define __FMAN_COMMON_H
92090 +
92091 +/**************************************************************************//**
92092 + @Description NIA Description
92093 +*//***************************************************************************/
92094 +#define NIA_ORDER_RESTOR 0x00800000
92095 +#define NIA_ENG_FM_CTL 0x00000000
92096 +#define NIA_ENG_PRS 0x00440000
92097 +#define NIA_ENG_KG 0x00480000
92098 +#define NIA_ENG_PLCR 0x004C0000
92099 +#define NIA_ENG_BMI 0x00500000
92100 +#define NIA_ENG_QMI_ENQ 0x00540000
92101 +#define NIA_ENG_QMI_DEQ 0x00580000
92102 +#define NIA_ENG_MASK 0x007C0000
92103 +
92104 +#define NIA_FM_CTL_AC_CC 0x00000006
92105 +#define NIA_FM_CTL_AC_HC 0x0000000C
92106 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
92107 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
92108 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
92109 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
92110 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
92111 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
92112 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
92113 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
92114 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
92115 +
92116 +
92117 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
92118 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
92119 +#define NIA_BMI_AC_RELEASE 0x000000C0
92120 +#define NIA_BMI_AC_DISCARD 0x000000C1
92121 +#define NIA_BMI_AC_TX 0x00000274
92122 +#define NIA_BMI_AC_FETCH 0x00000208
92123 +#define NIA_BMI_AC_MASK 0x000003FF
92124 +
92125 +#define NIA_KG_DIRECT 0x00000100
92126 +#define NIA_KG_CC_EN 0x00000200
92127 +#define NIA_PLCR_ABSOLUTE 0x00008000
92128 +
92129 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
92130 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
92131 +
92132 +#endif /* __FMAN_COMMON_H */
92133 --- /dev/null
92134 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
92135 @@ -0,0 +1,273 @@
92136 +/*
92137 + * Copyright 2008-2012 Freescale Semiconductor Inc.
92138 + *
92139 + * Redistribution and use in source and binary forms, with or without
92140 + * modification, are permitted provided that the following conditions are met:
92141 + * * Redistributions of source code must retain the above copyright
92142 + * notice, this list of conditions and the following disclaimer.
92143 + * * Redistributions in binary form must reproduce the above copyright
92144 + * notice, this list of conditions and the following disclaimer in the
92145 + * documentation and/or other materials provided with the distribution.
92146 + * * Neither the name of Freescale Semiconductor nor the
92147 + * names of its contributors may be used to endorse or promote products
92148 + * derived from this software without specific prior written permission.
92149 + *
92150 + *
92151 + * ALTERNATIVELY, this software may be distributed under the terms of the
92152 + * GNU General Public License ("GPL") as published by the Free Software
92153 + * Foundation, either version 2 of that License or (at your option) any
92154 + * later version.
92155 + *
92156 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92157 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92158 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92159 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92160 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92161 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92162 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92163 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92164 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92165 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92166 + */
92167 +
92168 +#ifndef __FSL_ENET_H
92169 +#define __FSL_ENET_H
92170 +
92171 +/**
92172 + @Description Ethernet MAC-PHY Interface
92173 +*/
92174 +
92175 +enum enet_interface {
92176 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
92177 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
92178 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
92179 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
92180 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
92181 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
92182 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
92183 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
92184 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
92185 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
92186 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
92187 +};
92188 +
92189 +/**
92190 + @Description Ethernet Speed (nominal data rate)
92191 +*/
92192 +enum enet_speed {
92193 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
92194 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
92195 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
92196 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
92197 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
92198 +};
92199 +
92200 +enum mac_type {
92201 + E_MAC_DTSEC,
92202 + E_MAC_TGEC,
92203 + E_MAC_MEMAC
92204 +};
92205 +
92206 +/**************************************************************************//**
92207 + @Description Enum for inter-module interrupts registration
92208 +*//***************************************************************************/
92209 +enum fman_event_modules {
92210 + E_FMAN_MOD_PRS, /**< Parser event */
92211 + E_FMAN_MOD_KG, /**< Keygen event */
92212 + E_FMAN_MOD_PLCR, /**< Policer event */
92213 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
92214 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
92215 + E_FMAN_MOD_TMR, /**< Timer event */
92216 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
92217 + E_FMAN_MOD_MACSEC,
92218 + E_FMAN_MOD_DUMMY_LAST
92219 +};
92220 +
92221 +/**************************************************************************//**
92222 + @Description Enum for interrupts types
92223 +*//***************************************************************************/
92224 +enum fman_intr_type {
92225 + E_FMAN_INTR_TYPE_ERR,
92226 + E_FMAN_INTR_TYPE_NORMAL
92227 +};
92228 +
92229 +/**************************************************************************//**
92230 + @Description enum for defining MAC types
92231 +*//***************************************************************************/
92232 +enum fman_mac_type {
92233 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
92234 + E_FMAN_MAC_1G /**< 1G MAC */
92235 +};
92236 +
92237 +enum fman_mac_exceptions {
92238 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
92239 + /**< 10GEC MDIO scan event interrupt */
92240 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
92241 + /**< 10GEC MDIO command completion interrupt */
92242 + E_FMAN_MAC_EX_10G_REM_FAULT,
92243 + /**< 10GEC, mEMAC Remote fault interrupt */
92244 + E_FMAN_MAC_EX_10G_LOC_FAULT,
92245 + /**< 10GEC, mEMAC Local fault interrupt */
92246 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
92247 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
92248 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
92249 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
92250 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
92251 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
92252 + E_FMAN_MAC_EX_10G_TX_ER,
92253 + /**< 10GEC Transmit frame error interrupt */
92254 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
92255 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
92256 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
92257 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
92258 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
92259 + /**< 10GEC Receive jabber frame interrupt */
92260 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
92261 + /**< 10GEC Receive oversized frame interrupt */
92262 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
92263 + /**< 10GEC Receive runt frame interrupt */
92264 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
92265 + /**< 10GEC Receive fragment frame interrupt */
92266 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
92267 + /**< 10GEC Receive payload length error interrupt */
92268 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
92269 + /**< 10GEC Receive CRC error interrupt */
92270 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
92271 + /**< 10GEC Receive alignment error interrupt */
92272 + E_FMAN_MAC_EX_1G_BAB_RX,
92273 + /**< dTSEC Babbling receive error */
92274 + E_FMAN_MAC_EX_1G_RX_CTL,
92275 + /**< dTSEC Receive control (pause frame) interrupt */
92276 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
92277 + /**< dTSEC Graceful transmit stop complete */
92278 + E_FMAN_MAC_EX_1G_BAB_TX,
92279 + /**< dTSEC Babbling transmit error */
92280 + E_FMAN_MAC_EX_1G_TX_CTL,
92281 + /**< dTSEC Transmit control (pause frame) interrupt */
92282 + E_FMAN_MAC_EX_1G_TX_ERR,
92283 + /**< dTSEC Transmit error */
92284 + E_FMAN_MAC_EX_1G_LATE_COL,
92285 + /**< dTSEC Late collision */
92286 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
92287 + /**< dTSEC Collision retry limit */
92288 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
92289 + /**< dTSEC Transmit FIFO underrun */
92290 + E_FMAN_MAC_EX_1G_MAG_PCKT,
92291 + /**< dTSEC Magic Packet detection */
92292 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
92293 + /**< dTSEC MII management read completion */
92294 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
92295 + /**< dTSEC MII management write completion */
92296 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
92297 + /**< dTSEC Graceful receive stop complete */
92298 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
92299 + /**< dTSEC Internal data error on transmit */
92300 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
92301 + /**< dTSEC Internal data error on receive */
92302 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
92303 + /**< dTSEC Time-Stamp Receive Error */
92304 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
92305 + /**< dTSEC MIB counter overflow */
92306 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
92307 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
92308 + not supported on T4240/B4860 rev1 chips */
92309 +};
92310 +
92311 +#define ENET_IF_SGMII_BASEX 0x80000000
92312 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
92313 + and phy or backplane;
92314 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
92315 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
92316 + 10Mbps, 100Mbps or 1000Mbps */
92317 +
92318 +enum enet_mode {
92319 + E_ENET_MODE_INVALID = 0,
92320 + /**< Invalid Ethernet mode */
92321 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
92322 + /**< 10 Mbps MII */
92323 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
92324 + /**< 100 Mbps MII */
92325 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
92326 + /**< 10 Mbps RMII */
92327 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
92328 + /**< 100 Mbps RMII */
92329 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
92330 + /**< 10 Mbps SMII */
92331 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
92332 + /**< 100 Mbps SMII */
92333 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
92334 + /**< 1000 Mbps GMII */
92335 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
92336 + /**< 10 Mbps RGMII */
92337 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
92338 + /**< 100 Mbps RGMII */
92339 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
92340 + /**< 1000 Mbps RGMII */
92341 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
92342 + /**< 1000 Mbps TBI */
92343 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
92344 + /**< 1000 Mbps RTBI */
92345 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
92346 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
92347 + SGMII phy according to Cisco SGMII specification */
92348 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
92349 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
92350 + SGMII phy according to Cisco SGMII specification */
92351 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
92352 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
92353 + SGMII phy according to Cisco SGMII specification */
92354 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92355 + | E_ENET_SPEED_10),
92356 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
92357 + MAC and SGMII phy or backplane */
92358 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92359 + | E_ENET_SPEED_100),
92360 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
92361 + MAC and SGMII phy or backplane */
92362 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
92363 + | E_ENET_SPEED_1000),
92364 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
92365 + MAC and SGMII phy or backplane */
92366 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
92367 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
92368 + QSGMII phy according to Cisco QSGMII specification */
92369 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
92370 + | E_ENET_SPEED_1000),
92371 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
92372 + MAC and QSGMII phy or backplane */
92373 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
92374 + /**< 10000 Mbps XGMII */
92375 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
92376 + /**< 10000 Mbps XFI */
92377 +};
92378 +
92379 +enum fmam_mac_statistics_level {
92380 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
92381 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
92382 + Optimized for performance */
92383 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
92384 + optimized for performance */
92385 +};
92386 +
92387 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
92388 + | (_speed))
92389 +
92390 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
92391 + ((mode) & 0x0FFF0000)
92392 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
92393 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
92394 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
92395 + ((uint64_t)(_enet_addr)[1] << 32) | \
92396 + ((uint64_t)(_enet_addr)[2] << 24) | \
92397 + ((uint64_t)(_enet_addr)[3] << 16) | \
92398 + ((uint64_t)(_enet_addr)[4] << 8) | \
92399 + ((uint64_t)(_enet_addr)[5]))
92400 +
92401 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
92402 + do { \
92403 + int i; \
92404 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
92405 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
92406 + } while (0)
92407 +
92408 +#endif /* __FSL_ENET_H */
92409 --- /dev/null
92410 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
92411 @@ -0,0 +1,825 @@
92412 +/*
92413 + * Copyright 2013 Freescale Semiconductor Inc.
92414 + *
92415 + * Redistribution and use in source and binary forms, with or without
92416 + * modification, are permitted provided that the following conditions are met:
92417 + * * Redistributions of source code must retain the above copyright
92418 + * notice, this list of conditions and the following disclaimer.
92419 + * * Redistributions in binary form must reproduce the above copyright
92420 + * notice, this list of conditions and the following disclaimer in the
92421 + * documentation and/or other materials provided with the distribution.
92422 + * * Neither the name of Freescale Semiconductor nor the
92423 + * names of its contributors may be used to endorse or promote products
92424 + * derived from this software without specific prior written permission.
92425 + *
92426 + *
92427 + * ALTERNATIVELY, this software may be distributed under the terms of the
92428 + * GNU General Public License ("GPL") as published by the Free Software
92429 + * Foundation, either version 2 of that License or (at your option) any
92430 + * later version.
92431 + *
92432 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92433 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92434 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92435 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92436 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92437 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92438 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92439 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92440 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92441 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92442 + */
92443 +
92444 +#ifndef __FSL_FMAN_H
92445 +#define __FSL_FMAN_H
92446 +
92447 +#include "common/general.h"
92448 +
92449 +struct fman_ext_pool_params {
92450 + uint8_t id; /**< External buffer pool id */
92451 + uint16_t size; /**< External buffer pool buffer size */
92452 +};
92453 +
92454 +struct fman_ext_pools {
92455 + uint8_t num_pools_used; /**< Number of pools use by this port */
92456 + struct fman_ext_pool_params *ext_buf_pool;
92457 + /**< Parameters for each port */
92458 +};
92459 +
92460 +struct fman_backup_bm_pools {
92461 + uint8_t num_backup_pools; /**< Number of BM backup pools -
92462 + must be smaller than the total number
92463 + of pools defined for the specified
92464 + port.*/
92465 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
92466 + specifying which pools should be used
92467 + only as backup. Pool id's specified
92468 + here must be a subset of the pools
92469 + used by the specified port.*/
92470 +};
92471 +
92472 +/**************************************************************************//**
92473 + @Description A structure for defining BM pool depletion criteria
92474 +*//***************************************************************************/
92475 +struct fman_buf_pool_depletion {
92476 + bool buf_pool_depletion_enabled;
92477 + bool pools_grp_mode_enable; /**< select mode in which pause frames
92478 + will be sent after a number of pools
92479 + (all together!) are depleted */
92480 + uint8_t num_pools; /**< the number of depleted pools that
92481 + will invoke pause frames transmission.
92482 + */
92483 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
92484 + considered for depletion (Note - this
92485 + pool must be used by this port!). */
92486 + bool single_pool_mode_enable; /**< select mode in which pause frames
92487 + will be sent after a single-pool
92488 + is depleted; */
92489 + bool *pools_to_consider_for_single_mode;
92490 + /**< For each pool, TRUE if it should be
92491 + considered for depletion (Note - this
92492 + pool must be used by this port!) */
92493 + bool has_pfc_priorities;
92494 + bool *pfc_priorities_en; /**< This field is used by the MAC as
92495 + the Priority Enable Vector in the PFC
92496 + frame which is transmitted */
92497 +};
92498 +
92499 +/**************************************************************************//**
92500 + @Description Enum for defining port DMA swap mode
92501 +*//***************************************************************************/
92502 +enum fman_dma_swap_option {
92503 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
92504 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
92505 + in PowerPc Little Endian mode. */
92506 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
92507 + in Big Endian mode */
92508 +};
92509 +
92510 +/**************************************************************************//**
92511 + @Description Enum for defining port DMA cache attributes
92512 +*//***************************************************************************/
92513 +enum fman_dma_cache_option {
92514 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
92515 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
92516 +};
92517 +
92518 +typedef struct t_FmPrsResult fm_prs_result_t;
92519 +typedef enum e_EnetMode enet_mode_t;
92520 +typedef t_Handle handle_t;
92521 +
92522 +struct fman_revision_info {
92523 + uint8_t majorRev; /**< Major revision */
92524 + uint8_t minorRev; /**< Minor revision */
92525 +};
92526 +
92527 +/* sizes */
92528 +#define CAPWAP_FRAG_EXTRA_SPACE 32
92529 +#define OFFSET_UNITS 16
92530 +#define MAX_INT_OFFSET 240
92531 +#define MAX_IC_SIZE 256
92532 +#define MAX_EXT_OFFSET 496
92533 +#define MAX_EXT_BUFFER_OFFSET 511
92534 +
92535 +/**************************************************************************
92536 + @Description Memory Mapped Registers
92537 +***************************************************************************/
92538 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
92539 +
92540 +struct fman_fpm_regs {
92541 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
92542 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
92543 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
92544 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
92545 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
92546 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
92547 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
92548 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
92549 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
92550 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
92551 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
92552 + uint32_t res0050[4]; /**< res 0x50-0x5f */
92553 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
92554 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
92555 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
92556 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
92557 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
92558 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
92559 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
92560 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
92561 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
92562 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
92563 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
92564 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
92565 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
92566 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
92567 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
92568 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
92569 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
92570 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
92571 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
92572 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
92573 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
92574 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
92575 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
92576 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
92577 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
92578 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
92579 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
92580 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
92581 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
92582 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
92583 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
92584 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
92585 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
92586 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
92587 + uint32_t res0600[0x400 - 384];
92588 +};
92589 +
92590 +struct fman_bmi_regs {
92591 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
92592 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
92593 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
92594 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
92595 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
92596 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
92597 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
92598 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
92599 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
92600 + uint32_t res0060[12]; /**<0x60 - 0x8f */
92601 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
92602 + uint32_t res009c; /**< 0x9c */
92603 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
92604 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
92605 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
92606 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
92607 + uint32_t res0200; /**< 0x200 */
92608 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
92609 + uint32_t res0300; /**< 0x300 */
92610 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
92611 +};
92612 +
92613 +struct fman_qmi_regs {
92614 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
92615 + uint32_t res0004; /**< 0x04 */
92616 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
92617 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
92618 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
92619 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
92620 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
92621 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
92622 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
92623 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
92624 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
92625 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
92626 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
92627 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
92628 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
92629 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
92630 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
92631 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
92632 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
92633 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
92634 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
92635 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
92636 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
92637 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
92638 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
92639 + uint32_t res007c; /**< 0x7c */
92640 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
92641 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
92642 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
92643 + struct {
92644 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
92645 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
92646 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
92647 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
92648 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
92649 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
92650 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
92651 + uint32_t res001c; /**< 0x1c */
92652 + } dbg_traps[3]; /**< 0x90 - 0xef */
92653 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
92654 +};
92655 +
92656 +struct fman_dma_regs {
92657 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
92658 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
92659 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
92660 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
92661 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
92662 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
92663 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
92664 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
92665 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
92666 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
92667 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
92668 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
92669 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
92670 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
92671 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
92672 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
92673 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
92674 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
92675 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
92676 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
92677 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
92678 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
92679 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
92680 + uint32_t res005c; /**< 0x5c */
92681 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
92682 + uint32_t res00e0[0x400 - 56];
92683 +};
92684 +
92685 +struct fman_rg {
92686 + struct fman_fpm_regs *fpm_rg;
92687 + struct fman_dma_regs *dma_rg;
92688 + struct fman_bmi_regs *bmi_rg;
92689 + struct fman_qmi_regs *qmi_rg;
92690 +};
92691 +
92692 +enum fman_dma_cache_override {
92693 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
92694 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
92695 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
92696 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
92697 +};
92698 +
92699 +enum fman_dma_aid_mode {
92700 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
92701 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
92702 +};
92703 +
92704 +enum fman_dma_dbg_cnt_mode {
92705 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
92706 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
92707 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
92708 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
92709 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
92710 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
92711 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
92712 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
92713 +};
92714 +
92715 +enum fman_dma_emergency_level {
92716 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
92717 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
92718 +};
92719 +
92720 +enum fman_catastrophic_err {
92721 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
92722 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
92723 +};
92724 +
92725 +enum fman_dma_err {
92726 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
92727 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
92728 +};
92729 +
92730 +struct fman_cfg {
92731 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
92732 + bool en_counters;
92733 + uint8_t disp_limit_tsh;
92734 + uint8_t prs_disp_tsh;
92735 + uint8_t plcr_disp_tsh;
92736 + uint8_t kg_disp_tsh;
92737 + uint8_t bmi_disp_tsh;
92738 + uint8_t qmi_enq_disp_tsh;
92739 + uint8_t qmi_deq_disp_tsh;
92740 + uint8_t fm_ctl1_disp_tsh;
92741 + uint8_t fm_ctl2_disp_tsh;
92742 + enum fman_dma_cache_override dma_cache_override;
92743 + enum fman_dma_aid_mode dma_aid_mode;
92744 + bool dma_aid_override;
92745 + uint8_t dma_axi_dbg_num_of_beats;
92746 + uint8_t dma_cam_num_of_entries;
92747 + uint32_t dma_watchdog;
92748 + uint8_t dma_comm_qtsh_asrt_emer;
92749 + uint8_t dma_write_buf_tsh_asrt_emer;
92750 + uint8_t dma_read_buf_tsh_asrt_emer;
92751 + uint8_t dma_comm_qtsh_clr_emer;
92752 + uint8_t dma_write_buf_tsh_clr_emer;
92753 + uint8_t dma_read_buf_tsh_clr_emer;
92754 + uint32_t dma_sos_emergency;
92755 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
92756 + bool dma_stop_on_bus_error;
92757 + bool dma_en_emergency;
92758 + uint32_t dma_emergency_bus_select;
92759 + enum fman_dma_emergency_level dma_emergency_level;
92760 + bool dma_en_emergency_smoother;
92761 + uint32_t dma_emergency_switch_counter;
92762 + bool halt_on_external_activ;
92763 + bool halt_on_unrecov_ecc_err;
92764 + enum fman_catastrophic_err catastrophic_err;
92765 + enum fman_dma_err dma_err;
92766 + bool en_muram_test_mode;
92767 + bool en_iram_test_mode;
92768 + bool external_ecc_rams_enable;
92769 + uint16_t tnum_aging_period;
92770 + uint32_t exceptions;
92771 + uint16_t clk_freq;
92772 + bool pedantic_dma;
92773 + uint32_t cam_base_addr;
92774 + uint32_t fifo_base_addr;
92775 + uint32_t total_fifo_size;
92776 + uint8_t total_num_of_tasks;
92777 + bool qmi_deq_option_support;
92778 + uint32_t qmi_def_tnums_thresh;
92779 + bool fman_partition_array;
92780 + uint8_t num_of_fman_ctrl_evnt_regs;
92781 +};
92782 +
92783 +/**************************************************************************//**
92784 + @Description Exceptions
92785 +*//***************************************************************************/
92786 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
92787 +#define FMAN_EX_DMA_READ_ECC 0x40000000
92788 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
92789 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
92790 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
92791 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
92792 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
92793 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
92794 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
92795 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
92796 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
92797 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
92798 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
92799 +#define FMAN_EX_IRAM_ECC 0x00040000
92800 +#define FMAN_EX_NURAM_ECC 0x00020000
92801 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
92802 +
92803 +enum fman_exceptions {
92804 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
92805 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
92806 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
92807 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
92808 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
92809 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
92810 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
92811 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
92812 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
92813 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
92814 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
92815 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
92816 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
92817 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
92818 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
92819 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
92820 +};
92821 +
92822 +enum fman_counters {
92823 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
92824 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
92825 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
92826 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
92827 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
92828 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
92829 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
92830 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
92831 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
92832 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
92833 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
92834 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
92835 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
92836 +};
92837 +
92838 +#define FPM_PRT_FM_CTL1 0x00000001
92839 +#define FPM_PRT_FM_CTL2 0x00000002
92840 +
92841 +/**************************************************************************//**
92842 + @Description DMA definitions
92843 +*//***************************************************************************/
92844 +
92845 +/* masks */
92846 +#define DMA_MODE_AID_OR 0x20000000
92847 +#define DMA_MODE_SBER 0x10000000
92848 +#define DMA_MODE_BER 0x00200000
92849 +#define DMA_MODE_EB 0x00100000
92850 +#define DMA_MODE_ECC 0x00000020
92851 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
92852 +#define DMA_MODE_SECURE_PROT 0x00000800
92853 +#define DMA_MODE_EMER_READ 0x00080000
92854 +#define DMA_MODE_EMER_WRITE 0x00040000
92855 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
92856 +#define DMA_MODE_CEN_MASK 0x0000E000
92857 +#define DMA_MODE_DBG_MASK 0x00000380
92858 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
92859 +
92860 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
92861 +
92862 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
92863 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
92864 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
92865 +
92866 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
92867 +#define DMA_LOW_LIODN_MASK 0x00000FFF
92868 +
92869 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
92870 +#define DMA_STATUS_BUS_ERR 0x08000000
92871 +#define DMA_STATUS_READ_ECC 0x04000000
92872 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
92873 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
92874 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
92875 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
92876 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
92877 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
92878 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
92879 +
92880 +#define FM_LIODN_BASE_MASK 0x00000FFF
92881 +
92882 +/* shifts */
92883 +#define DMA_MODE_CACHE_OR_SHIFT 30
92884 +#define DMA_MODE_BUS_PRI_SHIFT 16
92885 +#define DMA_MODE_AXI_DBG_SHIFT 24
92886 +#define DMA_MODE_CEN_SHIFT 13
92887 +#define DMA_MODE_BUS_PROT_SHIFT 10
92888 +#define DMA_MODE_DBG_SHIFT 7
92889 +#define DMA_MODE_EMER_LVL_SHIFT 6
92890 +#define DMA_MODE_AID_MODE_SHIFT 4
92891 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
92892 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
92893 +
92894 +#define DMA_THRESH_COMMQ_SHIFT 24
92895 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
92896 +
92897 +#define DMA_LIODN_SHIFT 16
92898 +
92899 +#define DMA_TRANSFER_PORTID_SHIFT 24
92900 +#define DMA_TRANSFER_TNUM_SHIFT 16
92901 +
92902 +/* sizes */
92903 +#define DMA_MAX_WATCHDOG 0xffffffff
92904 +
92905 +/* others */
92906 +#define DMA_CAM_SIZEOF_ENTRY 0x40
92907 +#define DMA_CAM_ALIGN 0x1000
92908 +#define DMA_CAM_UNITS 8
92909 +
92910 +/**************************************************************************//**
92911 + @Description General defines
92912 +*//***************************************************************************/
92913 +
92914 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
92915 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
92916 +
92917 +/**************************************************************************//**
92918 + @Description FPM defines
92919 +*//***************************************************************************/
92920 +
92921 +/* masks */
92922 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
92923 +#define FPM_EV_MASK_STALL 0x40000000
92924 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
92925 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
92926 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
92927 +#define FPM_EV_MASK_STALL_EN 0x00004000
92928 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
92929 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
92930 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
92931 +
92932 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
92933 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
92934 +#define FPM_RAM_MURAM_ECC 0x00008000
92935 +#define FPM_RAM_IRAM_ECC 0x00004000
92936 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
92937 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
92938 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
92939 +
92940 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
92941 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
92942 +
92943 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
92944 +#define FPM_REV1_MINOR_MASK 0x000000FF
92945 +
92946 +#define FPM_REV2_INTEG_MASK 0x00FF0000
92947 +#define FPM_REV2_ERR_MASK 0x0000FF00
92948 +#define FPM_REV2_CFG_MASK 0x000000FF
92949 +
92950 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
92951 +#define FPM_TS_CTL_EN 0x80000000
92952 +
92953 +#define FPM_PRC_REALSE_STALLED 0x00800000
92954 +
92955 +#define FPM_PS_STALLED 0x00800000
92956 +#define FPM_PS_FM_CTL1_SEL 0x80000000
92957 +#define FPM_PS_FM_CTL2_SEL 0x40000000
92958 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
92959 +
92960 +#define FPM_RSTC_FM_RESET 0x80000000
92961 +#define FPM_RSTC_10G0_RESET 0x04000000
92962 +#define FPM_RSTC_1G0_RESET 0x40000000
92963 +#define FPM_RSTC_1G1_RESET 0x20000000
92964 +#define FPM_RSTC_1G2_RESET 0x10000000
92965 +#define FPM_RSTC_1G3_RESET 0x08000000
92966 +#define FPM_RSTC_1G4_RESET 0x02000000
92967 +
92968 +
92969 +#define FPM_DISP_LIMIT_MASK 0x1F000000
92970 +#define FPM_THR1_PRS_MASK 0xFF000000
92971 +#define FPM_THR1_KG_MASK 0x00FF0000
92972 +#define FPM_THR1_PLCR_MASK 0x0000FF00
92973 +#define FPM_THR1_BMI_MASK 0x000000FF
92974 +
92975 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
92976 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
92977 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
92978 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
92979 +
92980 +/* shifts */
92981 +#define FPM_DISP_LIMIT_SHIFT 24
92982 +
92983 +#define FPM_THR1_PRS_SHIFT 24
92984 +#define FPM_THR1_KG_SHIFT 16
92985 +#define FPM_THR1_PLCR_SHIFT 8
92986 +#define FPM_THR1_BMI_SHIFT 0
92987 +
92988 +#define FPM_THR2_QMI_ENQ_SHIFT 24
92989 +#define FPM_THR2_QMI_DEQ_SHIFT 0
92990 +#define FPM_THR2_FM_CTL1_SHIFT 16
92991 +#define FPM_THR2_FM_CTL2_SHIFT 8
92992 +
92993 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
92994 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
92995 +
92996 +#define FPM_REV1_MAJOR_SHIFT 8
92997 +#define FPM_REV1_MINOR_SHIFT 0
92998 +
92999 +#define FPM_REV2_INTEG_SHIFT 16
93000 +#define FPM_REV2_ERR_SHIFT 8
93001 +#define FPM_REV2_CFG_SHIFT 0
93002 +
93003 +#define FPM_TS_INT_SHIFT 16
93004 +
93005 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
93006 +
93007 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
93008 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
93009 +
93010 +#define FPM_DISP_LIMIT_SHIFT 24
93011 +
93012 +/* Interrupts defines */
93013 +#define FPM_EVENT_FM_CTL_0 0x00008000
93014 +#define FPM_EVENT_FM_CTL 0x0000FF00
93015 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
93016 +
93017 +/* others */
93018 +#define FPM_MAX_DISP_LIMIT 31
93019 +#define FPM_RSTC_FM_RESET 0x80000000
93020 +#define FPM_RSTC_1G0_RESET 0x40000000
93021 +#define FPM_RSTC_1G1_RESET 0x20000000
93022 +#define FPM_RSTC_1G2_RESET 0x10000000
93023 +#define FPM_RSTC_1G3_RESET 0x08000000
93024 +#define FPM_RSTC_10G0_RESET 0x04000000
93025 +#define FPM_RSTC_1G4_RESET 0x02000000
93026 +#define FPM_RSTC_1G5_RESET 0x01000000
93027 +#define FPM_RSTC_1G6_RESET 0x00800000
93028 +#define FPM_RSTC_1G7_RESET 0x00400000
93029 +#define FPM_RSTC_10G1_RESET 0x00200000
93030 +/**************************************************************************//**
93031 + @Description BMI defines
93032 +*//***************************************************************************/
93033 +/* masks */
93034 +#define BMI_INIT_START 0x80000000
93035 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
93036 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
93037 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
93038 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
93039 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
93040 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
93041 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
93042 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
93043 +#define BMI_FIFO_SIZE_MASK 0x000003FF
93044 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
93045 +#define BMI_CFG2_DMAS_MASK 0x0000003F
93046 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
93047 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
93048 +
93049 +/* shifts */
93050 +#define BMI_CFG2_TASKS_SHIFT 16
93051 +#define BMI_CFG2_DMAS_SHIFT 0
93052 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
93053 +#define BMI_FIFO_SIZE_SHIFT 0
93054 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
93055 +#define BMI_NUM_OF_TASKS_SHIFT 24
93056 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
93057 +#define BMI_NUM_OF_DMAS_SHIFT 8
93058 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
93059 +
93060 +/* others */
93061 +#define BMI_FIFO_ALIGN 0x100
93062 +#define FMAN_BMI_FIFO_UNITS 0x100
93063 +
93064 +
93065 +/**************************************************************************//**
93066 + @Description QMI defines
93067 +*//***************************************************************************/
93068 +/* masks */
93069 +#define QMI_CFG_ENQ_EN 0x80000000
93070 +#define QMI_CFG_DEQ_EN 0x40000000
93071 +#define QMI_CFG_EN_COUNTERS 0x10000000
93072 +#define QMI_CFG_SOFT_RESET 0x01000000
93073 +#define QMI_CFG_DEQ_MASK 0x0000003F
93074 +#define QMI_CFG_ENQ_MASK 0x00003F00
93075 +
93076 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
93077 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
93078 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
93079 +
93080 +/* shifts */
93081 +#define QMI_CFG_ENQ_SHIFT 8
93082 +#define QMI_TAPC_TAP 22
93083 +
93084 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
93085 +
93086 +/**************************************************************************//**
93087 + @Description IRAM defines
93088 +*//***************************************************************************/
93089 +/* masks */
93090 +#define IRAM_IADD_AIE 0x80000000
93091 +#define IRAM_READY 0x80000000
93092 +
93093 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
93094 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
93095 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
93096 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
93097 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
93098 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
93099 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
93100 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
93101 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
93102 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
93103 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
93104 + uint8_t event_reg_id);
93105 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
93106 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
93107 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93108 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
93109 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
93110 + uint8_t port_id);
93111 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93112 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
93113 + uint8_t port_id);
93114 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
93115 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
93116 + uint8_t port_id);
93117 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
93118 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
93119 + uint8_t reg_id);
93120 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
93121 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
93122 + uint8_t *minor);
93123 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
93124 + enum fman_counters reg_name);
93125 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
93126 +
93127 +
93128 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
93129 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
93130 + uint32_t enable_events);
93131 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
93132 + uint8_t port_id,
93133 + uint8_t num_fman_ctrls,
93134 + uint32_t or_fman_ctrl);
93135 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
93136 + uint8_t port_id,
93137 + bool independent_mode,
93138 + bool is_rx_port);
93139 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93140 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
93141 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
93142 + uint8_t port_id,
93143 + uint16_t liodn_base,
93144 + uint16_t liodn_offset);
93145 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
93146 + uint8_t port_id,
93147 + uint32_t size_of_fifo,
93148 + uint32_t extra_size_of_fifo);
93149 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
93150 + uint8_t port_id,
93151 + uint8_t num_of_tasks,
93152 + uint8_t num_of_extra_tasks);
93153 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
93154 + uint8_t port_id,
93155 + uint8_t num_of_open_dmas,
93156 + uint8_t num_of_extra_open_dmas,
93157 + uint8_t total_num_of_dmas);
93158 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
93159 +int fman_set_exception(struct fman_rg *fman_rg,
93160 + enum fman_exceptions exception,
93161 + bool enable);
93162 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
93163 + bool enable);
93164 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
93165 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
93166 + uint32_t congestion_group_id,
93167 + uint8_t piority_bit_map,
93168 + uint32_t reg_num);
93169 +
93170 +
93171 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
93172 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93173 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
93174 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
93175 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
93176 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
93177 +void fman_free_resources(struct fman_rg *fman_rg);
93178 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
93179 +void fman_reset(struct fman_fpm_regs *fpm_rg);
93180 +void fman_resume(struct fman_fpm_regs *fpm_rg);
93181 +
93182 +
93183 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
93184 + uint8_t count1ubit,
93185 + uint16_t fm_clk_freq);
93186 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93187 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
93188 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
93189 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93190 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
93191 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
93192 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
93193 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
93194 +int fman_modify_counter(struct fman_rg *fman_rg,
93195 + enum fman_counters reg_name,
93196 + uint32_t val);
93197 +void fman_force_intr(struct fman_rg *fman_rg,
93198 + enum fman_exceptions exception);
93199 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
93200 + uint8_t port_id,
93201 + uint8_t base_storage_profile,
93202 + uint8_t log2_num_of_profiles);
93203 +
93204 +/**************************************************************************//**
93205 + @Description default values
93206 +*//***************************************************************************/
93207 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
93208 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
93209 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
93210 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
93211 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
93212 +#define DEFAULT_AID_OVERRIDE FALSE
93213 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
93214 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
93215 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
93216 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
93217 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
93218 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
93219 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
93220 +#define DEFAULT_DMA_SOS_EMERGENCY 0
93221 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
93222 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
93223 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
93224 +#define DEFAULT_DISP_LIMIT 0
93225 +#define DEFAULT_PRS_DISP_TH 16
93226 +#define DEFAULT_PLCR_DISP_TH 16
93227 +#define DEFAULT_KG_DISP_TH 16
93228 +#define DEFAULT_BMI_DISP_TH 16
93229 +#define DEFAULT_QMI_ENQ_DISP_TH 16
93230 +#define DEFAULT_QMI_DEQ_DISP_TH 16
93231 +#define DEFAULT_FM_CTL1_DISP_TH 16
93232 +#define DEFAULT_FM_CTL2_DISP_TH 16
93233 +#define DEFAULT_TNUM_AGING_PERIOD 4
93234 +
93235 +
93236 +#endif /* __FSL_FMAN_H */
93237 --- /dev/null
93238 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
93239 @@ -0,0 +1,1096 @@
93240 +/*
93241 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93242 + *
93243 + * Redistribution and use in source and binary forms, with or without
93244 + * modification, are permitted provided that the following conditions are met:
93245 + * * Redistributions of source code must retain the above copyright
93246 + * notice, this list of conditions and the following disclaimer.
93247 + * * Redistributions in binary form must reproduce the above copyright
93248 + * notice, this list of conditions and the following disclaimer in the
93249 + * documentation and/or other materials provided with the distribution.
93250 + * * Neither the name of Freescale Semiconductor nor the
93251 + * names of its contributors may be used to endorse or promote products
93252 + * derived from this software without specific prior written permission.
93253 + *
93254 + *
93255 + * ALTERNATIVELY, this software may be distributed under the terms of the
93256 + * GNU General Public License ("GPL") as published by the Free Software
93257 + * Foundation, either version 2 of that License or (at your option) any
93258 + * later version.
93259 + *
93260 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93261 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93262 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93263 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93264 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93265 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93266 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93267 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93268 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93269 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93270 + */
93271 +
93272 +#ifndef __FSL_FMAN_DTSEC_H
93273 +#define __FSL_FMAN_DTSEC_H
93274 +
93275 +#include "common/general.h"
93276 +#include "fsl_enet.h"
93277 +
93278 +/**
93279 + * DOC: dTSEC Init sequence
93280 + *
93281 + * To prepare dTSEC block for transfer use the following call sequence:
93282 + *
93283 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
93284 + * use is to obtain the default dTSEC configuration parameters.
93285 + *
93286 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
93287 + * to customize the dTSEC behavior.
93288 + *
93289 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
93290 + * dTSEC is initialized while both Tx and Rx are disabled.
93291 + *
93292 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
93293 + * This is used by dTSEC to match against received packets.
93294 + *
93295 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
93296 + * after the PHY establishes the link.
93297 + *
93298 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
93299 + * reception.
93300 + */
93301 +
93302 +/**
93303 + * DOC: dTSEC Graceful stop
93304 + *
93305 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
93306 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
93307 + * but return before this stop is complete. To query for graceful stop
93308 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
93309 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
93310 + * enable graceful stop interrupts.
93311 + *
93312 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
93313 + * fman_dtsec_start_rx().
93314 + */
93315 +
93316 +/**
93317 + * DOC: dTSEC interrupt handling
93318 + *
93319 + * This code does not provide an interrupt handler for dTSEC. Instead this
93320 + * handler should be implemented and registered to the operating system by the
93321 + * caller. Some primitives for accessing the event status and mask registers
93322 + * are provided.
93323 + *
93324 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
93325 + */
93326 +
93327 +/**
93328 + * DOC: dTSEC Events
93329 + *
93330 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
93331 + * event register at any time to check for pending interrupts. If an event
93332 + * occurs and its corresponding enable bit is set in the interrupt mask
93333 + * register, the event also causes a hardware interrupt at the PIC.
93334 + *
93335 + * To poll for event status use the fman_dtsec_get_event() function.
93336 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
93337 + * fman_dtsec_disable_interrupt() functions.
93338 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
93339 + * serviced event bit.
93340 + *
93341 + * The following events may be signaled by dTSEC hardware:
93342 + *
93343 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
93344 + * a frame was received with length in excess of the MAC's maximum frame length
93345 + * register.
93346 + *
93347 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
93348 + * control frame was received while Rx pause frame handling is enabled.
93349 + * Also see fman_dtsec_handle_rx_pause().
93350 + *
93351 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
93352 + * counters has exceeded the size of its register.
93353 + *
93354 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
93355 + * complete. The transmitter is in a stopped state, in which only pause frames
93356 + * can be transmitted.
93357 + * Also see fman_dtsec_stop_tx().
93358 + *
93359 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
93360 + * has exceeded the value in the MAC's Maximum Frame Length register.
93361 + *
93362 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
93363 + * indicates that a control frame was transmitted.
93364 + *
93365 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
93366 + * occurred on the transmitted channel. This bit is set whenever any transmit
93367 + * error occurs which causes the dTSEC to discard all or part of a frame
93368 + * (LC, CRL, XFUN).
93369 + *
93370 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
93371 + * occurred beyond the collision window (slot time) in half-duplex mode.
93372 + * The frame is truncated with a bad CRC and the remainder of the frame
93373 + * is discarded.
93374 + *
93375 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
93376 + * of successive transmission collisions has exceeded the MAC's half-duplex
93377 + * register's retransmission maximum count. The frame is discarded without
93378 + * being transmitted and transmission of the next frame commences. This only
93379 + * occurs while in half-duplex mode.
93380 + * The number of retransmit attempts can be set in
93381 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
93382 + *
93383 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
93384 + * transmit FIFO became empty before the complete frame was transmitted.
93385 + * The frame is truncated with a bad CRC and the remainder of the frame is
93386 + * discarded.
93387 + *
93388 + * %DTSEC_IEVENT_MAG - TBD
93389 + *
93390 + * %DTSEC_IEVENT_MMRD - MII management read completion.
93391 + *
93392 + * %DTSEC_IEVENT_MMWR - MII management write completion.
93393 + *
93394 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
93395 + * know if the system has completed the stop and it is safe to write to receive
93396 + * registers (status, control or configuration registers) that are used by the
93397 + * system during normal operation.
93398 + *
93399 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
93400 + * that the dTSEC has detected a parity error on its stored transmit data, which
93401 + * is likely to compromise the validity of recently transferred frames.
93402 + *
93403 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
93404 + * the dTSEC has detected a parity error on its stored receive data, which is
93405 + * likely to compromise the validity of recently transferred frames.
93406 + */
93407 +/* Interrupt Mask Register (IMASK) */
93408 +#define DTSEC_IMASK_BREN 0x80000000
93409 +#define DTSEC_IMASK_RXCEN 0x40000000
93410 +#define DTSEC_IMASK_MSROEN 0x04000000
93411 +#define DTSEC_IMASK_GTSCEN 0x02000000
93412 +#define DTSEC_IMASK_BTEN 0x01000000
93413 +#define DTSEC_IMASK_TXCEN 0x00800000
93414 +#define DTSEC_IMASK_TXEEN 0x00400000
93415 +#define DTSEC_IMASK_LCEN 0x00040000
93416 +#define DTSEC_IMASK_CRLEN 0x00020000
93417 +#define DTSEC_IMASK_XFUNEN 0x00010000
93418 +#define DTSEC_IMASK_ABRTEN 0x00008000
93419 +#define DTSEC_IMASK_IFERREN 0x00004000
93420 +#define DTSEC_IMASK_MAGEN 0x00000800
93421 +#define DTSEC_IMASK_MMRDEN 0x00000400
93422 +#define DTSEC_IMASK_MMWREN 0x00000200
93423 +#define DTSEC_IMASK_GRSCEN 0x00000100
93424 +#define DTSEC_IMASK_TDPEEN 0x00000002
93425 +#define DTSEC_IMASK_RDPEEN 0x00000001
93426 +
93427 +#define DTSEC_EVENTS_MASK \
93428 + ((uint32_t)(DTSEC_IMASK_BREN | \
93429 + DTSEC_IMASK_RXCEN | \
93430 + DTSEC_IMASK_BTEN | \
93431 + DTSEC_IMASK_TXCEN | \
93432 + DTSEC_IMASK_TXEEN | \
93433 + DTSEC_IMASK_ABRTEN | \
93434 + DTSEC_IMASK_LCEN | \
93435 + DTSEC_IMASK_CRLEN | \
93436 + DTSEC_IMASK_XFUNEN | \
93437 + DTSEC_IMASK_IFERREN | \
93438 + DTSEC_IMASK_MAGEN | \
93439 + DTSEC_IMASK_TDPEEN | \
93440 + DTSEC_IMASK_RDPEEN))
93441 +
93442 +/* dtsec timestamp event bits */
93443 +#define TMR_PEMASK_TSREEN 0x00010000
93444 +#define TMR_PEVENT_TSRE 0x00010000
93445 +
93446 +/* Group address bit indication */
93447 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
93448 +/* size in bytes of L2 address */
93449 +#define MAC_ADDRLEN 6
93450 +
93451 +#define DEFAULT_HALFDUP_ON FALSE
93452 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
93453 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
93454 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
93455 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
93456 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
93457 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
93458 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
93459 +#define DEFAULT_RX_DROP_BCAST FALSE
93460 +#define DEFAULT_RX_SHORT_FRM TRUE
93461 +#define DEFAULT_RX_LEN_CHECK FALSE
93462 +#define DEFAULT_TX_PAD_CRC TRUE
93463 +#define DEFAULT_TX_CRC FALSE
93464 +#define DEFAULT_RX_CTRL_ACC FALSE
93465 +#define DEFAULT_TX_PAUSE_TIME 0xf000
93466 +#define DEFAULT_TBIPA 5
93467 +#define DEFAULT_RX_PREPEND 0
93468 +#define DEFAULT_PTP_TSU_EN TRUE
93469 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
93470 +#define DEFAULT_PREAMBLE_LEN 7
93471 +#define DEFAULT_RX_PREAMBLE FALSE
93472 +#define DEFAULT_TX_PREAMBLE FALSE
93473 +#define DEFAULT_LOOPBACK FALSE
93474 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
93475 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
93476 +#define DEFAULT_RX_FLOW TRUE
93477 +#define DEFAULT_TX_FLOW TRUE
93478 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
93479 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
93480 +#define DEFAULT_RX_PROMISC FALSE
93481 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
93482 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
93483 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
93484 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
93485 +#define DEFAULT_MAXIMUM_FRAME 0x600
93486 +#define DEFAULT_TBI_PHY_ADDR 5
93487 +#define DEFAULT_WAKE_ON_LAN FALSE
93488 +
93489 +/* register related defines (bits, field offsets..) */
93490 +#define DTSEC_ID1_ID 0xffff0000
93491 +#define DTSEC_ID1_REV_MJ 0x0000FF00
93492 +#define DTSEC_ID1_REV_MN 0x000000ff
93493 +
93494 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
93495 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
93496 +
93497 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
93498 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
93499 +#define DTSEC_ECNTRL_STEN 0x00001000
93500 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
93501 +#define DTSEC_ECNTRL_GMIIM 0x00000040
93502 +#define DTSEC_ECNTRL_TBIM 0x00000020
93503 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
93504 +#define DTSEC_ECNTRL_RPM 0x00000010
93505 +#define DTSEC_ECNTRL_R100M 0x00000008
93506 +#define DTSEC_ECNTRL_RMM 0x00000004
93507 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
93508 +
93509 +#define DTSEC_TCTRL_THDF 0x00000800
93510 +#define DTSEC_TCTRL_TTSE 0x00000040
93511 +#define DTSEC_TCTRL_GTS 0x00000020
93512 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
93513 +
93514 +/* PTV offsets */
93515 +#define PTV_PTE_OFST 16
93516 +
93517 +#define RCTRL_CFA 0x00008000
93518 +#define RCTRL_GHTX 0x00000400
93519 +#define RCTRL_RTSE 0x00000040
93520 +#define RCTRL_GRS 0x00000020
93521 +#define RCTRL_BC_REJ 0x00000010
93522 +#define RCTRL_MPROM 0x00000008
93523 +#define RCTRL_RSF 0x00000004
93524 +#define RCTRL_UPROM 0x00000001
93525 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
93526 +
93527 +#define TMR_CTL_ESFDP 0x00000800
93528 +#define TMR_CTL_ESFDE 0x00000400
93529 +
93530 +#define MACCFG1_SOFT_RESET 0x80000000
93531 +#define MACCFG1_LOOPBACK 0x00000100
93532 +#define MACCFG1_RX_FLOW 0x00000020
93533 +#define MACCFG1_TX_FLOW 0x00000010
93534 +#define MACCFG1_TX_EN 0x00000001
93535 +#define MACCFG1_RX_EN 0x00000004
93536 +#define MACCFG1_RESET_RxMC 0x00080000
93537 +#define MACCFG1_RESET_TxMC 0x00040000
93538 +#define MACCFG1_RESET_RxFUN 0x00020000
93539 +#define MACCFG1_RESET_TxFUN 0x00010000
93540 +
93541 +#define MACCFG2_NIBBLE_MODE 0x00000100
93542 +#define MACCFG2_BYTE_MODE 0x00000200
93543 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
93544 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
93545 +#define MACCFG2_LENGTH_CHECK 0x00000010
93546 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
93547 +#define MACCFG2_PAD_CRC_EN 0x00000004
93548 +#define MACCFG2_CRC_EN 0x00000002
93549 +#define MACCFG2_FULL_DUPLEX 0x00000001
93550 +
93551 +#define PREAMBLE_LENGTH_SHIFT 12
93552 +
93553 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
93554 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
93555 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
93556 +
93557 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
93558 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
93559 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
93560 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
93561 +
93562 +#define HAFDUP_ALT_BEB 0x00080000
93563 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
93564 +#define HAFDUP_NO_BACKOFF 0x00020000
93565 +#define HAFDUP_EXCESS_DEFER 0x00010000
93566 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
93567 +
93568 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
93569 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
93570 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
93571 +
93572 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
93573 +
93574 +/* CAR1/2 bits */
93575 +#define DTSEC_CAR1_TR64 0x80000000
93576 +#define DTSEC_CAR1_TR127 0x40000000
93577 +#define DTSEC_CAR1_TR255 0x20000000
93578 +#define DTSEC_CAR1_TR511 0x10000000
93579 +#define DTSEC_CAR1_TRK1 0x08000000
93580 +#define DTSEC_CAR1_TRMAX 0x04000000
93581 +#define DTSEC_CAR1_TRMGV 0x02000000
93582 +
93583 +#define DTSEC_CAR1_RBYT 0x00010000
93584 +#define DTSEC_CAR1_RPKT 0x00008000
93585 +#define DTSEC_CAR1_RFCS 0x00004000
93586 +#define DTSEC_CAR1_RMCA 0x00002000
93587 +#define DTSEC_CAR1_RBCA 0x00001000
93588 +#define DTSEC_CAR1_RXCF 0x00000800
93589 +#define DTSEC_CAR1_RXPF 0x00000400
93590 +#define DTSEC_CAR1_RXUO 0x00000200
93591 +#define DTSEC_CAR1_RALN 0x00000100
93592 +#define DTSEC_CAR1_RFLR 0x00000080
93593 +#define DTSEC_CAR1_RCDE 0x00000040
93594 +#define DTSEC_CAR1_RCSE 0x00000020
93595 +#define DTSEC_CAR1_RUND 0x00000010
93596 +#define DTSEC_CAR1_ROVR 0x00000008
93597 +#define DTSEC_CAR1_RFRG 0x00000004
93598 +#define DTSEC_CAR1_RJBR 0x00000002
93599 +#define DTSEC_CAR1_RDRP 0x00000001
93600 +
93601 +#define DTSEC_CAR2_TJBR 0x00080000
93602 +#define DTSEC_CAR2_TFCS 0x00040000
93603 +#define DTSEC_CAR2_TXCF 0x00020000
93604 +#define DTSEC_CAR2_TOVR 0x00010000
93605 +#define DTSEC_CAR2_TUND 0x00008000
93606 +#define DTSEC_CAR2_TFRG 0x00004000
93607 +#define DTSEC_CAR2_TBYT 0x00002000
93608 +#define DTSEC_CAR2_TPKT 0x00001000
93609 +#define DTSEC_CAR2_TMCA 0x00000800
93610 +#define DTSEC_CAR2_TBCA 0x00000400
93611 +#define DTSEC_CAR2_TXPF 0x00000200
93612 +#define DTSEC_CAR2_TDFR 0x00000100
93613 +#define DTSEC_CAR2_TEDF 0x00000080
93614 +#define DTSEC_CAR2_TSCL 0x00000040
93615 +#define DTSEC_CAR2_TMCL 0x00000020
93616 +#define DTSEC_CAR2_TLCL 0x00000010
93617 +#define DTSEC_CAR2_TXCL 0x00000008
93618 +#define DTSEC_CAR2_TNCL 0x00000004
93619 +#define DTSEC_CAR2_TDRP 0x00000001
93620 +
93621 +#define CAM1_ERRORS_ONLY \
93622 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
93623 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
93624 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93625 + | DTSEC_CAR1_RDRP)
93626 +
93627 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
93628 +
93629 +/*
93630 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
93631 + * (or Ethernet) statistics.
93632 + */
93633 +#define CAM1_MIB_GRP_1 \
93634 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
93635 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
93636 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
93637 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
93638 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
93639 +
93640 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
93641 +
93642 +/* memory map */
93643 +
93644 +struct dtsec_regs {
93645 + /* dTSEC General Control and Status Registers */
93646 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
93647 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
93648 + uint32_t ievent; /* 0x008 Interrupt event register */
93649 + uint32_t imask; /* 0x00C Interrupt mask register */
93650 + uint32_t reserved0010[1];
93651 + uint32_t ecntrl; /* 0x014 E control register */
93652 + uint32_t ptv; /* 0x018 Pause time value register */
93653 + uint32_t tbipa; /* 0x01C TBI PHY address register */
93654 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
93655 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
93656 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
93657 + uint32_t reserved002c[5];
93658 + uint32_t tctrl; /* 0x040 Transmit control register */
93659 + uint32_t reserved0044[3];
93660 + uint32_t rctrl; /* 0x050 Receive control register */
93661 + uint32_t reserved0054[11];
93662 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
93663 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
93664 + uint32_t reserved00c0[16];
93665 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
93666 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
93667 + uint32_t ipgifg; /* 0x108 IPG/IFG */
93668 + uint32_t hafdup; /* 0x10C Half-duplex */
93669 + uint32_t maxfrm; /* 0x110 Maximum frame */
93670 + uint32_t reserved0114[10];
93671 + uint32_t ifstat; /* 0x13C Interface status */
93672 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
93673 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
93674 + struct {
93675 + uint32_t exact_match1; /* octets 1-4 */
93676 + uint32_t exact_match2; /* octets 5-6 */
93677 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
93678 + uint32_t reserved01c0[16];
93679 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
93680 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
93681 + * counter */
93682 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
93683 + * counter */
93684 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
93685 + * counter */
93686 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
93687 + * counter */
93688 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
93689 + * counter */
93690 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
93691 + * VLAN frame count */
93692 + uint32_t rbyt; /* 0x21C receive byte counter */
93693 + uint32_t rpkt; /* 0x220 receive packet counter */
93694 + uint32_t rfcs; /* 0x224 receive FCS error counter */
93695 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
93696 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
93697 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
93698 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
93699 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
93700 + uint32_t raln; /* 0x23C receive alignment error counter */
93701 + uint32_t rflr; /* 0x240 receive frame length error counter */
93702 + uint32_t rcde; /* 0x244 receive code error counter */
93703 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
93704 + uint32_t rund; /* 0x24C receive undersize packet counter */
93705 + uint32_t rovr; /* 0x250 receive oversize packet counter */
93706 + uint32_t rfrg; /* 0x254 receive fragments counter */
93707 + uint32_t rjbr; /* 0x258 receive jabber counter */
93708 + uint32_t rdrp; /* 0x25C receive drop */
93709 + uint32_t tbyt; /* 0x260 transmit byte counter */
93710 + uint32_t tpkt; /* 0x264 transmit packet counter */
93711 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
93712 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
93713 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
93714 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
93715 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
93716 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
93717 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
93718 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
93719 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
93720 + uint32_t tncl; /* 0x28C transmit total collision counter */
93721 + uint32_t reserved0290[1];
93722 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
93723 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
93724 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
93725 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
93726 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
93727 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
93728 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
93729 + uint32_t car1; /* 0x2B0 carry register one register* */
93730 + uint32_t car2; /* 0x2B4 carry register two register* */
93731 + uint32_t cam1; /* 0x2B8 carry register one mask register */
93732 + uint32_t cam2; /* 0x2BC carry register two mask register */
93733 + uint32_t reserved02c0[848];
93734 +};
93735 +
93736 +/**
93737 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
93738 + *
93739 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
93740 + * good or bad frame, of any type, transmitted or received, which
93741 + * is 64 bytes in length.
93742 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
93743 + * each good or bad frame of any type, transmitted or received,
93744 + * which is 65-127 bytes in length.
93745 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
93746 + * for each good or bad frame, of any type, transmitted or
93747 + * received, which is 128-255 bytes in length.
93748 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
93749 + * for each good or bad frame, of any type, transmitted or
93750 + * received, which is 256-511 bytes in length.
93751 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
93752 + * for each good or bad frame, of any type, transmitted or
93753 + * received, which is 512-1023 bytes in length.
93754 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
93755 + * for each good or bad frame, of any type, transmitted or
93756 + * received, which is 1024-1518 bytes in length.
93757 + * @rfrg: Receive fragments count. Increments for each received frame
93758 + * which is less than 64 bytes in length and contains an invalid
93759 + * FCS. This includes integral and non-integral lengths.
93760 + * @rjbr: Receive jabber count. Increments for received frames which
93761 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
93762 + * invalid FCS. This includes alignment errors.
93763 + * @rdrp: Receive dropped packets count. Increments for received frames
93764 + * which are streamed to system but are later dropped due to lack
93765 + * of system resources. Does not increment for frames rejected due
93766 + * to address filtering.
93767 + * @raln: Receive alignment error count. Increments for each received
93768 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
93769 + * an invalid FCS and is not an integral number of bytes.
93770 + * @rund: Receive undersize packet count. Increments each time a frame is
93771 + * received which is less than 64 bytes in length and contains a
93772 + * valid FCS and is otherwise well formed. This count does not
93773 + * include range length errors.
93774 + * @rovr: Receive oversize packet count. Increments each time a frame is
93775 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
93776 + * contains a valid FCS and is otherwise well formed.
93777 + * @rbyt: Receive byte count. Increments by the byte count of frames
93778 + * received, including those in bad packets, excluding preamble and
93779 + * SFD but including FCS bytes.
93780 + * @rpkt: Receive packet count. Increments for each received frame
93781 + * (including bad packets, all unicast, broadcast, and multicast
93782 + * packets).
93783 + * @rmca: Receive multicast packet count. Increments for each multicast
93784 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93785 + * 1522 (VLAN), excluding broadcast frames. This count does not
93786 + * include range/length errors.
93787 + * @rbca: Receive broadcast packet count. Increments for each broadcast
93788 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
93789 + * 1522 (VLAN), excluding multicast frames. Does not include
93790 + * range/length errors.
93791 + * @tdrp: Transmit drop frame count. Increments each time a memory error
93792 + * or an underrun has occurred.
93793 + * @tncl: Transmit total collision counter. Increments by the number of
93794 + * collisions experienced during the transmission of a frame. Does
93795 + * not increment for aborted frames.
93796 + *
93797 + * The structure contains a group of dTSEC HW specific counters relating to the
93798 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
93799 + * is counting only the carry events of the corresponding HW counters.
93800 + *
93801 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
93802 + * and SFD but including FCS bytes.
93803 + */
93804 +struct dtsec_mib_grp_1_counters {
93805 + uint64_t rdrp;
93806 + uint64_t tdrp;
93807 + uint64_t rbyt;
93808 + uint64_t rpkt;
93809 + uint64_t rbca;
93810 + uint64_t rmca;
93811 + uint64_t raln;
93812 + uint64_t rund;
93813 + uint64_t rovr;
93814 + uint64_t rfrg;
93815 + uint64_t rjbr;
93816 + uint64_t tncl;
93817 + uint64_t tr64;
93818 + uint64_t tr127;
93819 + uint64_t tr255;
93820 + uint64_t tr511;
93821 + uint64_t tr1k;
93822 + uint64_t trmax;
93823 +};
93824 +
93825 +enum dtsec_stat_counters {
93826 + E_DTSEC_STAT_TR64,
93827 + E_DTSEC_STAT_TR127,
93828 + E_DTSEC_STAT_TR255,
93829 + E_DTSEC_STAT_TR511,
93830 + E_DTSEC_STAT_TR1K,
93831 + E_DTSEC_STAT_TRMAX,
93832 + E_DTSEC_STAT_TRMGV,
93833 + E_DTSEC_STAT_RBYT,
93834 + E_DTSEC_STAT_RPKT,
93835 + E_DTSEC_STAT_RMCA,
93836 + E_DTSEC_STAT_RBCA,
93837 + E_DTSEC_STAT_RXPF,
93838 + E_DTSEC_STAT_RALN,
93839 + E_DTSEC_STAT_RFLR,
93840 + E_DTSEC_STAT_RCDE,
93841 + E_DTSEC_STAT_RCSE,
93842 + E_DTSEC_STAT_RUND,
93843 + E_DTSEC_STAT_ROVR,
93844 + E_DTSEC_STAT_RFRG,
93845 + E_DTSEC_STAT_RJBR,
93846 + E_DTSEC_STAT_RDRP,
93847 + E_DTSEC_STAT_TFCS,
93848 + E_DTSEC_STAT_TBYT,
93849 + E_DTSEC_STAT_TPKT,
93850 + E_DTSEC_STAT_TMCA,
93851 + E_DTSEC_STAT_TBCA,
93852 + E_DTSEC_STAT_TXPF,
93853 + E_DTSEC_STAT_TNCL,
93854 + E_DTSEC_STAT_TDRP
93855 +};
93856 +
93857 +enum dtsec_stat_level {
93858 + /* No statistics */
93859 + E_MAC_STAT_NONE = 0,
93860 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
93861 + E_MAC_STAT_MIB_GRP1,
93862 + /* Only error counters are available. Optimized for performance */
93863 + E_MAC_STAT_PARTIAL,
93864 + /* All counters available. Not optimized for performance */
93865 + E_MAC_STAT_FULL
93866 +};
93867 +
93868 +
93869 +/**
93870 + * struct dtsec_cfg - dTSEC configuration
93871 + *
93872 + * @halfdup_on: Transmit half-duplex flow control, under software
93873 + * control for 10/100-Mbps half-duplex media. If set,
93874 + * back pressure is applied to media by raising carrier.
93875 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
93876 + * If this is exceeded dTSEC aborts transmission due to
93877 + * excessive collisions. The standard specifies the
93878 + * attempt limit to be 15.
93879 + * @halfdup_coll_window:The number of bytes of the frame during which
93880 + * collisions may occur. The default value of 55
93881 + * corresponds to the frame byte at the end of the
93882 + * standard 512-bit slot time window. If collisions are
93883 + * detected after this byte, the late collision event is
93884 + * asserted and transmission of current frame is aborted.
93885 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
93886 + * will be discarded by dTSEC.
93887 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
93888 + * of length 14..63 bytes.
93889 + * @rx_len_check: Length check for received frames. If set, the MAC
93890 + * checks the frame's length field on receive to ensure it
93891 + * matches the actual data field length. This only works
93892 + * for received frames with length field less than 1500.
93893 + * No check is performed for larger frames.
93894 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
93895 + * transmitted short frames and appends a CRC to every
93896 + * frame regardless of padding requirement.
93897 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
93898 + * to all frames. If frames presented to the MAC have a
93899 + * valid length and contain a valid CRC, @tx_crc should be
93900 + * reset.
93901 + * This field is ignored if @tx_pad_crc is set.
93902 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
93903 + * standard control frame behavior, and all Ethernet frames
93904 + * that have an ethertype of 0x8808 are treated as normal
93905 + * Ethernet frames and passed up to the packet interface on
93906 + * a DA match. Received pause control frames are passed to
93907 + * the packet interface only if Rx flow control is also
93908 + * disabled. See fman_dtsec_handle_rx_pause() function.
93909 + * @tx_pause_time: Transmit pause time value. This pause value is used as
93910 + * part of the pause frame to be sent when a transmit pause
93911 + * frame is initiated. If set to 0 this disables
93912 + * transmission of pause frames.
93913 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
93914 + * received Ethernet 7-byte preamble and passes it to the
93915 + * packet interface at the start of each received frame.
93916 + * This field should be reset for internal MAC loop-back
93917 + * mode.
93918 + * @tx_preamble: User defined preamble enable for transmitted frames.
93919 + * If set, a user-defined preamble must passed to the MAC
93920 + * and it is transmitted instead of the standard preamble.
93921 + * @preamble_len: Length, in bytes, of the preamble field preceding each
93922 + * Ethernet start-of-frame delimiter byte. The default
93923 + * value of 0x7 should be used in order to guarantee
93924 + * reliable operation with IEEE 802.3 compliant hardware.
93925 + * @rx_prepend: Packet alignment padding length. The specified number
93926 + * of bytes (1-31) of zero padding are inserted before the
93927 + * start of each received frame. For Ethernet, where
93928 + * optional preamble extraction is enabled, the padding
93929 + * appears before the preamble, otherwise the padding
93930 + * precedes the layer 2 header.
93931 + *
93932 + * This structure contains basic dTSEC configuration and must be passed to
93933 + * fman_dtsec_init() function. A default set of configuration values can be
93934 + * obtained by calling fman_dtsec_defconfig().
93935 + */
93936 +struct dtsec_cfg {
93937 + bool halfdup_on;
93938 + bool halfdup_alt_backoff_en;
93939 + bool halfdup_excess_defer;
93940 + bool halfdup_no_backoff;
93941 + bool halfdup_bp_no_backoff;
93942 + uint8_t halfdup_alt_backoff_val;
93943 + uint16_t halfdup_retransmit;
93944 + uint16_t halfdup_coll_window;
93945 + bool rx_drop_bcast;
93946 + bool rx_short_frm;
93947 + bool rx_len_check;
93948 + bool tx_pad_crc;
93949 + bool tx_crc;
93950 + bool rx_ctrl_acc;
93951 + unsigned short tx_pause_time;
93952 + unsigned short tbipa;
93953 + bool ptp_tsu_en;
93954 + bool ptp_exception_en;
93955 + bool rx_preamble;
93956 + bool tx_preamble;
93957 + unsigned char preamble_len;
93958 + unsigned char rx_prepend;
93959 + bool loopback;
93960 + bool rx_time_stamp_en;
93961 + bool tx_time_stamp_en;
93962 + bool rx_flow;
93963 + bool tx_flow;
93964 + bool rx_group_hash_exd;
93965 + bool rx_promisc;
93966 + uint8_t tbi_phy_addr;
93967 + uint16_t tx_pause_time_extd;
93968 + uint16_t maximum_frame;
93969 + uint32_t non_back_to_back_ipg1;
93970 + uint32_t non_back_to_back_ipg2;
93971 + uint32_t min_ifg_enforcement;
93972 + uint32_t back_to_back_ipg;
93973 + bool wake_on_lan;
93974 +};
93975 +
93976 +
93977 +/**
93978 + * fman_dtsec_defconfig() - Get default dTSEC configuration
93979 + * @cfg: pointer to configuration structure.
93980 + *
93981 + * Call this function to obtain a default set of configuration values for
93982 + * initializing dTSEC. The user can overwrite any of the values before calling
93983 + * fman_dtsec_init(), if specific configuration needs to be applied.
93984 + */
93985 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
93986 +
93987 +/**
93988 + * fman_dtsec_init() - Init dTSEC hardware block
93989 + * @regs: Pointer to dTSEC register block
93990 + * @cfg: dTSEC configuration data
93991 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
93992 + * @iface_speed: 1G or 10G
93993 + * @macaddr: MAC station address to be assigned to the device
93994 + * @fm_rev_maj: major rev number
93995 + * @fm_rev_min: minor rev number
93996 + * @exceptions_mask: initial exceptions mask
93997 + *
93998 + * This function initializes dTSEC and applies basic configuration.
93999 + *
94000 + * dTSEC initialization sequence:
94001 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
94002 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
94003 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
94004 + *
94005 + * Returns: 0 if successful, an error code otherwise.
94006 + */
94007 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
94008 + enum enet_interface iface_mode,
94009 + enum enet_speed iface_speed,
94010 + uint8_t *macaddr, uint8_t fm_rev_maj,
94011 + uint8_t fm_rev_min,
94012 + uint32_t exception_mask);
94013 +
94014 +/**
94015 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
94016 + * @regs: Pointer to dTSEC register block
94017 + * @apply_rx: enable rx side
94018 + * @apply_tx: enable tx side
94019 + *
94020 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
94021 + */
94022 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94023 +
94024 +/**
94025 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
94026 + * @regs: Pointer to dTSEC register block
94027 + * @apply_rx: disable rx side
94028 + * @apply_tx: disable tx side
94029 + *
94030 + * This function disables Tx and Rx in dTSEC.
94031 + */
94032 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
94033 +
94034 +/**
94035 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
94036 + * @regs: Pointer to dTSEC register block
94037 + *
94038 + * Returns dtsec_id content
94039 + *
94040 + * Call this function to obtain the dTSEC hardware version.
94041 + */
94042 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
94043 +
94044 +/**
94045 + * fman_dtsec_set_mac_address() - Set MAC station address
94046 + * @regs: Pointer to dTSEC register block
94047 + * @macaddr: MAC address array
94048 + *
94049 + * This function sets MAC station address. To enable unicast reception call
94050 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
94051 + * match the destination address of received unicast frames against this
94052 + * address.
94053 + */
94054 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94055 +
94056 +/**
94057 + * fman_dtsec_get_mac_address() - Query MAC station address
94058 + * @regs: Pointer to dTSEC register block
94059 + * @macaddr: MAC address array
94060 + */
94061 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
94062 +
94063 +/**
94064 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
94065 + * @regs: Pointer to dTSEC register block
94066 + * @enable: Enable unicast promiscuous mode
94067 + *
94068 + * Use this function to enable/disable dTSEC L2 address filtering. If the
94069 + * address filtering is disabled all unicast packets are accepted.
94070 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
94071 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
94072 + * multicast addresses.
94073 + */
94074 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
94075 +
94076 +/**
94077 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
94078 + * (magic packet support)
94079 + * @regs: Pointer to dTSEC register block
94080 + * @en: Enable Wake On Lan support in dTSEC
94081 + *
94082 + */
94083 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
94084 +
94085 +/**
94086 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
94087 + * @regs: Pointer to dTSEC register block
94088 + * @iface_mode: dTSEC interface mode
94089 + * @speed: Link speed
94090 + * @full_dx: True for full-duplex, false for half-duplex.
94091 + *
94092 + * This function configures the MAC to function and the desired rates. Use it
94093 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
94094 + * changes (for instance following PHY auto-negociation).
94095 + *
94096 + * Returns: 0 if successful, an error code otherwise.
94097 + */
94098 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
94099 + enum enet_interface iface_mode,
94100 + enum enet_speed speed, bool full_dx);
94101 +
94102 +/**
94103 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
94104 + * @regs: Pointer to dTSEC register block
94105 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
94106 + *
94107 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
94108 + * so that the associated TBI PHY (i.e. the link) may be initialized.
94109 + *
94110 + * Returns: 0 if successful, an error code otherwise.
94111 + */
94112 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
94113 + uint8_t addr);
94114 +
94115 +/**
94116 + * fman_dtsec_set_max_frame_len() - Set max frame length
94117 + * @regs: Pointer to dTSEC register block
94118 + * @length: Max frame length.
94119 + *
94120 + * Sets maximum frame length for received and transmitted frames. Frames that
94121 + * exceeds this length are truncated.
94122 + */
94123 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
94124 +
94125 +/**
94126 + * fman_dtsec_get_max_frame_len() - Query max frame length
94127 + * @regs: Pointer to dTSEC register block
94128 + *
94129 + * Returns: the current value of the maximum frame length.
94130 + */
94131 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
94132 +
94133 +/**
94134 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
94135 + * @regs: Pointer to dTSEC register block
94136 + * @en: Enable pause frame handling in dTSEC
94137 + *
94138 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
94139 + * if dTSEC is set in half-duplex mode.
94140 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
94141 + * frames will be transferred to the packet interface just like regular Ethernet
94142 + * frames.
94143 + */
94144 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
94145 +
94146 +/**
94147 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
94148 + * @regs: Pointer to dTSEC register block
94149 + * @time: Time value included in pause frames
94150 + *
94151 + * Call this function to set the time value used in transmitted pause frames.
94152 + * If time is 0, transmission of pause frames is disabled
94153 + */
94154 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
94155 +
94156 +/**
94157 + * fman_dtsec_ack_event() - Acknowledge handled events
94158 + * @regs: Pointer to dTSEC register block
94159 + * @ev_mask: Events to acknowledge
94160 + *
94161 + * After handling events signaled by dTSEC in either polling or interrupt mode,
94162 + * call this function to reset the associated status bits in dTSEC event
94163 + * register.
94164 + */
94165 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
94166 +
94167 +/**
94168 + * fman_dtsec_get_event() - Returns currently asserted events
94169 + * @regs: Pointer to dTSEC register block
94170 + * @ev_mask: Mask of relevant events
94171 + *
94172 + * Call this function to obtain a bit-mask of events that are currently asserted
94173 + * in dTSEC, taken from IEVENT register.
94174 + *
94175 + * Returns: a bit-mask of events asserted in dTSEC.
94176 + */
94177 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
94178 +
94179 +/**
94180 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
94181 + * @regs: Pointer to dTSEC register block
94182 + *
94183 + * Call this function to obtain a bit-mask of enabled interrupts
94184 + * in dTSEC, taken from IMASK register.
94185 + *
94186 + * Returns: a bit-mask of enabled interrupts in dTSEC.
94187 + */
94188 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
94189 +
94190 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
94191 + uint8_t paddr_num);
94192 +
94193 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
94194 + uint64_t addr,
94195 + uint8_t paddr_num);
94196 +
94197 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
94198 +
94199 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
94200 +
94201 +/**
94202 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
94203 + * @regs: Pointer to dTSEC register block
94204 + * @ev_mask: Mask of relevant events
94205 + *
94206 + * Call this function to disable interrupts in dTSEC for the specified events.
94207 + * To enable interrupts use fman_dtsec_enable_interrupt().
94208 + */
94209 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94210 +
94211 +/**
94212 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
94213 + * @regs: Pointer to dTSEC register block
94214 + * @ev_mask: Mask of relevant events
94215 + *
94216 + * Call this function to enable interrupts in dTSEC for the specified events.
94217 + * To disable interrupts use fman_dtsec_disable_interrupt().
94218 + */
94219 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
94220 +
94221 +/**
94222 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
94223 + * @regs: Pointer to dTSEC register block
94224 + * @en: true to enable timestamps, false to disable them
94225 + *
94226 + * Call this function to enable/disable dTSEC timestamps. This affects both
94227 + * Tx and Rx.
94228 + */
94229 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
94230 +
94231 +/**
94232 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
94233 + * @regs: Pointer to dTSEC register block
94234 + * @bucket: Bucket index
94235 + * @enable: true/false to enable/disable this bucket
94236 + *
94237 + * This function enables or disables the specified bucket. Enabling a bucket
94238 + * associated with an address configures dTSEC to accept received packets
94239 + * with that destination address.
94240 + * Multiple addresses may be associated with the same bucket. Disabling a
94241 + * bucket will affect all addresses associated with that bucket. A bucket that
94242 + * is enabled requires further filtering and verification in the upper layers
94243 + *
94244 + */
94245 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
94246 +
94247 +/**
94248 + * dtsec_set_hash_table() - insert a crc code into thr filter table
94249 + * @regs: Pointer to dTSEC register block
94250 + * @crc: crc to insert
94251 + * @mcast: true is this is a multicast address
94252 + * @ghtx: true if we are in ghtx mode
94253 + *
94254 + * This function inserts a crc code into the filter table.
94255 + */
94256 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
94257 + bool mcast, bool ghtx);
94258 +
94259 +/**
94260 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
94261 + * @regs: Pointer to dTSEC register block
94262 + * @mcast: Reset multicast entries
94263 + * @ucast: Reset unicast entries
94264 + *
94265 + * Resets all entries in L2 address filter table. After calling this function
94266 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
94267 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
94268 + * @ucast argument is ignored.
94269 + * This does not affect the primary nor the 15 additional addresses configured
94270 + * using dtsec_set_address() or dtsec_set_match_address().
94271 + */
94272 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
94273 + bool ucast);
94274 +
94275 +/**
94276 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
94277 + * @regs: Pointer to dTSEC register block
94278 + * @enable: Enable multicast promiscuous mode
94279 + *
94280 + * Call this to enable/disable L2 address filtering for multicast packets.
94281 + */
94282 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
94283 +
94284 +/* statistics APIs */
94285 +
94286 +/**
94287 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
94288 + * @regs: Pointer to dTSEC register block
94289 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
94290 + * to specify all the existing counters.
94291 + * If set to _none_, it disables all the counters.
94292 + *
94293 + * Enables the MIB statistics hw counters and sets up the carry interrupt
94294 + * masks for the counters corresponding to the @level input parameter.
94295 + *
94296 + * Returns: error if invalid @level value given.
94297 + */
94298 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
94299 + enum dtsec_stat_level level);
94300 +
94301 +/**
94302 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
94303 + * @regs: Pointer to dTSEC register block
94304 + */
94305 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
94306 +
94307 +/**
94308 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
94309 + * @regs: Pointer to dTSEC register block
94310 + * @car1: car1 register value
94311 + * @car2: car2 register value
94312 + *
94313 + * When set, the carry bits signal that an overflow occurred on the
94314 + * corresponding counters.
94315 + * Note that the carry bits (CAR1-2 registers) will assert the
94316 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
94317 + *
94318 + * Returns: true if overflow occurred, otherwise - false
94319 + */
94320 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
94321 + uint32_t *car1, uint32_t *car2);
94322 +
94323 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
94324 +
94325 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
94326 + enum dtsec_stat_counters reg_name);
94327 +
94328 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
94329 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
94330 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
94331 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
94332 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
94333 +
94334 +
94335 +#endif /* __FSL_FMAN_DTSEC_H */
94336 --- /dev/null
94337 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
94338 @@ -0,0 +1,107 @@
94339 +/*
94340 + * Copyright 2008-2013 Freescale Semiconductor Inc.
94341 + *
94342 + * Redistribution and use in source and binary forms, with or without
94343 + * modification, are permitted provided that the following conditions are met:
94344 + * * Redistributions of source code must retain the above copyright
94345 + * notice, this list of conditions and the following disclaimer.
94346 + * * Redistributions in binary form must reproduce the above copyright
94347 + * notice, this list of conditions and the following disclaimer in the
94348 + * documentation and/or other materials provided with the distribution.
94349 + * * Neither the name of Freescale Semiconductor nor the
94350 + * names of its contributors may be used to endorse or promote products
94351 + * derived from this software without specific prior written permission.
94352 + *
94353 + *
94354 + * ALTERNATIVELY, this software may be distributed under the terms of the
94355 + * GNU General Public License ("GPL") as published by the Free Software
94356 + * Foundation, either version 2 of that License or (at your option) any
94357 + * later version.
94358 + *
94359 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94360 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94361 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94362 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94363 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94364 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94365 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94366 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94367 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94368 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94369 + */
94370 +
94371 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
94372 +#define __FSL_FMAN_DTSEC_MII_ACC_H
94373 +
94374 +#include "common/general.h"
94375 +
94376 +
94377 +/* MII Management Configuration Register */
94378 +#define MIIMCFG_RESET_MGMT 0x80000000
94379 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
94380 +#define MIIMCFG_MGNTCLK_SHIFT 0
94381 +
94382 +/* MII Management Command Register */
94383 +#define MIIMCOM_SCAN_CYCLE 0x00000002
94384 +#define MIIMCOM_READ_CYCLE 0x00000001
94385 +
94386 +/* MII Management Address Register */
94387 +#define MIIMADD_PHY_ADDR_SHIFT 8
94388 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
94389 +
94390 +#define MIIMADD_REG_ADDR_SHIFT 0
94391 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
94392 +
94393 +/* MII Management Indicator Register */
94394 +#define MIIMIND_BUSY 0x00000001
94395 +
94396 +
94397 +/* PHY Control Register */
94398 +#define PHY_CR_PHY_RESET 0x8000
94399 +#define PHY_CR_LOOPBACK 0x4000
94400 +#define PHY_CR_SPEED0 0x2000
94401 +#define PHY_CR_ANE 0x1000
94402 +#define PHY_CR_RESET_AN 0x0200
94403 +#define PHY_CR_FULLDUPLEX 0x0100
94404 +#define PHY_CR_SPEED1 0x0040
94405 +
94406 +#define PHY_TBICON_SRESET 0x8000
94407 +#define PHY_TBICON_SPEED2 0x0020
94408 +#define PHY_TBICON_CLK_SEL 0x0020
94409 +#define PHY_TBIANA_SGMII 0x4001
94410 +#define PHY_TBIANA_1000X 0x01a0
94411 +/* register map */
94412 +
94413 +/* MII Configuration Control Memory Map Registers */
94414 +struct dtsec_mii_reg {
94415 + uint32_t reserved1[72];
94416 + uint32_t miimcfg; /* MII Mgmt:configuration */
94417 + uint32_t miimcom; /* MII Mgmt:command */
94418 + uint32_t miimadd; /* MII Mgmt:address */
94419 + uint32_t miimcon; /* MII Mgmt:control 3 */
94420 + uint32_t miimstat; /* MII Mgmt:status */
94421 + uint32_t miimind; /* MII Mgmt:indicators */
94422 +};
94423 +
94424 +/* dTSEC MII API */
94425 +
94426 +/* functions to access the mii registers for phy configuration.
94427 + * this functionality may not be available for all dtsecs in the system.
94428 + * consult the reference manual for details */
94429 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
94430 +/* frequency is in MHz.
94431 + * note that dtsec clock is 1/2 of fman clock */
94432 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
94433 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
94434 + uint8_t addr,
94435 + uint8_t reg,
94436 + uint16_t data,
94437 + uint16_t dtsec_freq);
94438 +
94439 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
94440 + uint8_t addr,
94441 + uint8_t reg,
94442 + uint16_t *data,
94443 + uint16_t dtsec_freq);
94444 +
94445 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
94446 --- /dev/null
94447 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
94448 @@ -0,0 +1,514 @@
94449 +/*
94450 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94451 + *
94452 + * Redistribution and use in source and binary forms, with or without
94453 + * modification, are permitted provided that the following conditions are met:
94454 + * * Redistributions of source code must retain the above copyright
94455 + * notice, this list of conditions and the following disclaimer.
94456 + * * Redistributions in binary form must reproduce the above copyright
94457 + * notice, this list of conditions and the following disclaimer in the
94458 + * documentation and/or other materials provided with the distribution.
94459 + * * Neither the name of Freescale Semiconductor nor the
94460 + * names of its contributors may be used to endorse or promote products
94461 + * derived from this software without specific prior written permission.
94462 + *
94463 + *
94464 + * ALTERNATIVELY, this software may be distributed under the terms of the
94465 + * GNU General Public License ("GPL") as published by the Free Software
94466 + * Foundation, either version 2 of that License or (at your option) any
94467 + * later version.
94468 + *
94469 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94470 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94471 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94472 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94473 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94474 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94475 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94476 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94477 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94478 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94479 + */
94480 +
94481 +#ifndef __FSL_FMAN_KG_H
94482 +#define __FSL_FMAN_KG_H
94483 +
94484 +#include "common/general.h"
94485 +
94486 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
94487 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
94488 +/**< Total num of masks allowed on KG extractions */
94489 +#define FM_KG_EXTRACT_MASKS_NUM 4
94490 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
94491 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
94492 +
94493 +struct fman_kg_regs {
94494 + uint32_t fmkg_gcr;
94495 + uint32_t res004;
94496 + uint32_t res008;
94497 + uint32_t fmkg_eer;
94498 + uint32_t fmkg_eeer;
94499 + uint32_t res014;
94500 + uint32_t res018;
94501 + uint32_t fmkg_seer;
94502 + uint32_t fmkg_seeer;
94503 + uint32_t fmkg_gsr;
94504 + uint32_t fmkg_tpc;
94505 + uint32_t fmkg_serc;
94506 + uint32_t res030[4];
94507 + uint32_t fmkg_fdor;
94508 + uint32_t fmkg_gdv0r;
94509 + uint32_t fmkg_gdv1r;
94510 + uint32_t res04c[6];
94511 + uint32_t fmkg_feer;
94512 + uint32_t res068[38];
94513 + uint32_t fmkg_indirect[63];
94514 + uint32_t fmkg_ar;
94515 +};
94516 +
94517 +struct fman_kg_scheme_regs {
94518 + uint32_t kgse_mode; /**< MODE */
94519 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
94520 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
94521 + uint32_t kgse_bmch; /**< Bit Mask Command High */
94522 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
94523 + uint32_t kgse_fqb; /**< Frame Queue Base */
94524 + uint32_t kgse_hc; /**< Hash Command */
94525 + uint32_t kgse_ppc; /**< Policer Profile Command */
94526 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
94527 + /**< Generic Extract Command */
94528 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
94529 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
94530 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
94531 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
94532 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
94533 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
94534 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
94535 +};
94536 +
94537 +struct fman_kg_pe_regs{
94538 + uint32_t fmkg_pe_sp;
94539 + uint32_t fmkg_pe_cpp;
94540 +};
94541 +
94542 +struct fman_kg_cp_regs {
94543 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
94544 +};
94545 +
94546 +
94547 +#define FM_KG_KGAR_GO 0x80000000
94548 +#define FM_KG_KGAR_READ 0x40000000
94549 +#define FM_KG_KGAR_WRITE 0x00000000
94550 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
94551 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
94552 +
94553 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
94554 +#define KG_SCH_PP_NO_GEN 0x10000000
94555 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
94556 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
94557 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94558 +#define KG_SCH_BITMASK_MASK 0x000000FF
94559 +#define KG_SCH_GEN_VALID 0x80000000
94560 +#define KG_SCH_GEN_MASK 0x00FF0000
94561 +#define FM_PCD_KG_KGAR_ERR 0x20000000
94562 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
94563 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
94564 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
94565 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
94566 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
94567 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
94568 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
94569 +
94570 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
94571 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
94572 +
94573 +/* ECC capture register */
94574 +#define KG_FMKG_SERC_CAP 0x80000000
94575 +#define KG_FMKG_SERC_CET 0x40000000
94576 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
94577 +#define KG_FMKG_SERC_CNT_SHIFT 16
94578 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
94579 +
94580 +/* Masks */
94581 +#define FM_KG_KGGCR_EN 0x80000000
94582 +#define KG_SCH_GEN_VALID 0x80000000
94583 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
94584 +#define KG_ERR_TYPE_DOUBLE 0x40000000
94585 +#define KG_ERR_ADDR_MASK 0x00000FFF
94586 +#define KG_SCH_MODE_EN 0x80000000
94587 +
94588 +/* shifts */
94589 +#define FM_KG_KGAR_NUM_SHIFT 16
94590 +#define FM_KG_PE_CPP_MASK_SHIFT 16
94591 +#define FM_KG_KGAR_WSEL_SHIFT 8
94592 +
94593 +#define FM_KG_SCH_GEN_HT_INVALID 0
94594 +
94595 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
94596 +
94597 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
94598 +switch (i) \
94599 +{ \
94600 + case 0: (shift) = 26; break; \
94601 + case 1: (shift) = 20; break; \
94602 + case 2: (shift) = 10; break; \
94603 + case 3: (shift) = 4; break; \
94604 + default: (shift) = 0; \
94605 +}
94606 +
94607 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
94608 +switch (i) \
94609 +{ \
94610 + case 0: (shift) = 16; break; \
94611 + case 1: (shift) = 0; break; \
94612 + case 2: (shift) = 28; break; \
94613 + case 3: (shift) = 24; break; \
94614 + default: (shift) = 0; \
94615 +}
94616 +
94617 +#define KG_GET_MASK_SHIFT(shift, i) \
94618 +switch (i) \
94619 +{ \
94620 + case 0: shift = 24; break; \
94621 + case 1: shift = 16; break; \
94622 + case 2: shift = 8; break; \
94623 + case 3: shift = 0; break; \
94624 + default: shift = 0; \
94625 +}
94626 +
94627 +/* Port entry CPP register */
94628 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
94629 +
94630 +/* Scheme registers */
94631 +#define FMAN_KG_SCH_MODE_EN 0x80000000
94632 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
94633 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
94634 +
94635 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
94636 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
94637 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
94638 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
94639 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
94640 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
94641 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
94642 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
94643 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
94644 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
94645 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
94646 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
94647 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
94648 +
94649 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
94650 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
94651 +#define FMAN_KG_SCH_GEN_OR 0x00008000
94652 +
94653 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
94654 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
94655 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
94656 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
94657 +
94658 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
94659 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
94660 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
94661 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
94662 +
94663 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
94664 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
94665 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
94666 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
94667 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
94668 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
94669 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
94670 +
94671 +enum fman_kg_gen_extract_src {
94672 + E_FMAN_KG_GEN_EXTRACT_ETH,
94673 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
94674 + E_FMAN_KG_GEN_EXTRACT_SNAP,
94675 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
94676 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
94677 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
94678 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
94679 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
94680 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
94681 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
94682 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
94683 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
94684 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
94685 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
94686 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
94687 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
94688 + E_FMAN_KG_GEN_EXTRACT_GRE,
94689 + E_FMAN_KG_GEN_EXTRACT_TCP,
94690 + E_FMAN_KG_GEN_EXTRACT_UDP,
94691 + E_FMAN_KG_GEN_EXTRACT_SCTP,
94692 + E_FMAN_KG_GEN_EXTRACT_DCCP,
94693 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
94694 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
94695 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
94696 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
94697 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
94698 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
94699 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
94700 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
94701 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
94702 +};
94703 +
94704 +struct fman_kg_ex_ecc_attr
94705 +{
94706 + bool valid;
94707 + bool double_ecc;
94708 + uint16_t addr;
94709 + uint8_t single_ecc_count;
94710 +};
94711 +
94712 +enum fman_kg_def_select
94713 +{
94714 + E_FMAN_KG_DEF_GLOBAL_0,
94715 + E_FMAN_KG_DEF_GLOBAL_1,
94716 + E_FMAN_KG_DEF_SCHEME_0,
94717 + E_FMAN_KG_DEF_SCHEME_1
94718 +};
94719 +
94720 +struct fman_kg_extract_def
94721 +{
94722 + enum fman_kg_def_select mac_addr;
94723 + enum fman_kg_def_select vlan_tci;
94724 + enum fman_kg_def_select etype;
94725 + enum fman_kg_def_select ppp_sid;
94726 + enum fman_kg_def_select ppp_pid;
94727 + enum fman_kg_def_select mpls;
94728 + enum fman_kg_def_select ip_addr;
94729 + enum fman_kg_def_select ptype;
94730 + enum fman_kg_def_select ip_tos_tc;
94731 + enum fman_kg_def_select ipv6_fl;
94732 + enum fman_kg_def_select ipsec_spi;
94733 + enum fman_kg_def_select l4_port;
94734 + enum fman_kg_def_select tcp_flg;
94735 +};
94736 +
94737 +enum fman_kg_gen_extract_type
94738 +{
94739 + E_FMAN_KG_HASH_EXTRACT,
94740 + E_FMAN_KG_OR_EXTRACT
94741 +};
94742 +
94743 +struct fman_kg_gen_extract_params
94744 +{
94745 + /* Hash or Or-ed extract */
94746 + enum fman_kg_gen_extract_type type;
94747 + enum fman_kg_gen_extract_src src;
94748 + bool no_validation;
94749 + /* Extraction offset from the header location specified above */
94750 + uint8_t offset;
94751 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
94752 + * hash result shift for FMAN_KG_OR_EXTRACT */
94753 + uint8_t extract;
94754 + uint8_t mask;
94755 + /* Default value to use when header specified
94756 + * by fman_kg_gen_extract_src doesn't present */
94757 + enum fman_kg_def_select def_val;
94758 +};
94759 +
94760 +struct fman_kg_extract_mask
94761 +{
94762 + /**< Indication if mask is on known field extraction or
94763 + * on general extraction; TRUE for known field */
94764 + bool is_known;
94765 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
94766 + * generic register index for generic extracts mask */
94767 + uint32_t field_or_gen_idx;
94768 + /**< Byte offset from start of the extracted data specified
94769 + * by field_or_gen_idx */
94770 + uint8_t offset;
94771 + /**< Byte mask (selected bits will be used) */
94772 + uint8_t mask;
94773 +};
94774 +
94775 +struct fman_kg_extract_params
94776 +{
94777 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
94778 + uint32_t known_fields;
94779 + struct fman_kg_extract_def known_fields_def;
94780 + /* Number of entries in gen_extract */
94781 + uint8_t gen_extract_num;
94782 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
94783 + /* Number of entries in masks */
94784 + uint8_t masks_num;
94785 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
94786 + uint32_t def_scheme_0;
94787 + uint32_t def_scheme_1;
94788 +};
94789 +
94790 +struct fman_kg_hash_params
94791 +{
94792 + bool use_hash;
94793 + uint8_t shift_r;
94794 + uint32_t mask; /**< 24-bit mask */
94795 + bool sym; /**< Symmetric hash for src and dest pairs */
94796 +};
94797 +
94798 +struct fman_kg_pp_params
94799 +{
94800 + uint8_t base;
94801 + uint8_t shift;
94802 + uint8_t mask;
94803 + bool bypass_pp_gen;
94804 +};
94805 +
94806 +struct fman_kg_cc_params
94807 +{
94808 + uint8_t base_offset;
94809 + uint32_t qlcv_bits_sel;
94810 +};
94811 +
94812 +enum fman_pcd_engine
94813 +{
94814 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
94815 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
94816 + E_FMAN_PCD_KG, /**< Keygen indicated */
94817 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
94818 + E_FMAN_PCD_PLCR, /**< Policer indicated */
94819 + E_FMAN_PCD_PRS /**< Parser indicated */
94820 +};
94821 +
94822 +struct fman_kg_cls_plan_params
94823 +{
94824 + uint8_t entries_mask;
94825 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
94826 +};
94827 +
94828 +struct fman_kg_scheme_params
94829 +{
94830 + uint32_t match_vector;
94831 + struct fman_kg_extract_params extract_params;
94832 + struct fman_kg_hash_params hash_params;
94833 + uint32_t base_fqid;
94834 + /* What we do w/features supported per FM version ?? */
94835 + bool bypass_fqid_gen;
94836 + struct fman_kg_pp_params policer_params;
94837 + struct fman_kg_cc_params cc_params;
94838 + bool update_counter;
94839 + /**< counter_value: Set scheme counter to the specified value;
94840 + * relevant only when update_counter = TRUE. */
94841 + uint32_t counter_value;
94842 + enum fman_pcd_engine next_engine;
94843 + /**< Next engine action code */
94844 + uint32_t next_engine_action;
94845 +};
94846 +
94847 +
94848 +
94849 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
94850 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
94851 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
94852 +void fman_kg_get_event(struct fman_kg_regs *regs,
94853 + uint32_t *event,
94854 + uint32_t *scheme_idx);
94855 +void fman_kg_init(struct fman_kg_regs *regs,
94856 + uint32_t exceptions,
94857 + uint32_t dflt_nia);
94858 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
94859 +void fman_kg_enable(struct fman_kg_regs *regs);
94860 +void fman_kg_disable(struct fman_kg_regs *regs);
94861 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
94862 + uint8_t hwport_id,
94863 + uint32_t bind_cls_plans);
94864 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
94865 + uint8_t grp_mask,
94866 + uint32_t *bind_cls_plans);
94867 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
94868 + uint8_t hwport_id,
94869 + uint32_t schemes);
94870 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
94871 + uint8_t grp_id,
94872 + uint8_t entries_mask,
94873 + uint8_t hwport_id,
94874 + struct fman_kg_cp_regs *cls_plan_regs);
94875 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
94876 + struct fman_kg_cp_regs *cls_plan_regs);
94877 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
94878 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
94879 + uint8_t scheme_id,
94880 + uint8_t hwport_id,
94881 + uint32_t counter);
94882 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
94883 + uint8_t scheme_id,
94884 + uint8_t hwport_id,
94885 + uint32_t *counter);
94886 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
94887 + uint8_t scheme_id,
94888 + uint8_t hwport_id);
94889 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
94890 + uint8_t scheme_id,
94891 + uint8_t hwport_id,
94892 + struct fman_kg_scheme_regs *scheme_regs,
94893 + bool update_counter);
94894 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
94895 + struct fman_kg_scheme_regs *scheme_regs);
94896 +void fman_kg_get_capture(struct fman_kg_regs *regs,
94897 + struct fman_kg_ex_ecc_attr *ecc_attr,
94898 + bool clear);
94899 +void fman_kg_get_exception(struct fman_kg_regs *regs,
94900 + uint32_t *events,
94901 + uint32_t *scheme_ids,
94902 + bool clear);
94903 +void fman_kg_set_exception(struct fman_kg_regs *regs,
94904 + uint32_t exception,
94905 + bool enable);
94906 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
94907 + uint8_t def_id,
94908 + uint32_t val);
94909 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
94910 +
94911 +
94912 +
94913 +/**************************************************************************//**
94914 + @Description NIA Description
94915 +*//***************************************************************************/
94916 +#define KG_NIA_ORDER_RESTOR 0x00800000
94917 +#define KG_NIA_ENG_FM_CTL 0x00000000
94918 +#define KG_NIA_ENG_PRS 0x00440000
94919 +#define KG_NIA_ENG_KG 0x00480000
94920 +#define KG_NIA_ENG_PLCR 0x004C0000
94921 +#define KG_NIA_ENG_BMI 0x00500000
94922 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
94923 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
94924 +#define KG_NIA_ENG_MASK 0x007C0000
94925 +
94926 +#define KG_NIA_AC_MASK 0x0003FFFF
94927 +
94928 +#define KG_NIA_INVALID 0xFFFFFFFF
94929 +
94930 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
94931 + uint32_t next_engine_action)
94932 +{
94933 + uint32_t nia;
94934 +
94935 + if (next_engine_action & ~KG_NIA_AC_MASK)
94936 + return KG_NIA_INVALID;
94937 +
94938 + switch (next_engine) {
94939 + case E_FMAN_PCD_DONE:
94940 + nia = KG_NIA_ENG_BMI | next_engine_action;
94941 + break;
94942 +
94943 + case E_FMAN_PCD_KG:
94944 + nia = KG_NIA_ENG_KG | next_engine_action;
94945 + break;
94946 +
94947 + case E_FMAN_PCD_CC:
94948 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
94949 + break;
94950 +
94951 + case E_FMAN_PCD_PLCR:
94952 + nia = KG_NIA_ENG_PLCR | next_engine_action;
94953 + break;
94954 +
94955 + default:
94956 + nia = KG_NIA_INVALID;
94957 + }
94958 +
94959 + return nia;
94960 +}
94961 +
94962 +#endif /* __FSL_FMAN_KG_H */
94963 --- /dev/null
94964 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
94965 @@ -0,0 +1,434 @@
94966 +/*
94967 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94968 + *
94969 + * Redistribution and use in source and binary forms, with or without
94970 + * modification, are permitted provided that the following conditions are met:
94971 + * * Redistributions of source code must retain the above copyright
94972 + * notice, this list of conditions and the following disclaimer.
94973 + * * Redistributions in binary form must reproduce the above copyright
94974 + * notice, this list of conditions and the following disclaimer in the
94975 + * documentation and/or other materials provided with the distribution.
94976 + * * Neither the name of Freescale Semiconductor nor the
94977 + * names of its contributors may be used to endorse or promote products
94978 + * derived from this software without specific prior written permission.
94979 + *
94980 + *
94981 + * ALTERNATIVELY, this software may be distributed under the terms of the
94982 + * GNU General Public License ("GPL") as published by the Free Software
94983 + * Foundation, either version 2 of that License or (at your option) any
94984 + * later version.
94985 + *
94986 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94987 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94988 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94989 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94990 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94991 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94992 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94993 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94994 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94995 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94996 + */
94997 +
94998 +
94999 +#ifndef __FSL_FMAN_MEMAC_H
95000 +#define __FSL_FMAN_MEMAC_H
95001 +
95002 +#include "common/general.h"
95003 +#include "fsl_enet.h"
95004 +
95005 +
95006 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
95007 +
95008 +/* Control and Configuration Register (COMMAND_CONFIG) */
95009 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
95010 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
95011 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
95012 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
95013 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
95014 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
95015 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
95016 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
95017 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
95018 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
95019 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
95020 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
95021 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
95022 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
95023 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
95024 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
95025 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
95026 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
95027 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
95028 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
95029 +
95030 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
95031 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
95032 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
95033 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
95034 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
95035 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
95036 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
95037 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
95038 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
95039 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
95040 +
95041 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
95042 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95043 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95044 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
95045 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
95046 +
95047 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
95048 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
95049 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
95050 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
95051 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
95052 +
95053 +/* Interface Mode Register (IF_MODE) */
95054 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
95055 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
95056 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
95057 +#define IF_MODE_RGMII 0x00000004
95058 +#define IF_MODE_RGMII_AUTO 0x00008000
95059 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
95060 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
95061 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
95062 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
95063 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
95064 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
95065 +
95066 +/* Hash table Control Register (HASHTABLE_CTRL) */
95067 +#define HASH_CTRL_MCAST_SHIFT 26
95068 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
95069 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
95070 +
95071 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
95072 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
95073 +
95074 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
95075 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
95076 +
95077 +/* Statistics Configuration Register (STATN_CONFIG) */
95078 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
95079 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
95080 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
95081 +
95082 +/* Interrupt Mask Register (IMASK) */
95083 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
95084 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
95085 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
95086 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
95087 +
95088 +#define MEMAC_ALL_ERRS_IMASK \
95089 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
95090 + MEMAC_IMASK_TECC_ER | \
95091 + MEMAC_IMASK_RECC_ER | \
95092 + MEMAC_IMASK_MGI))
95093 +
95094 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
95095 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
95096 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
95097 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
95098 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
95099 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
95100 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
95101 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
95102 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
95103 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
95104 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
95105 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
95106 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
95107 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
95108 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
95109 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
95110 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
95111 +
95112 +enum memac_counters {
95113 + E_MEMAC_COUNTER_R64,
95114 + E_MEMAC_COUNTER_T64,
95115 + E_MEMAC_COUNTER_R127,
95116 + E_MEMAC_COUNTER_T127,
95117 + E_MEMAC_COUNTER_R255,
95118 + E_MEMAC_COUNTER_T255,
95119 + E_MEMAC_COUNTER_R511,
95120 + E_MEMAC_COUNTER_T511,
95121 + E_MEMAC_COUNTER_R1023,
95122 + E_MEMAC_COUNTER_T1023,
95123 + E_MEMAC_COUNTER_R1518,
95124 + E_MEMAC_COUNTER_T1518,
95125 + E_MEMAC_COUNTER_R1519X,
95126 + E_MEMAC_COUNTER_T1519X,
95127 + E_MEMAC_COUNTER_RFRG,
95128 + E_MEMAC_COUNTER_RJBR,
95129 + E_MEMAC_COUNTER_RDRP,
95130 + E_MEMAC_COUNTER_RALN,
95131 + E_MEMAC_COUNTER_TUND,
95132 + E_MEMAC_COUNTER_ROVR,
95133 + E_MEMAC_COUNTER_RXPF,
95134 + E_MEMAC_COUNTER_TXPF,
95135 + E_MEMAC_COUNTER_ROCT,
95136 + E_MEMAC_COUNTER_RMCA,
95137 + E_MEMAC_COUNTER_RBCA,
95138 + E_MEMAC_COUNTER_RPKT,
95139 + E_MEMAC_COUNTER_RUCA,
95140 + E_MEMAC_COUNTER_RERR,
95141 + E_MEMAC_COUNTER_TOCT,
95142 + E_MEMAC_COUNTER_TMCA,
95143 + E_MEMAC_COUNTER_TBCA,
95144 + E_MEMAC_COUNTER_TUCA,
95145 + E_MEMAC_COUNTER_TERR
95146 +};
95147 +
95148 +#define DEFAULT_PAUSE_QUANTA 0xf000
95149 +#define DEFAULT_FRAME_LENGTH 0x600
95150 +#define DEFAULT_TX_IPG_LENGTH 12
95151 +
95152 +/*
95153 + * memory map
95154 + */
95155 +
95156 +struct mac_addr {
95157 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
95158 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
95159 +};
95160 +
95161 +struct memac_regs {
95162 + /* General Control and Status */
95163 + uint32_t res0000[2];
95164 + uint32_t command_config; /* 0x008 Ctrl and cfg */
95165 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
95166 + uint32_t maxfrm; /* 0x014 Max frame length */
95167 + uint32_t res0018[1];
95168 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
95169 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
95170 + uint32_t res0024[2];
95171 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
95172 + uint32_t res0030[4];
95173 + uint32_t ievent; /* 0x040 Interrupt event */
95174 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
95175 + uint32_t res0048;
95176 + uint32_t imask; /* 0x04C Interrupt mask */
95177 + uint32_t res0050;
95178 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
95179 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
95180 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
95181 + uint32_t res0078[2];
95182 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
95183 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
95184 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
95185 + uint32_t res00c0[8];
95186 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
95187 + uint32_t res00e4[7];
95188 + /* Rx Statistics Counter */
95189 + uint32_t reoct_l;
95190 + uint32_t reoct_u;
95191 + uint32_t roct_l;
95192 + uint32_t roct_u;
95193 + uint32_t raln_l;
95194 + uint32_t raln_u;
95195 + uint32_t rxpf_l;
95196 + uint32_t rxpf_u;
95197 + uint32_t rfrm_l;
95198 + uint32_t rfrm_u;
95199 + uint32_t rfcs_l;
95200 + uint32_t rfcs_u;
95201 + uint32_t rvlan_l;
95202 + uint32_t rvlan_u;
95203 + uint32_t rerr_l;
95204 + uint32_t rerr_u;
95205 + uint32_t ruca_l;
95206 + uint32_t ruca_u;
95207 + uint32_t rmca_l;
95208 + uint32_t rmca_u;
95209 + uint32_t rbca_l;
95210 + uint32_t rbca_u;
95211 + uint32_t rdrp_l;
95212 + uint32_t rdrp_u;
95213 + uint32_t rpkt_l;
95214 + uint32_t rpkt_u;
95215 + uint32_t rund_l;
95216 + uint32_t rund_u;
95217 + uint32_t r64_l;
95218 + uint32_t r64_u;
95219 + uint32_t r127_l;
95220 + uint32_t r127_u;
95221 + uint32_t r255_l;
95222 + uint32_t r255_u;
95223 + uint32_t r511_l;
95224 + uint32_t r511_u;
95225 + uint32_t r1023_l;
95226 + uint32_t r1023_u;
95227 + uint32_t r1518_l;
95228 + uint32_t r1518_u;
95229 + uint32_t r1519x_l;
95230 + uint32_t r1519x_u;
95231 + uint32_t rovr_l;
95232 + uint32_t rovr_u;
95233 + uint32_t rjbr_l;
95234 + uint32_t rjbr_u;
95235 + uint32_t rfrg_l;
95236 + uint32_t rfrg_u;
95237 + uint32_t rcnp_l;
95238 + uint32_t rcnp_u;
95239 + uint32_t rdrntp_l;
95240 + uint32_t rdrntp_u;
95241 + uint32_t res01d0[12];
95242 + /* Tx Statistics Counter */
95243 + uint32_t teoct_l;
95244 + uint32_t teoct_u;
95245 + uint32_t toct_l;
95246 + uint32_t toct_u;
95247 + uint32_t res0210[2];
95248 + uint32_t txpf_l;
95249 + uint32_t txpf_u;
95250 + uint32_t tfrm_l;
95251 + uint32_t tfrm_u;
95252 + uint32_t tfcs_l;
95253 + uint32_t tfcs_u;
95254 + uint32_t tvlan_l;
95255 + uint32_t tvlan_u;
95256 + uint32_t terr_l;
95257 + uint32_t terr_u;
95258 + uint32_t tuca_l;
95259 + uint32_t tuca_u;
95260 + uint32_t tmca_l;
95261 + uint32_t tmca_u;
95262 + uint32_t tbca_l;
95263 + uint32_t tbca_u;
95264 + uint32_t res0258[2];
95265 + uint32_t tpkt_l;
95266 + uint32_t tpkt_u;
95267 + uint32_t tund_l;
95268 + uint32_t tund_u;
95269 + uint32_t t64_l;
95270 + uint32_t t64_u;
95271 + uint32_t t127_l;
95272 + uint32_t t127_u;
95273 + uint32_t t255_l;
95274 + uint32_t t255_u;
95275 + uint32_t t511_l;
95276 + uint32_t t511_u;
95277 + uint32_t t1023_l;
95278 + uint32_t t1023_u;
95279 + uint32_t t1518_l;
95280 + uint32_t t1518_u;
95281 + uint32_t t1519x_l;
95282 + uint32_t t1519x_u;
95283 + uint32_t res02a8[6];
95284 + uint32_t tcnp_l;
95285 + uint32_t tcnp_u;
95286 + uint32_t res02c8[14];
95287 + /* Line Interface Control */
95288 + uint32_t if_mode; /* 0x300 Interface Mode Control */
95289 + uint32_t if_status; /* 0x304 Interface Status */
95290 + uint32_t res0308[14];
95291 + /* HiGig/2 */
95292 + uint32_t hg_config; /* 0x340 Control and cfg */
95293 + uint32_t res0344[3];
95294 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
95295 + uint32_t res0354[3];
95296 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
95297 + uint32_t res0364[3];
95298 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
95299 + uint32_t hg_fifos_status; /* 0x374 fifos status */
95300 + uint32_t rhm; /* 0x378 rx messages counter */
95301 + uint32_t thm; /* 0x37C tx messages counter */
95302 +};
95303 +
95304 +struct memac_cfg {
95305 + bool reset_on_init;
95306 + bool rx_error_discard;
95307 + bool pause_ignore;
95308 + bool pause_forward_enable;
95309 + bool no_length_check_enable;
95310 + bool cmd_frame_enable;
95311 + bool send_idle_enable;
95312 + bool wan_mode_enable;
95313 + bool promiscuous_mode_enable;
95314 + bool tx_addr_ins_enable;
95315 + bool loopback_enable;
95316 + bool lgth_check_nostdr;
95317 + bool time_stamp_enable;
95318 + bool pad_enable;
95319 + bool phy_tx_ena_on;
95320 + bool rx_sfd_any;
95321 + bool rx_pbl_fwd;
95322 + bool tx_pbl_fwd;
95323 + bool debug_mode;
95324 + bool wake_on_lan;
95325 + uint16_t max_frame_length;
95326 + uint16_t pause_quanta;
95327 + uint32_t tx_ipg_length;
95328 +};
95329 +
95330 +
95331 +/**
95332 + * fman_memac_defconfig() - Get default MEMAC configuration
95333 + * @cfg: pointer to configuration structure.
95334 + *
95335 + * Call this function to obtain a default set of configuration values for
95336 + * initializing MEMAC. The user can overwrite any of the values before calling
95337 + * fman_memac_init(), if specific configuration needs to be applied.
95338 + */
95339 +void fman_memac_defconfig(struct memac_cfg *cfg);
95340 +
95341 +int fman_memac_init(struct memac_regs *regs,
95342 + struct memac_cfg *cfg,
95343 + enum enet_interface enet_interface,
95344 + enum enet_speed enet_speed,
95345 + bool slow_10g_if,
95346 + uint32_t exceptions);
95347 +
95348 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95349 +
95350 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
95351 +
95352 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
95353 +
95354 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
95355 + uint8_t *adr,
95356 + uint8_t paddr_num);
95357 +
95358 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
95359 + uint8_t paddr_num);
95360 +
95361 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
95362 + enum memac_counters reg_name);
95363 +
95364 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
95365 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
95366 +
95367 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
95368 +
95369 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
95370 + bool enable);
95371 +
95372 +void fman_memac_reset_stat(struct memac_regs *regs);
95373 +
95374 +void fman_memac_reset(struct memac_regs *regs);
95375 +
95376 +void fman_memac_reset_filter_table(struct memac_regs *regs);
95377 +
95378 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
95379 +
95380 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
95381 +
95382 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
95383 + bool enable);
95384 +
95385 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
95386 +
95387 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
95388 +
95389 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
95390 +
95391 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
95392 +
95393 +void fman_memac_adjust_link(struct memac_regs *regs,
95394 + enum enet_interface iface_mode,
95395 + enum enet_speed speed, bool full_dx);
95396 +
95397 +
95398 +
95399 +#endif /*__FSL_FMAN_MEMAC_H*/
95400 --- /dev/null
95401 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
95402 @@ -0,0 +1,78 @@
95403 +/*
95404 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95405 + *
95406 + * Redistribution and use in source and binary forms, with or without
95407 + * modification, are permitted provided that the following conditions are met:
95408 + * * Redistributions of source code must retain the above copyright
95409 + * notice, this list of conditions and the following disclaimer.
95410 + * * Redistributions in binary form must reproduce the above copyright
95411 + * notice, this list of conditions and the following disclaimer in the
95412 + * documentation and/or other materials provided with the distribution.
95413 + * * Neither the name of Freescale Semiconductor nor the
95414 + * names of its contributors may be used to endorse or promote products
95415 + * derived from this software without specific prior written permission.
95416 + *
95417 + *
95418 + * ALTERNATIVELY, this software may be distributed under the terms of the
95419 + * GNU General Public License ("GPL") as published by the Free Software
95420 + * Foundation, either version 2 of that License or (at your option) any
95421 + * later version.
95422 + *
95423 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95424 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95425 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95426 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95427 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95428 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95429 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95430 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95431 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95432 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95433 + */
95434 +
95435 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
95436 +#define __FSL_FMAN_MEMAC_MII_ACC_H
95437 +
95438 +#include "common/general.h"
95439 +#include "fsl_enet.h"
95440 +/* MII Management Registers */
95441 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
95442 +#define MDIO_CFG_CLK_DIV_SHIFT 7
95443 +#define MDIO_CFG_HOLD_MASK 0x0000001c
95444 +#define MDIO_CFG_ENC45 0x00000040
95445 +#define MDIO_CFG_READ_ERR 0x00000002
95446 +#define MDIO_CFG_BSY 0x00000001
95447 +
95448 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
95449 +#define MDIO_CTL_READ 0x00008000
95450 +
95451 +#define MDIO_DATA_BSY 0x80000000
95452 +
95453 +/*MEMAC Internal PHY Registers - SGMII */
95454 +#define PHY_SGMII_CR_PHY_RESET 0x8000
95455 +#define PHY_SGMII_CR_RESET_AN 0x0200
95456 +#define PHY_SGMII_CR_DEF_VAL 0x1140
95457 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
95458 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
95459 +#define PHY_SGMII_IF_MODE_AN 0x0002
95460 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
95461 +#define PHY_SGMII_IF_MODE_1000X 0x0000
95462 +
95463 +/*----------------------------------------------------*/
95464 +/* MII Configuration Control Memory Map Registers */
95465 +/*----------------------------------------------------*/
95466 +struct memac_mii_access_mem_map {
95467 + uint32_t mdio_cfg; /* 0x030 */
95468 + uint32_t mdio_ctrl; /* 0x034 */
95469 + uint32_t mdio_data; /* 0x038 */
95470 + uint32_t mdio_addr; /* 0x03c */
95471 +};
95472 +
95473 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95474 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
95475 + enum enet_speed enet_speed);
95476 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
95477 + uint8_t phy_addr, uint8_t reg, uint16_t data,
95478 + enum enet_speed enet_speed);
95479 +
95480 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
95481 --- /dev/null
95482 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
95483 @@ -0,0 +1,593 @@
95484 +/*
95485 + * Copyright 2008-2013 Freescale Semiconductor Inc.
95486 + *
95487 + * Redistribution and use in source and binary forms, with or without
95488 + * modification, are permitted provided that the following conditions are met:
95489 + * * Redistributions of source code must retain the above copyright
95490 + * notice, this list of conditions and the following disclaimer.
95491 + * * Redistributions in binary form must reproduce the above copyright
95492 + * notice, this list of conditions and the following disclaimer in the
95493 + * documentation and/or other materials provided with the distribution.
95494 + * * Neither the name of Freescale Semiconductor nor the
95495 + * names of its contributors may be used to endorse or promote products
95496 + * derived from this software without specific prior written permission.
95497 + *
95498 + *
95499 + * ALTERNATIVELY, this software may be distributed under the terms of the
95500 + * GNU General Public License ("GPL") as published by the Free Software
95501 + * Foundation, either version 2 of that License or (at your option) any
95502 + * later version.
95503 + *
95504 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
95505 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
95506 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
95507 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
95508 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
95509 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
95510 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
95511 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
95512 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
95513 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
95514 + */
95515 +
95516 +#ifndef __FSL_FMAN_PORT_H
95517 +#define __FSL_FMAN_PORT_H
95518 +
95519 +#include "fsl_fman_sp.h"
95520 +
95521 +/** @Collection Registers bit fields */
95522 +
95523 +/** @Description BMI defines */
95524 +#define BMI_EBD_EN 0x80000000
95525 +
95526 +#define BMI_PORT_CFG_EN 0x80000000
95527 +#define BMI_PORT_CFG_FDOVR 0x02000000
95528 +#define BMI_PORT_CFG_IM 0x01000000
95529 +
95530 +#define BMI_PORT_STATUS_BSY 0x80000000
95531 +
95532 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
95533 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
95534 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
95535 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
95536 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
95537 +
95538 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
95539 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
95540 +
95541 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
95542 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
95543 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
95544 +
95545 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
95546 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
95547 +
95548 +#define BMI_INT_BUF_MARG_SHIFT 28
95549 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
95550 +
95551 +#define BMI_CMD_MR_LEAC 0x00200000
95552 +#define BMI_CMD_MR_SLEAC 0x00100000
95553 +#define BMI_CMD_MR_MA 0x00080000
95554 +#define BMI_CMD_MR_DEAS 0x00040000
95555 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
95556 + BMI_CMD_MR_SLEAC | \
95557 + BMI_CMD_MR_MA | \
95558 + BMI_CMD_MR_DEAS)
95559 +#define BMI_CMD_TX_MR_DEF 0
95560 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
95561 + BMI_CMD_MR_MA)
95562 +
95563 +#define BMI_CMD_ATTR_ORDER 0x80000000
95564 +#define BMI_CMD_ATTR_SYNC 0x02000000
95565 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
95566 +
95567 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
95568 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
95569 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
95570 +
95571 +#define BMI_COUNTERS_EN 0x80000000
95572 +
95573 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
95574 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
95575 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
95576 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
95577 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
95578 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
95579 +
95580 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
95581 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
95582 +
95583 +#define MAX_PERFORMANCE_TASK_COMP 64
95584 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
95585 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
95586 +#define MAX_PERFORMANCE_DMA_COMP 16
95587 +#define MAX_PERFORMANCE_FIFO_COMP 1024
95588 +
95589 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
95590 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
95591 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
95592 +
95593 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
95594 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
95595 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
95596 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
95597 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
95598 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
95599 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
95600 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
95601 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
95602 +
95603 +/** @Description QMI defines */
95604 +#define QMI_PORT_CFG_EN 0x80000000
95605 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
95606 +
95607 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
95608 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
95609 +
95610 +#define QMI_DEQ_CFG_PRI 0x80000000
95611 +#define QMI_DEQ_CFG_TYPE1 0x10000000
95612 +#define QMI_DEQ_CFG_TYPE2 0x20000000
95613 +#define QMI_DEQ_CFG_TYPE3 0x30000000
95614 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
95615 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
95616 +#define QMI_DEQ_CFG_SP_MASK 0xf
95617 +#define QMI_DEQ_CFG_SP_SHIFT 20
95618 +
95619 +
95620 +/** @Description General port defines */
95621 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
95622 + (((fm_rev_maj) == 4) ? 4 : 8)
95623 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
95624 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
95625 +#define FMAN_PORT_CG_MAP_NUM 8
95626 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
95627 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
95628 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
95629 +
95630 +
95631 +/** @Collection FM Port Register Map */
95632 +
95633 +/** @Description BMI Rx port register map */
95634 +struct fman_port_rx_bmi_regs {
95635 + uint32_t fmbm_rcfg; /**< Rx Configuration */
95636 + uint32_t fmbm_rst; /**< Rx Status */
95637 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
95638 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
95639 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
95640 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
95641 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
95642 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
95643 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
95644 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
95645 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
95646 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
95647 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
95648 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
95649 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
95650 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
95651 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95652 + /**< Rx Parse Results Array Init*/
95653 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
95654 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
95655 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
95656 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
95657 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
95658 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
95659 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
95660 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
95661 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
95662 + /**< Buffer Manager pool Information-*/
95663 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
95664 + /**< Allocate Counter-*/
95665 + uint32_t reserved0130[8];
95666 + /**< 0x130/0x140 - 0x15F reserved -*/
95667 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
95668 + /**< Congestion Group Map*/
95669 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
95670 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
95671 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
95672 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
95673 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
95674 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
95675 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
95676 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
95677 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
95678 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
95679 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
95680 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
95681 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
95682 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
95683 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
95684 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
95685 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
95686 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
95687 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
95688 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
95689 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
95690 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
95691 +};
95692 +
95693 +/** @Description BMI Tx port register map */
95694 +struct fman_port_tx_bmi_regs {
95695 + uint32_t fmbm_tcfg; /**< Tx Configuration */
95696 + uint32_t fmbm_tst; /**< Tx Status */
95697 + uint32_t fmbm_tda; /**< Tx DMA attributes */
95698 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
95699 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
95700 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
95701 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
95702 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
95703 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
95704 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
95705 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
95706 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
95707 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
95708 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
95709 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
95710 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
95711 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
95712 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
95713 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
95714 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
95715 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
95716 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
95717 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
95718 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
95719 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
95720 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
95721 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
95722 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
95723 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
95724 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
95725 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
95726 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
95727 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
95728 +};
95729 +
95730 +/** @Description BMI O/H port register map */
95731 +struct fman_port_oh_bmi_regs {
95732 + uint32_t fmbm_ocfg; /**< O/H Configuration */
95733 + uint32_t fmbm_ost; /**< O/H Status */
95734 + uint32_t fmbm_oda; /**< O/H DMA attributes */
95735 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
95736 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
95737 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
95738 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
95739 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
95740 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
95741 + uint32_t fmbm_opp; /**< O/H Policer Profile */
95742 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
95743 + uint32_t fmbm_oim; /**< O/H Internal margins*/
95744 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
95745 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
95746 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
95747 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
95748 + /**< O/H Parse Results Array Initialization */
95749 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
95750 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
95751 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
95752 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
95753 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
95754 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
95755 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
95756 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
95757 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
95758 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
95759 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
95760 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
95761 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
95762 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
95763 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
95764 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
95765 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
95766 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
95767 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
95768 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
95769 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
95770 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
95771 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
95772 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
95773 + uint32_t fmbm_opc; /**< O/H Performance Counters */
95774 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
95775 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
95776 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
95777 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
95778 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
95779 +};
95780 +
95781 +/** @Description BMI port register map */
95782 +union fman_port_bmi_regs {
95783 + struct fman_port_rx_bmi_regs rx;
95784 + struct fman_port_tx_bmi_regs tx;
95785 + struct fman_port_oh_bmi_regs oh;
95786 +};
95787 +
95788 +/** @Description QMI port register map */
95789 +struct fman_port_qmi_regs {
95790 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
95791 + uint32_t fmqm_pns; /**< PortID n Status Register */
95792 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
95793 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
95794 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
95795 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
95796 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
95797 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
95798 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
95799 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
95800 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
95801 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
95802 +};
95803 +
95804 +
95805 +enum fman_port_dma_swap {
95806 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
95807 + E_FMAN_PORT_DMA_SWAP_LE,
95808 + /**< The transferred data should be swapped in PPC Little Endian mode */
95809 + E_FMAN_PORT_DMA_SWAP_BE
95810 + /**< The transferred data should be swapped in Big Endian mode */
95811 +};
95812 +
95813 +/* Default port color */
95814 +enum fman_port_color {
95815 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
95816 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
95817 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
95818 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
95819 +};
95820 +
95821 +/* QMI dequeue from the SP channel - types */
95822 +enum fman_port_deq_type {
95823 + E_FMAN_PORT_DEQ_BY_PRI,
95824 + /**< Priority precedence and Intra-Class scheduling */
95825 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
95826 + /**< Active FQ precedence and Intra-Class scheduling */
95827 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
95828 + /**< Active FQ precedence and override Intra-Class scheduling */
95829 +};
95830 +
95831 +/* QMI dequeue prefetch modes */
95832 +enum fman_port_deq_prefetch {
95833 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
95834 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
95835 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
95836 +};
95837 +
95838 +/* Parameters for defining performance counters behavior */
95839 +struct fman_port_perf_cnt_params {
95840 + uint8_t task_val; /**< Task compare value */
95841 + uint8_t queue_val;
95842 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
95843 + uint8_t dma_val; /**< Dma compare value */
95844 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
95845 +};
95846 +
95847 +/** @Description FM Port configuration structure, used at init */
95848 +struct fman_port_cfg {
95849 + struct fman_port_perf_cnt_params perf_cnt_params;
95850 + /* BMI parameters */
95851 + enum fman_port_dma_swap dma_swap_data;
95852 + bool dma_ic_stash_on;
95853 + bool dma_header_stash_on;
95854 + bool dma_sg_stash_on;
95855 + bool dma_write_optimize;
95856 + uint16_t ic_ext_offset;
95857 + uint8_t ic_int_offset;
95858 + uint16_t ic_size;
95859 + enum fman_port_color color;
95860 + bool sync_req;
95861 + bool discard_override;
95862 + uint8_t checksum_bytes_ignore;
95863 + uint8_t rx_cut_end_bytes;
95864 + uint32_t rx_pri_elevation;
95865 + uint32_t rx_fifo_thr;
95866 + uint8_t rx_fd_bits;
95867 + uint8_t int_buf_start_margin;
95868 + uint16_t ext_buf_start_margin;
95869 + uint16_t ext_buf_end_margin;
95870 + uint32_t tx_fifo_min_level;
95871 + uint32_t tx_fifo_low_comf_level;
95872 + uint8_t tx_fifo_deq_pipeline_depth;
95873 + bool stats_counters_enable;
95874 + bool perf_counters_enable;
95875 + /* QMI parameters */
95876 + bool deq_high_pri;
95877 + enum fman_port_deq_type deq_type;
95878 + enum fman_port_deq_prefetch deq_prefetch_opt;
95879 + uint16_t deq_byte_cnt;
95880 + bool queue_counters_enable;
95881 + bool no_scatter_gather;
95882 + int errata_A006675;
95883 + int errata_A006320;
95884 + int excessive_threshold_register;
95885 + int fmbm_rebm_has_sgd;
95886 + int fmbm_tfne_has_features;
95887 + int qmi_deq_options_support;
95888 +};
95889 +
95890 +enum fman_port_type {
95891 + E_FMAN_PORT_TYPE_OP = 0,
95892 + /**< Offline parsing port, shares id-s with
95893 + * host command, so must have exclusive id-s */
95894 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
95895 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
95896 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
95897 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
95898 + E_FMAN_PORT_TYPE_DUMMY,
95899 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
95900 + /**< Host command port, shares id-s with
95901 + * offline parsing ports, so must have exclusive id-s */
95902 +};
95903 +
95904 +struct fman_port_params {
95905 + uint32_t discard_mask;
95906 + uint32_t err_mask;
95907 + uint32_t dflt_fqid;
95908 + uint32_t err_fqid;
95909 + uint8_t deq_sp;
95910 + bool dont_release_buf;
95911 +};
95912 +
95913 +/* Port context - used by most API functions */
95914 +struct fman_port {
95915 + enum fman_port_type type;
95916 + uint8_t fm_rev_maj;
95917 + uint8_t fm_rev_min;
95918 + union fman_port_bmi_regs *bmi_regs;
95919 + struct fman_port_qmi_regs *qmi_regs;
95920 + bool im_en;
95921 + uint8_t ext_pools_num;
95922 +};
95923 +
95924 +/** @Description External buffer pools configuration */
95925 +struct fman_port_bpools {
95926 + uint8_t count; /**< Num of pools to set up */
95927 + bool counters_enable; /**< Enable allocate counters */
95928 + uint8_t grp_bp_depleted_num;
95929 + /**< Number of depleted pools - if reached the BMI indicates
95930 + * the MAC to send a pause frame */
95931 + struct {
95932 + uint8_t bpid; /**< BM pool ID */
95933 + uint16_t size;
95934 + /**< Pool's size - must be in ascending order */
95935 + bool is_backup;
95936 + /**< If this is a backup pool */
95937 + bool grp_bp_depleted;
95938 + /**< Consider this buffer in multiple pools depletion criteria*/
95939 + bool single_bp_depleted;
95940 + /**< Consider this buffer in single pool depletion criteria */
95941 + bool pfc_priorities_en;
95942 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
95943 +};
95944 +
95945 +enum fman_port_rate_limiter_scale_down {
95946 + E_FMAN_PORT_RATE_DOWN_NONE,
95947 + E_FMAN_PORT_RATE_DOWN_BY_2,
95948 + E_FMAN_PORT_RATE_DOWN_BY_4,
95949 + E_FMAN_PORT_RATE_DOWN_BY_8
95950 +};
95951 +
95952 +/* Rate limiter configuration */
95953 +struct fman_port_rate_limiter {
95954 + uint8_t count_1micro_bit;
95955 + bool high_burst_size_gran;
95956 + /**< Defines burst_size granularity for OP ports; when TRUE,
95957 + * burst_size below counts in frames, otherwise in 10^3 frames */
95958 + uint16_t burst_size;
95959 + /**< Max burst size, in KBytes for Tx port, according to
95960 + * high_burst_size_gran definition for OP port */
95961 + uint32_t rate;
95962 + /**< In Kbps for Tx port, in frames/sec for OP port */
95963 + enum fman_port_rate_limiter_scale_down rate_factor;
95964 +};
95965 +
95966 +/* BMI statistics counters */
95967 +enum fman_port_stats_counters {
95968 + E_FMAN_PORT_STATS_CNT_FRAME,
95969 + /**< Number of processed frames; valid for all ports */
95970 + E_FMAN_PORT_STATS_CNT_DISCARD,
95971 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
95972 + * frames discarded due to DMA error; valid for all ports */
95973 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
95974 + /**< Number of buffer deallocate operations; valid for all ports */
95975 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
95976 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
95977 + * valid for Rx ports only */
95978 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
95979 + /**< Number of Rx oversized frames, that is frames exceeding max frame
95980 + * size configured for the corresponding ETH controller;
95981 + * valid for Rx ports only */
95982 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
95983 + /**< Frames discarded due to lack of external buffers; valid for
95984 + * Rx ports only */
95985 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
95986 + /**< Frames discarded due to frame length error; valid for Tx and
95987 + * O/H ports only */
95988 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
95989 + /**< Frames discarded due to unsupported FD format; valid for Tx
95990 + * and O/H ports only */
95991 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
95992 + /**< Number of frames filtered out by PCD module; valid for
95993 + * Rx and OP ports only */
95994 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
95995 + /**< Frames rejected by QMAN that were not able to release their
95996 + * buffers due to DMA error; valid for Rx and O/H ports only */
95997 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
95998 + /**< Frames going through O/H port that were not able to to enter the
95999 + * return queue due to WRED algorithm; valid for O/H ports only */
96000 +};
96001 +
96002 +/* BMI performance counters */
96003 +enum fman_port_perf_counters {
96004 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
96005 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
96006 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
96007 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
96008 + * utilization; not valid for O/H ports */
96009 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
96010 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
96011 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
96012 + /**< Number of cycles in which Rx pause activation control is on;
96013 + * valid for Rx ports only */
96014 +};
96015 +
96016 +/* QMI counters */
96017 +enum fman_port_qmi_counters {
96018 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
96019 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
96020 + E_FMAN_PORT_DEQ_FROM_DFLT,
96021 + /**< Dequeue from default FQID counter not valid for Rx ports */
96022 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
96023 +};
96024 +
96025 +
96026 +/** @Collection FM Port API */
96027 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
96028 +int fman_port_init(struct fman_port *port,
96029 + struct fman_port_cfg *cfg,
96030 + struct fman_port_params *params);
96031 +int fman_port_enable(struct fman_port *port);
96032 +int fman_port_disable(const struct fman_port *port);
96033 +int fman_port_set_bpools(const struct fman_port *port,
96034 + const struct fman_port_bpools *bp);
96035 +int fman_port_set_rate_limiter(struct fman_port *port,
96036 + struct fman_port_rate_limiter *rate_limiter);
96037 +int fman_port_delete_rate_limiter(struct fman_port *port);
96038 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
96039 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
96040 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
96041 + uint8_t rx_fd_bits,
96042 + bool add);
96043 +int fman_port_set_perf_cnt_params(struct fman_port *port,
96044 + struct fman_port_perf_cnt_params *params);
96045 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
96046 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
96047 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
96048 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
96049 + uint8_t bpid,
96050 + bool enable);
96051 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
96052 + enum fman_port_stats_counters counter);
96053 +void fman_port_set_stats_counter(struct fman_port *port,
96054 + enum fman_port_stats_counters counter,
96055 + uint32_t value);
96056 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
96057 + enum fman_port_perf_counters counter);
96058 +void fman_port_set_perf_counter(struct fman_port *port,
96059 + enum fman_port_perf_counters counter,
96060 + uint32_t value);
96061 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
96062 + enum fman_port_qmi_counters counter);
96063 +void fman_port_set_qmi_counter(struct fman_port *port,
96064 + enum fman_port_qmi_counters counter,
96065 + uint32_t value);
96066 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
96067 +void fman_port_set_bpool_counter(struct fman_port *port,
96068 + uint8_t bpid,
96069 + uint32_t value);
96070 +int fman_port_add_congestion_grps(struct fman_port *port,
96071 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96072 +int fman_port_remove_congestion_grps(struct fman_port *port,
96073 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
96074 +
96075 +
96076 +#endif /* __FSL_FMAN_PORT_H */
96077 --- /dev/null
96078 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
96079 @@ -0,0 +1,102 @@
96080 +/*
96081 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96082 + *
96083 + * Redistribution and use in source and binary forms, with or without
96084 + * modification, are permitted provided that the following conditions are met:
96085 + * * Redistributions of source code must retain the above copyright
96086 + * notice, this list of conditions and the following disclaimer.
96087 + * * Redistributions in binary form must reproduce the above copyright
96088 + * notice, this list of conditions and the following disclaimer in the
96089 + * documentation and/or other materials provided with the distribution.
96090 + * * Neither the name of Freescale Semiconductor nor the
96091 + * names of its contributors may be used to endorse or promote products
96092 + * derived from this software without specific prior written permission.
96093 + *
96094 + *
96095 + * ALTERNATIVELY, this software may be distributed under the terms of the
96096 + * GNU General Public License ("GPL") as published by the Free Software
96097 + * Foundation, either version 2 of that License or (at your option) any
96098 + * later version.
96099 + *
96100 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96101 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96102 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96103 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96104 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96105 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96106 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96107 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96108 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96109 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96110 + */
96111 +
96112 +#ifndef __FSL_FMAN_PRS_H
96113 +#define __FSL_FMAN_PRS_H
96114 +
96115 +#include "common/general.h"
96116 +
96117 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
96118 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
96119 +
96120 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
96121 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
96122 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
96123 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
96124 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
96125 +#define PRS_MAX_CYCLE_LIMIT 8191
96126 +
96127 +#define DEFAULT_MAX_PRS_CYC_LIM 0
96128 +
96129 +struct fman_prs_regs {
96130 + uint32_t fmpr_rpclim;
96131 + uint32_t fmpr_rpimac;
96132 + uint32_t pmeec;
96133 + uint32_t res00c[5];
96134 + uint32_t fmpr_pevr;
96135 + uint32_t fmpr_pever;
96136 + uint32_t res028;
96137 + uint32_t fmpr_perr;
96138 + uint32_t fmpr_perer;
96139 + uint32_t res034;
96140 + uint32_t res038[10];
96141 + uint32_t fmpr_ppsc;
96142 + uint32_t res064;
96143 + uint32_t fmpr_pds;
96144 + uint32_t fmpr_l2rrs;
96145 + uint32_t fmpr_l3rrs;
96146 + uint32_t fmpr_l4rrs;
96147 + uint32_t fmpr_srrs;
96148 + uint32_t fmpr_l2rres;
96149 + uint32_t fmpr_l3rres;
96150 + uint32_t fmpr_l4rres;
96151 + uint32_t fmpr_srres;
96152 + uint32_t fmpr_spcs;
96153 + uint32_t fmpr_spscs;
96154 + uint32_t fmpr_hxscs;
96155 + uint32_t fmpr_mrcs;
96156 + uint32_t fmpr_mwcs;
96157 + uint32_t fmpr_mrscs;
96158 + uint32_t fmpr_mwscs;
96159 + uint32_t fmpr_fcscs;
96160 +};
96161 +
96162 +struct fman_prs_cfg {
96163 + uint32_t port_id_stat;
96164 + uint16_t max_prs_cyc_lim;
96165 + uint32_t prs_exceptions;
96166 +};
96167 +
96168 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96169 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
96170 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
96171 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
96172 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
96173 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
96174 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
96175 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
96176 +void fman_prs_enable(struct fman_prs_regs *regs);
96177 +void fman_prs_disable(struct fman_prs_regs *regs);
96178 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
96179 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
96180 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
96181 +#endif /* __FSL_FMAN_PRS_H */
96182 --- /dev/null
96183 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
96184 @@ -0,0 +1,449 @@
96185 +/*
96186 + * Copyright 2013 Freescale Semiconductor Inc.
96187 + *
96188 + * Redistribution and use in source and binary forms, with or without
96189 + * modification, are permitted provided that the following conditions are met:
96190 + * * Redistributions of source code must retain the above copyright
96191 + * notice, this list of conditions and the following disclaimer.
96192 + * * Redistributions in binary form must reproduce the above copyright
96193 + * notice, this list of conditions and the following disclaimer in the
96194 + * documentation and/or other materials provided with the distribution.
96195 + * * Neither the name of Freescale Semiconductor nor the
96196 + * names of its contributors may be used to endorse or promote products
96197 + * derived from this software without specific prior written permission.
96198 + *
96199 + *
96200 + * ALTERNATIVELY, this software may be distributed under the terms of the
96201 + * GNU General Public License ("GPL") as published by the Free Software
96202 + * Foundation, either version 2 of that License or (at your option) any
96203 + * later version.
96204 + *
96205 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96206 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96207 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96208 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96209 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96210 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96211 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96212 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96213 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96214 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96215 + */
96216 +
96217 +#ifndef __FSL_FMAN_RTC_H
96218 +#define __FSL_FMAN_RTC_H
96219 +
96220 +#include "common/general.h"
96221 +
96222 +/* FM RTC Registers definitions */
96223 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
96224 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
96225 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
96226 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
96227 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
96228 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
96229 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
96230 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
96231 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
96232 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
96233 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
96234 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
96235 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
96236 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
96237 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
96238 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
96239 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
96240 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
96241 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
96242 +
96243 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
96244 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
96245 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
96246 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
96247 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
96248 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
96249 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
96250 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
96251 + FMAN_RTC_TMR_TEVENT_ETS1 |\
96252 + FMAN_RTC_TMR_TEVENT_ALM2 |\
96253 + FMAN_RTC_TMR_TEVENT_ALM1 |\
96254 + FMAN_RTC_TMR_TEVENT_PP1 |\
96255 + FMAN_RTC_TMR_TEVENT_PP2 |\
96256 + FMAN_RTC_TMR_TEVENT_PP3)
96257 +
96258 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
96259 +
96260 +/**************************************************************************//**
96261 + @Description FM RTC Alarm Polarity Options.
96262 +*//***************************************************************************/
96263 +enum fman_rtc_alarm_polarity {
96264 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
96265 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
96266 +};
96267 +
96268 +/**************************************************************************//**
96269 + @Description FM RTC Trigger Polarity Options.
96270 +*//***************************************************************************/
96271 +enum fman_rtc_trigger_polarity {
96272 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
96273 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
96274 +};
96275 +
96276 +/**************************************************************************//**
96277 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
96278 +*//***************************************************************************/
96279 +enum fman_src_clock {
96280 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
96281 + reference clock */
96282 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
96283 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
96284 +};
96285 +
96286 +/* RTC default values */
96287 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
96288 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
96289 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
96290 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
96291 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
96292 +#define DEFAULT_PULSE_REALIGN FALSE
96293 +
96294 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
96295 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
96296 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
96297 +
96298 +/**************************************************************************//**
96299 + @Description FM RTC timer alarm
96300 +*//***************************************************************************/
96301 +struct t_tmr_alarm{
96302 + uint32_t tmr_alarm_h; /**< */
96303 + uint32_t tmr_alarm_l; /**< */
96304 +};
96305 +
96306 +/**************************************************************************//**
96307 + @Description FM RTC timer Ex trigger
96308 +*//***************************************************************************/
96309 +struct t_tmr_ext_trigger{
96310 + uint32_t tmr_etts_h; /**< */
96311 + uint32_t tmr_etts_l; /**< */
96312 +};
96313 +
96314 +struct rtc_regs {
96315 + uint32_t tmr_id; /* 0x000 Module ID register */
96316 + uint32_t tmr_id2; /* 0x004 Controller ID register */
96317 + uint32_t reserved0008[30];
96318 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
96319 + uint32_t tmr_tevent; /* 0x0084 timer event register */
96320 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
96321 + uint32_t reserved008c[3];
96322 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
96323 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
96324 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
96325 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
96326 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
96327 + uint32_t reserved00ac;
96328 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
96329 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
96330 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
96331 + alarm */
96332 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
96333 + fixed period interval */
96334 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96335 + /* 0x00e0 time stamp general purpose external */
96336 + uint32_t reserved00f0[4];
96337 +};
96338 +
96339 +struct rtc_cfg {
96340 + enum fman_src_clock src_clk;
96341 + uint32_t ext_src_clk_freq;
96342 + uint32_t rtc_freq_hz;
96343 + bool timer_slave_mode;
96344 + bool invert_input_clk_phase;
96345 + bool invert_output_clk_phase;
96346 + uint32_t events_mask;
96347 + bool bypass; /**< Indicates if frequency compensation
96348 + is bypassed */
96349 + bool pulse_realign;
96350 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
96351 + enum fman_rtc_trigger_polarity trigger_polarity
96352 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
96353 +};
96354 +
96355 +/**
96356 + * fman_rtc_defconfig() - Get default RTC configuration
96357 + * @cfg: pointer to configuration structure.
96358 + *
96359 + * Call this function to obtain a default set of configuration values for
96360 + * initializing RTC. The user can overwrite any of the values before calling
96361 + * fman_rtc_init(), if specific configuration needs to be applied.
96362 + */
96363 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
96364 +
96365 +/**
96366 + * fman_rtc_get_events() - Get the events
96367 + * @regs: Pointer to RTC register block
96368 + *
96369 + * Returns: The events
96370 + */
96371 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
96372 +
96373 +/**
96374 + * fman_rtc_get_interrupt_mask() - Get the events mask
96375 + * @regs: Pointer to RTC register block
96376 + *
96377 + * Returns: The events mask
96378 + */
96379 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
96380 +
96381 +
96382 +/**
96383 + * fman_rtc_set_interrupt_mask() - Set the events mask
96384 + * @regs: Pointer to RTC register block
96385 + * @mask: The mask to set
96386 + */
96387 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
96388 +
96389 +/**
96390 + * fman_rtc_get_event() - Check if specific events occurred
96391 + * @regs: Pointer to RTC register block
96392 + * @ev_mask: a mask of the events to check
96393 + *
96394 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
96395 + */
96396 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
96397 +
96398 +/**
96399 + * fman_rtc_check_and_clear_event() - Clear events which are on
96400 + * @regs: Pointer to RTC register block
96401 + *
96402 + * Returns: A mask of the events which were cleared
96403 + */
96404 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
96405 +
96406 +/**
96407 + * fman_rtc_ack_event() - Clear events
96408 + * @regs: Pointer to RTC register block
96409 + * @events: The events to disable
96410 + */
96411 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
96412 +
96413 +/**
96414 + * fman_rtc_enable_interupt() - Enable events interrupts
96415 + * @regs: Pointer to RTC register block
96416 + * @mask: The events to disable
96417 + */
96418 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
96419 +
96420 +/**
96421 + * fman_rtc_disable_interupt() - Disable events interrupts
96422 + * @regs: Pointer to RTC register block
96423 + * @mask: The events to disable
96424 + */
96425 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
96426 +
96427 +/**
96428 + * fman_rtc_get_timer_ctrl() - Get the control register
96429 + * @regs: Pointer to RTC register block
96430 + *
96431 + * Returns: The control register value
96432 + */
96433 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
96434 +
96435 +/**
96436 + * fman_rtc_set_timer_ctrl() - Set timer control register
96437 + * @regs: Pointer to RTC register block
96438 + * @val: The value to set
96439 + */
96440 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
96441 +
96442 +/**
96443 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
96444 + * @regs: Pointer to RTC register block
96445 + *
96446 + * Returns: The timer counter
96447 + */
96448 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
96449 +
96450 +/**
96451 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
96452 + * @regs: Pointer to RTC register block
96453 + * @val: The value to set
96454 + */
96455 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
96456 +
96457 +/**
96458 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
96459 + * @regs: Pointer to RTC register block
96460 + * @id: The id of the trigger stamp
96461 + *
96462 + * Returns: The time stamp
96463 + */
96464 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
96465 +
96466 +/**
96467 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
96468 + * @regs: Pointer to RTC register block
96469 + * @index: The index of alarm to set
96470 + * @val: The value to set
96471 + */
96472 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
96473 + uint32_t val);
96474 +
96475 +/**
96476 + * fman_rtc_set_timer_alarm() - Set timer alarm
96477 + * @regs: Pointer to RTC register block
96478 + * @index: The index of alarm to set
96479 + * @val: The value to set
96480 + */
96481 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
96482 +
96483 +/**
96484 + * fman_rtc_set_timer_fiper() - Set timer fiper
96485 + * @regs: Pointer to RTC register block
96486 + * @index: The index of fiper to set
96487 + * @val: The value to set
96488 + */
96489 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
96490 +
96491 +/**
96492 + * fman_rtc_set_timer_offset() - Set timer offset
96493 + * @regs: Pointer to RTC register block
96494 + * @val: The value to set
96495 + */
96496 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
96497 +
96498 +/**
96499 + * fman_rtc_get_timer() - Get the timer counter
96500 + * @regs: Pointer to RTC register block
96501 + *
96502 + * Returns: The timer counter
96503 + */
96504 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
96505 +{
96506 + uint64_t time;
96507 + /* TMR_CNT_L must be read first to get an accurate value */
96508 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
96509 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
96510 +
96511 + return time;
96512 +}
96513 +
96514 +/**
96515 + * fman_rtc_set_timer() - Set timer counter
96516 + * @regs: Pointer to RTC register block
96517 + * @val: The value to set
96518 + */
96519 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
96520 +{
96521 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
96522 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
96523 +}
96524 +
96525 +/**
96526 + * fman_rtc_timers_soft_reset() - Soft reset
96527 + * @regs: Pointer to RTC register block
96528 + *
96529 + * Resets all the timer registers and state machines for the 1588 IP and
96530 + * the attached client 1588
96531 + */
96532 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
96533 +
96534 +/**
96535 + * fman_rtc_clear_external_trigger() - Clear an external trigger
96536 + * @regs: Pointer to RTC register block
96537 + * @id: The id of the trigger to clear
96538 + */
96539 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
96540 +
96541 +/**
96542 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
96543 + * @regs: Pointer to RTC register block
96544 + * @id: The id of the fiper to clear
96545 + */
96546 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
96547 +
96548 +/**
96549 + * fman_rtc_enable() - Enable RTC hardware block
96550 + * @regs: Pointer to RTC register block
96551 + */
96552 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
96553 +
96554 +/**
96555 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
96556 + * @regs: Pointer to RTC register block
96557 + *
96558 + * Return: TRUE if enabled
96559 + */
96560 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
96561 +
96562 +/**
96563 + * fman_rtc_disable() - Disable RTC hardware block
96564 + * @regs: Pointer to RTC register block
96565 + */
96566 +void fman_rtc_disable(struct rtc_regs *regs);
96567 +
96568 +/**
96569 + * fman_rtc_init() - Init RTC hardware block
96570 + * @cfg: RTC configuration data
96571 + * @regs: Pointer to RTC register block
96572 + * @num_alarms: Number of alarms in RTC
96573 + * @num_fipers: Number of fipers in RTC
96574 + * @num_ext_triggers: Number of external triggers in RTC
96575 + * @freq_compensation: Frequency compensation
96576 + * @output_clock_divisor: Output clock divisor
96577 + *
96578 + * This function initializes RTC and applies basic configuration.
96579 + */
96580 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
96581 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
96582 + uint32_t freq_compensation, uint32_t output_clock_divisor);
96583 +
96584 +/**
96585 + * fman_rtc_set_alarm() - Set an alarm
96586 + * @regs: Pointer to RTC register block
96587 + * @id: id of alarm
96588 + * @val: value to write
96589 + * @enable: should interrupt be enabled
96590 + */
96591 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
96592 +
96593 +/**
96594 + * fman_rtc_set_periodic_pulse() - Set an alarm
96595 + * @regs: Pointer to RTC register block
96596 + * @id: id of fiper
96597 + * @val: value to write
96598 + * @enable: should interrupt be enabled
96599 + */
96600 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
96601 + bool enable);
96602 +
96603 +/**
96604 + * fman_rtc_set_ext_trigger() - Set an external trigger
96605 + * @regs: Pointer to RTC register block
96606 + * @id: id of trigger
96607 + * @enable: should interrupt be enabled
96608 + * @use_pulse_as_input: use the pulse as input
96609 + */
96610 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
96611 + bool use_pulse_as_input);
96612 +
96613 +struct fm_rtc_alarm_params {
96614 + uint8_t alarm_id; /**< 0 or 1 */
96615 + uint64_t alarm_time; /**< In nanoseconds, the time when the
96616 + alarm should go off - must be a
96617 + multiple of the RTC period */
96618 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
96619 + be called when RTC reaches alarmTime */
96620 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
96621 + expired.*/
96622 +};
96623 +
96624 +struct fm_rtc_periodic_pulse_params {
96625 + uint8_t periodic_pulse_id; /**< 0 or 1 */
96626 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
96627 + of the RTC period */
96628 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
96629 + routine will be called every
96630 + periodicPulsePeriod. */
96631 +};
96632 +
96633 +#endif /* __FSL_FMAN_RTC_H */
96634 --- /dev/null
96635 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
96636 @@ -0,0 +1,138 @@
96637 +/*
96638 + * Copyright 2013 Freescale Semiconductor Inc.
96639 + *
96640 + * Redistribution and use in source and binary forms, with or without
96641 + * modification, are permitted provided that the following conditions are met:
96642 + * * Redistributions of source code must retain the above copyright
96643 + * notice, this list of conditions and the following disclaimer.
96644 + * * Redistributions in binary form must reproduce the above copyright
96645 + * notice, this list of conditions and the following disclaimer in the
96646 + * documentation and/or other materials provided with the distribution.
96647 + * * Neither the name of Freescale Semiconductor nor the
96648 + * names of its contributors may be used to endorse or promote products
96649 + * derived from this software without specific prior written permission.
96650 + *
96651 + *
96652 + * ALTERNATIVELY, this software may be distributed under the terms of the
96653 + * GNU General Public License ("GPL") as published by the Free Software
96654 + * Foundation, either version 2 of that License or (at your option) any
96655 + * later version.
96656 + *
96657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96667 + */
96668 +
96669 +#ifndef __FSL_FMAN_SP_H
96670 +#define __FSL_FMAN_SP_H
96671 +
96672 +#include "common/general.h"
96673 +#include "fsl_fman.h"
96674 +
96675 +
96676 +struct fm_pcd_storage_profile_regs{
96677 + uint32_t fm_sp_ebmpi[8];
96678 + /*offset 0 - 0xc*/
96679 + /**< Buffer Manager pool Information */
96680 +
96681 + uint32_t fm_sp_acnt; /*offset 0x20*/
96682 + uint32_t fm_sp_ebm; /*offset 0x24*/
96683 + uint32_t fm_sp_da; /*offset 0x28*/
96684 + uint32_t fm_sp_icp; /*offset 0x2c*/
96685 + uint32_t fm_sp_mpd; /*offset 0x30*/
96686 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
96687 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
96688 +};
96689 +
96690 +/**************************************************************************//**
96691 + @Description structure for defining internal context copying
96692 +*//***************************************************************************/
96693 +struct fman_sp_int_context_data_copy{
96694 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
96695 + internal context is copied to (Rx)
96696 + or taken from (Tx, Op). */
96697 + uint8_t int_context_offset; /**< Offset within internal context to copy
96698 + from (Rx) or to copy to (Tx, Op).*/
96699 + uint16_t size; /**< Internal offset size to be copied */
96700 +};
96701 +
96702 +/**************************************************************************//**
96703 + @Description struct for defining external buffer margins
96704 +*//***************************************************************************/
96705 +struct fman_sp_buf_margins{
96706 + uint16_t start_margins; /**< Number of bytes to be left at the
96707 + beginning of the external buffer (must be
96708 + divisible by 16) */
96709 + uint16_t end_margins; /**< number of bytes to be left at the end of
96710 + the external buffer(must be divisible by 16)*/
96711 +};
96712 +
96713 +struct fm_storage_profile_params {
96714 + struct fman_ext_pools fm_ext_pools;
96715 + struct fman_backup_bm_pools backup_pools;
96716 + struct fman_sp_int_context_data_copy *int_context;
96717 + struct fman_sp_buf_margins *buf_margins;
96718 + enum fman_dma_swap_option dma_swap_data;
96719 + enum fman_dma_cache_option int_context_cache_attr;
96720 + enum fman_dma_cache_option header_cache_attr;
96721 + enum fman_dma_cache_option scatter_gather_cache_attr;
96722 + bool dma_write_optimize;
96723 + uint16_t liodn_offset;
96724 + bool no_scather_gather;
96725 + struct fman_buf_pool_depletion buf_pool_depletion;
96726 +};
96727 +
96728 +/**************************************************************************//**
96729 + @Description Registers bit fields
96730 +*//***************************************************************************/
96731 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
96732 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
96733 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
96734 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
96735 +#define FMAN_SP_SG_DISABLE 0x80000000
96736 +
96737 +/* shifts */
96738 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
96739 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
96740 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
96741 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
96742 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
96743 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
96744 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
96745 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
96746 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
96747 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
96748 +#define FMAN_SP_IC_SIZE_SHIFT 0
96749 +
96750 +/**************************************************************************//**
96751 + @Description defaults
96752 +*//***************************************************************************/
96753 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
96754 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
96755 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
96756 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
96757 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
96758 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
96759 +
96760 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
96761 +
96762 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
96763 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
96764 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
96765 + int max_num_of_pfc_priorities);
96766 +
96767 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
96768 + uint16_t index);
96769 +
96770 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
96771 + uint16_t index, uint32_t value);
96772 +
96773 +
96774 +#endif /* __FSL_FMAN_SP_H */
96775 --- /dev/null
96776 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
96777 @@ -0,0 +1,479 @@
96778 +/*
96779 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96780 + *
96781 + * Redistribution and use in source and binary forms, with or without
96782 + * modification, are permitted provided that the following conditions are met:
96783 + * * Redistributions of source code must retain the above copyright
96784 + * notice, this list of conditions and the following disclaimer.
96785 + * * Redistributions in binary form must reproduce the above copyright
96786 + * notice, this list of conditions and the following disclaimer in the
96787 + * documentation and/or other materials provided with the distribution.
96788 + * * Neither the name of Freescale Semiconductor nor the
96789 + * names of its contributors may be used to endorse or promote products
96790 + * derived from this software without specific prior written permission.
96791 + *
96792 + *
96793 + * ALTERNATIVELY, this software may be distributed under the terms of the
96794 + * GNU General Public License ("GPL") as published by the Free Software
96795 + * Foundation, either version 2 of that License or (at your option) any
96796 + * later version.
96797 + *
96798 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96799 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96800 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96801 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96802 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96803 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96804 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96805 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96806 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96807 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96808 + */
96809 +
96810 +#ifndef __FSL_FMAN_TGEC_H
96811 +#define __FSL_FMAN_TGEC_H
96812 +
96813 +#include "common/general.h"
96814 +#include "fsl_enet.h"
96815 +
96816 +
96817 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96818 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
96819 +
96820 +enum tgec_counters {
96821 + E_TGEC_COUNTER_R64,
96822 + E_TGEC_COUNTER_R127,
96823 + E_TGEC_COUNTER_R255,
96824 + E_TGEC_COUNTER_R511,
96825 + E_TGEC_COUNTER_R1023,
96826 + E_TGEC_COUNTER_R1518,
96827 + E_TGEC_COUNTER_R1519X,
96828 + E_TGEC_COUNTER_TRFRG,
96829 + E_TGEC_COUNTER_TRJBR,
96830 + E_TGEC_COUNTER_RDRP,
96831 + E_TGEC_COUNTER_RALN,
96832 + E_TGEC_COUNTER_TRUND,
96833 + E_TGEC_COUNTER_TROVR,
96834 + E_TGEC_COUNTER_RXPF,
96835 + E_TGEC_COUNTER_TXPF,
96836 + E_TGEC_COUNTER_ROCT,
96837 + E_TGEC_COUNTER_RMCA,
96838 + E_TGEC_COUNTER_RBCA,
96839 + E_TGEC_COUNTER_RPKT,
96840 + E_TGEC_COUNTER_RUCA,
96841 + E_TGEC_COUNTER_RERR,
96842 + E_TGEC_COUNTER_TOCT,
96843 + E_TGEC_COUNTER_TMCA,
96844 + E_TGEC_COUNTER_TBCA,
96845 + E_TGEC_COUNTER_TUCA,
96846 + E_TGEC_COUNTER_TERR
96847 +};
96848 +
96849 +/* Command and Configuration Register (COMMAND_CONFIG) */
96850 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
96851 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
96852 +#define CMD_CFG_NO_LEN_CHK 0x00020000
96853 +#define CMD_CFG_SEND_IDLE 0x00010000
96854 +#define CMD_CFG_RX_ER_DISC 0x00004000
96855 +#define CMD_CFG_CMD_FRM_EN 0x00002000
96856 +#define CMD_CFG_STAT_CLR 0x00001000
96857 +#define CMD_CFG_LOOPBACK_EN 0x00000400
96858 +#define CMD_CFG_TX_ADDR_INS 0x00000200
96859 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
96860 +#define CMD_CFG_PAUSE_FWD 0x00000080
96861 +#define CMD_CFG_PROMIS_EN 0x00000010
96862 +#define CMD_CFG_WAN_MODE 0x00000008
96863 +#define CMD_CFG_RX_EN 0x00000002
96864 +#define CMD_CFG_TX_EN 0x00000001
96865 +
96866 +/* Interrupt Mask Register (IMASK) */
96867 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
96868 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
96869 +#define TGEC_IMASK_REM_FAULT 0x00004000
96870 +#define TGEC_IMASK_LOC_FAULT 0x00002000
96871 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
96872 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
96873 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
96874 +#define TGEC_IMASK_TX_ER 0x00000200
96875 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
96876 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
96877 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
96878 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
96879 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
96880 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
96881 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
96882 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
96883 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
96884 +
96885 +#define TGEC_EVENTS_MASK \
96886 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
96887 + TGEC_IMASK_MDIO_CMD_CMPL | \
96888 + TGEC_IMASK_REM_FAULT | \
96889 + TGEC_IMASK_LOC_FAULT | \
96890 + TGEC_IMASK_TX_ECC_ER | \
96891 + TGEC_IMASK_TX_FIFO_UNFL | \
96892 + TGEC_IMASK_TX_FIFO_OVFL | \
96893 + TGEC_IMASK_TX_ER | \
96894 + TGEC_IMASK_RX_FIFO_OVFL | \
96895 + TGEC_IMASK_RX_ECC_ER | \
96896 + TGEC_IMASK_RX_JAB_FRM | \
96897 + TGEC_IMASK_RX_OVRSZ_FRM | \
96898 + TGEC_IMASK_RX_RUNT_FRM | \
96899 + TGEC_IMASK_RX_FRAG_FRM | \
96900 + TGEC_IMASK_RX_LEN_ER | \
96901 + TGEC_IMASK_RX_CRC_ER | \
96902 + TGEC_IMASK_RX_ALIGN_ER))
96903 +
96904 +/* Hashtable Control Register (HASHTABLE_CTRL) */
96905 +#define TGEC_HASH_MCAST_SHIFT 23
96906 +#define TGEC_HASH_MCAST_EN 0x00000200
96907 +#define TGEC_HASH_ADR_MSK 0x000001ff
96908 +
96909 +#define DEFAULT_WAN_MODE_ENABLE FALSE
96910 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
96911 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
96912 +#define DEFAULT_PAUSE_IGNORE FALSE
96913 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
96914 +#define DEFAULT_LOOPBACK_ENABLE FALSE
96915 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
96916 +#define DEFAULT_RX_ERROR_DISCARD FALSE
96917 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
96918 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
96919 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
96920 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
96921 +#define DEFAULT_TX_IPG_LENGTH 12
96922 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
96923 +#define DEFAULT_PAUSE_QUANT 0xf000
96924 +
96925 +/*
96926 + * 10G memory map
96927 + */
96928 +struct tgec_regs {
96929 + uint32_t tgec_id; /* 0x000 Controller ID */
96930 + uint32_t reserved001[1]; /* 0x004 */
96931 + uint32_t command_config; /* 0x008 Control and configuration */
96932 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
96933 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
96934 + uint32_t maxfrm; /* 0x014 Maximum frame length */
96935 + uint32_t pause_quant; /* 0x018 Pause quanta */
96936 + uint32_t rx_fifo_sections; /* 0x01c */
96937 + uint32_t tx_fifo_sections; /* 0x020 */
96938 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
96939 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
96940 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
96941 + uint32_t mdio_cfg_status; /* 0x030 */
96942 + uint32_t mdio_command; /* 0x034 */
96943 + uint32_t mdio_data; /* 0x038 */
96944 + uint32_t mdio_regaddr; /* 0x03c */
96945 + uint32_t status; /* 0x040 */
96946 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
96947 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
96948 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
96949 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
96950 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
96951 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
96952 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
96953 + uint32_t imask; /* 0x060 Interrupt mask */
96954 + uint32_t ievent; /* 0x064 Interrupt event */
96955 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
96956 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
96957 + uint32_t reserved070[4]; /* 0x070 */
96958 + /*10Ge Statistics Counter */
96959 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
96960 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
96961 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
96962 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
96963 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
96964 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
96965 + uint32_t raln_u; /* 98 aAlignmentErrors */
96966 + uint32_t raln_l; /* 9c aAlignmentErrors */
96967 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
96968 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
96969 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
96970 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
96971 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
96972 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
96973 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
96974 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
96975 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
96976 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
96977 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
96978 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
96979 + uint32_t toct_u; /* D0 ifOutOctets */
96980 + uint32_t toct_l; /* D4 ifOutOctets */
96981 + uint32_t roct_u; /* D8 ifInOctets */
96982 + uint32_t roct_l; /* Dc ifInOctets */
96983 + uint32_t ruca_u; /* E0 ifInUcastPkts */
96984 + uint32_t ruca_l; /* E4 ifInUcastPkts */
96985 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
96986 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
96987 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
96988 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
96989 + uint32_t terr_u; /* F8 ifOutErrors */
96990 + uint32_t terr_l; /* Fc ifOutErrors */
96991 + uint32_t reserved100[2]; /* 100-108*/
96992 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
96993 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
96994 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
96995 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
96996 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
96997 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
96998 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
96999 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
97000 + uint32_t reoct_u; /* 128 etherStatsOctets */
97001 + uint32_t reoct_l; /* 12c etherStatsOctets */
97002 + uint32_t rpkt_u; /* 130 etherStatsPkts */
97003 + uint32_t rpkt_l; /* 134 etherStatsPkts */
97004 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
97005 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
97006 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
97007 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
97008 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
97009 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
97010 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
97011 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
97012 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
97013 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
97014 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
97015 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
97016 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
97017 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
97018 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
97019 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
97020 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
97021 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
97022 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
97023 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
97024 + uint32_t trfrg_u; /* 188 etherStatsFragments */
97025 + uint32_t trfrg_l; /* 18C etherStatsFragments */
97026 + uint32_t rerr_u; /* 190 ifInErrors */
97027 + uint32_t rerr_l; /* 194 ifInErrors */
97028 +};
97029 +
97030 +/**
97031 + * struct tgec_cfg - TGEC configuration
97032 + *
97033 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
97034 + * any frame received with an error is discarded in the
97035 + * Core and not forwarded to the Client interface.
97036 + * When set to 0 (Reset value), erroneous Frames are
97037 + * forwarded to the Client interface with ff_rx_err
97038 + * asserted.
97039 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
97040 + * frames are ignored by the MAC. When set to 0
97041 + * (Reset value) the transmit process is stopped for the
97042 + * amount of time specified in the pause quanta received
97043 + * within a pause frame.
97044 + * @pause_forward_enable:
97045 + * Terminate / Forward Pause Frames. If set to 1 pause
97046 + * frames are forwarded to the user application. When set
97047 + * to 0 (Reset value) pause frames are terminated and
97048 + * discarded within the MAC.
97049 + * @no_length_check_enable:
97050 + * Payload Length Check Disable. When set to 0
97051 + * (Reset value), the Core checks the frame's payload
97052 + * length with the Frame Length/Type field, when set to 1
97053 + * the payload length check is disabled.
97054 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
97055 + * all Command Frames are accepted, when set to 0
97056 + * (Reset Value) only Pause Frames are accepted and all
97057 + * other Command Frames are rejected.
97058 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
97059 + * permanently sends XGMII Idle sequences even when faults
97060 + * are received.
97061 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
97062 + * (0, default) of operation.
97063 + * @promiscuous_mode_enable:
97064 + * Enables MAC promiscuous operation. When set to 1, all
97065 + * frames are received without any MAC address filtering,
97066 + * when set to 0 (Reset value) Unicast Frames with a
97067 + * destination address not matching the Core MAC Address
97068 + * (MAC Address programmed in Registers MAC_ADDR_0 and
97069 + * MAC_ADDR_1 or the MAC address programmed in Registers
97070 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
97071 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
97072 + * MAC overwrites the source MAC address received from the
97073 + * Client Interface with one of the MAC addresses. If set
97074 + * to 0 (Reset value), the source MAC address from the
97075 + * Client Interface is transmitted unmodified to the line.
97076 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
97077 + * loop_ena is set to '1', when set to 0 (Reset value)
97078 + * the signal loop_ena is set to 0.
97079 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
97080 + * depending on the value of this Bit
97081 + * @time_stamp_enable: This bit selects between enabling and disabling the
97082 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
97083 + * 0: IEEE 1588 is disabled
97084 + * @max_frame_length: Maximum supported received frame length.
97085 + * The 10GEC MAC supports reception of any frame size up
97086 + * to 16,352 bytes (0x3FE0). Typical settings are
97087 + * 0x05EE (1,518 bytes) for standard frames.
97088 + * Default setting is 0x0600 (1,536 bytes).
97089 + * Received frames that exceed this stated maximum
97090 + * are truncated.
97091 + * @pause_quant: Pause quanta value used with transmitted pause frames.
97092 + * Each quanta represents a 512 bit-times.
97093 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
97094 + * Depending on LAN or WAN mode of operation the value has
97095 + * the following meaning: - LAN Mode: Number of octets in
97096 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
97097 + * fully supported (see 10.6.1 page 49) for any setting. A
97098 + * default of 12 (reset value) must be set to conform to
97099 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
97100 + * be able to perform clock rate compensation. - WAN Mode:
97101 + * Stretch factor. Valid values are 4..15. The stretch
97102 + * factor is calculated as (value+1)*8. A default of 12
97103 + * (reset value) must be set to conform to IEEE 802.3ae
97104 + * (i.e. 13*8=104). A larger value shrinks the IPG
97105 + * (increasing bandwidth).
97106 + *
97107 + * This structure contains basic TGEC configuration and must be passed to
97108 + * fman_tgec_init() function. A default set of configuration values can be
97109 + * obtained by calling fman_tgec_defconfig().
97110 + */
97111 +struct tgec_cfg {
97112 + bool rx_error_discard;
97113 + bool pause_ignore;
97114 + bool pause_forward_enable;
97115 + bool no_length_check_enable;
97116 + bool cmd_frame_enable;
97117 + bool send_idle_enable;
97118 + bool wan_mode_enable;
97119 + bool promiscuous_mode_enable;
97120 + bool tx_addr_ins_enable;
97121 + bool loopback_enable;
97122 + bool lgth_check_nostdr;
97123 + bool time_stamp_enable;
97124 + uint16_t max_frame_length;
97125 + uint16_t pause_quant;
97126 + uint32_t tx_ipg_length;
97127 + bool skip_fman11_workaround;
97128 +};
97129 +
97130 +
97131 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
97132 +
97133 +/**
97134 + * fman_tgec_init() - Init tgec hardware block
97135 + * @regs: Pointer to tgec register block
97136 + * @cfg: tgec configuration data
97137 + * @exceptions_mask: initial exceptions mask
97138 + *
97139 + * This function initializes the tgec controller and applies its
97140 + * basic configuration.
97141 + *
97142 + * Returns: 0 if successful, an error code otherwise.
97143 + */
97144 +
97145 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
97146 + uint32_t exception_mask);
97147 +
97148 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97149 +
97150 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
97151 +
97152 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
97153 +
97154 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
97155 +
97156 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
97157 +
97158 +/**
97159 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
97160 + * @regs: Pointer to TGEC register block
97161 + */
97162 +void fman_tgec_reset_stat(struct tgec_regs *regs);
97163 +
97164 +/**
97165 + * fman_tgec_get_counter() - Reads TGEC HW counters
97166 + * @regs: Pointer to TGEC register block
97167 + * @reg_name: Counter name according to the appropriate enum
97168 + *
97169 + * Returns: Required counter value
97170 + */
97171 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
97172 + enum tgec_counters reg_name);
97173 +
97174 +/**
97175 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
97176 + * @regs: Pointer to TGEC register block
97177 + * @value: Value to be written in Hashtable Control Register
97178 + */
97179 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
97180 +
97181 +/**
97182 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
97183 + * @regs: Pointer to TGEC register block
97184 + * @pause_time: Pause quanta value used with transmitted pause frames.
97185 + * Each quanta represents a 512 bit-times
97186 + */
97187 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
97188 +
97189 +/**
97190 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
97191 + * @regs: Pointer to TGEC register block
97192 + * @en: Ignore/Respond to pause frame quanta
97193 + *
97194 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
97195 + * 0 - MAC stops transmit process for the duration specified
97196 + * in the Pause frame quanta of a received Pause frame.
97197 + * 1 - MAC ignores received Pause frames.
97198 + */
97199 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
97200 +
97201 +/**
97202 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
97203 + * @regs: Pointer to TGEC register block
97204 + * @en: enable/disable timestamp functionality
97205 + *
97206 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
97207 + * IEEE 1588 timestamp functionality control:
97208 + * 0 disabled, 1 enabled
97209 + */
97210 +
97211 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
97212 +
97213 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
97214 +
97215 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
97216 +
97217 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
97218 +
97219 +/**
97220 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
97221 + * @regs: Pointer to TGEC register block
97222 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
97223 + *
97224 + * Sets the additional station MAC address
97225 + */
97226 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
97227 +
97228 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
97229 +
97230 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97231 +
97232 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
97233 +
97234 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
97235 +
97236 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
97237 +
97238 +
97239 +/**
97240 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
97241 + * @regs: Pointer to TGEC register block
97242 + */
97243 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
97244 +
97245 +/**
97246 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
97247 + * main tgec configuration parameters
97248 + * @regs: Pointer to TGEC register block
97249 + *
97250 + * TODO
97251 + */
97252 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
97253 + *regs);
97254 +
97255 +
97256 +#endif /* __FSL_FMAN_TGEC_H */
97257 --- /dev/null
97258 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
97259 @@ -0,0 +1,291 @@
97260 +/*
97261 + * Copyright 2012 Freescale Semiconductor Inc.
97262 + *
97263 + * Redistribution and use in source and binary forms, with or without
97264 + * modification, are permitted provided that the following conditions are met:
97265 + * * Redistributions of source code must retain the above copyright
97266 + * notice, this list of conditions and the following disclaimer.
97267 + * * Redistributions in binary form must reproduce the above copyright
97268 + * notice, this list of conditions and the following disclaimer in the
97269 + * documentation and/or other materials provided with the distribution.
97270 + * * Neither the name of Freescale Semiconductor nor the
97271 + * names of its contributors may be used to endorse or promote products
97272 + * derived from this software without specific prior written permission.
97273 + *
97274 + *
97275 + * ALTERNATIVELY, this software may be distributed under the terms of the
97276 + * GNU General Public License ("GPL") as published by the Free Software
97277 + * Foundation, either version 2 of that License or (at your option) any
97278 + * later version.
97279 + *
97280 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97281 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97282 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97283 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97284 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97285 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97286 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97287 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97288 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97289 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97290 + */
97291 +
97292 +/**
97293 +
97294 + @File dpaa_integration_ext.h
97295 +
97296 + @Description T4240 FM external definitions and structures.
97297 +*//***************************************************************************/
97298 +#ifndef __DPAA_INTEGRATION_EXT_H
97299 +#define __DPAA_INTEGRATION_EXT_H
97300 +
97301 +#include "std_ext.h"
97302 +
97303 +
97304 +#define DPAA_VERSION 11
97305 +
97306 +/**************************************************************************//**
97307 + @Description DPAA SW Portals Enumeration.
97308 +*//***************************************************************************/
97309 +typedef enum
97310 +{
97311 + e_DPAA_SWPORTAL0 = 0,
97312 + e_DPAA_SWPORTAL1,
97313 + e_DPAA_SWPORTAL2,
97314 + e_DPAA_SWPORTAL3,
97315 + e_DPAA_SWPORTAL4,
97316 + e_DPAA_SWPORTAL5,
97317 + e_DPAA_SWPORTAL6,
97318 + e_DPAA_SWPORTAL7,
97319 + e_DPAA_SWPORTAL8,
97320 + e_DPAA_SWPORTAL9,
97321 + e_DPAA_SWPORTAL10,
97322 + e_DPAA_SWPORTAL11,
97323 + e_DPAA_SWPORTAL12,
97324 + e_DPAA_SWPORTAL13,
97325 + e_DPAA_SWPORTAL14,
97326 + e_DPAA_SWPORTAL15,
97327 + e_DPAA_SWPORTAL16,
97328 + e_DPAA_SWPORTAL17,
97329 + e_DPAA_SWPORTAL18,
97330 + e_DPAA_SWPORTAL19,
97331 + e_DPAA_SWPORTAL20,
97332 + e_DPAA_SWPORTAL21,
97333 + e_DPAA_SWPORTAL22,
97334 + e_DPAA_SWPORTAL23,
97335 + e_DPAA_SWPORTAL24,
97336 + e_DPAA_SWPORTAL_DUMMY_LAST
97337 +} e_DpaaSwPortal;
97338 +
97339 +/**************************************************************************//**
97340 + @Description DPAA Direct Connect Portals Enumeration.
97341 +*//***************************************************************************/
97342 +typedef enum
97343 +{
97344 + e_DPAA_DCPORTAL0 = 0,
97345 + e_DPAA_DCPORTAL1,
97346 + e_DPAA_DCPORTAL2,
97347 + e_DPAA_DCPORTAL_DUMMY_LAST
97348 +} e_DpaaDcPortal;
97349 +
97350 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
97351 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
97352 +
97353 +/*****************************************************************************
97354 + QMan INTEGRATION-SPECIFIC DEFINITIONS
97355 +******************************************************************************/
97356 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
97357 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
97358 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
97359 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
97360 + /**< FQIDs range - 24 bits */
97361 +
97362 +/**************************************************************************//**
97363 + @Description Work Queue Channel assignments in QMan.
97364 +*//***************************************************************************/
97365 +typedef enum
97366 +{
97367 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
97368 + e_QM_FQ_CHANNEL_SWPORTAL1,
97369 + e_QM_FQ_CHANNEL_SWPORTAL2,
97370 + e_QM_FQ_CHANNEL_SWPORTAL3,
97371 + e_QM_FQ_CHANNEL_SWPORTAL4,
97372 + e_QM_FQ_CHANNEL_SWPORTAL5,
97373 + e_QM_FQ_CHANNEL_SWPORTAL6,
97374 + e_QM_FQ_CHANNEL_SWPORTAL7,
97375 + e_QM_FQ_CHANNEL_SWPORTAL8,
97376 + e_QM_FQ_CHANNEL_SWPORTAL9,
97377 + e_QM_FQ_CHANNEL_SWPORTAL10,
97378 + e_QM_FQ_CHANNEL_SWPORTAL11,
97379 + e_QM_FQ_CHANNEL_SWPORTAL12,
97380 + e_QM_FQ_CHANNEL_SWPORTAL13,
97381 + e_QM_FQ_CHANNEL_SWPORTAL14,
97382 + e_QM_FQ_CHANNEL_SWPORTAL15,
97383 + e_QM_FQ_CHANNEL_SWPORTAL16,
97384 + e_QM_FQ_CHANNEL_SWPORTAL17,
97385 + e_QM_FQ_CHANNEL_SWPORTAL18,
97386 + e_QM_FQ_CHANNEL_SWPORTAL19,
97387 + e_QM_FQ_CHANNEL_SWPORTAL20,
97388 + e_QM_FQ_CHANNEL_SWPORTAL21,
97389 + e_QM_FQ_CHANNEL_SWPORTAL22,
97390 + e_QM_FQ_CHANNEL_SWPORTAL23,
97391 + e_QM_FQ_CHANNEL_SWPORTAL24,
97392 +
97393 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
97394 + e_QM_FQ_CHANNEL_POOL2,
97395 + e_QM_FQ_CHANNEL_POOL3,
97396 + e_QM_FQ_CHANNEL_POOL4,
97397 + e_QM_FQ_CHANNEL_POOL5,
97398 + e_QM_FQ_CHANNEL_POOL6,
97399 + e_QM_FQ_CHANNEL_POOL7,
97400 + e_QM_FQ_CHANNEL_POOL8,
97401 + e_QM_FQ_CHANNEL_POOL9,
97402 + e_QM_FQ_CHANNEL_POOL10,
97403 + e_QM_FQ_CHANNEL_POOL11,
97404 + e_QM_FQ_CHANNEL_POOL12,
97405 + e_QM_FQ_CHANNEL_POOL13,
97406 + e_QM_FQ_CHANNEL_POOL14,
97407 + e_QM_FQ_CHANNEL_POOL15,
97408 +
97409 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
97410 + connected to FMan 0; assigned in incrementing order to
97411 + each sub-portal (SP) in the portal */
97412 + e_QM_FQ_CHANNEL_FMAN0_SP1,
97413 + e_QM_FQ_CHANNEL_FMAN0_SP2,
97414 + e_QM_FQ_CHANNEL_FMAN0_SP3,
97415 + e_QM_FQ_CHANNEL_FMAN0_SP4,
97416 + e_QM_FQ_CHANNEL_FMAN0_SP5,
97417 + e_QM_FQ_CHANNEL_FMAN0_SP6,
97418 + e_QM_FQ_CHANNEL_FMAN0_SP7,
97419 + e_QM_FQ_CHANNEL_FMAN0_SP8,
97420 + e_QM_FQ_CHANNEL_FMAN0_SP9,
97421 + e_QM_FQ_CHANNEL_FMAN0_SP10,
97422 + e_QM_FQ_CHANNEL_FMAN0_SP11,
97423 + e_QM_FQ_CHANNEL_FMAN0_SP12,
97424 + e_QM_FQ_CHANNEL_FMAN0_SP13,
97425 + e_QM_FQ_CHANNEL_FMAN0_SP14,
97426 + e_QM_FQ_CHANNEL_FMAN0_SP15,
97427 +
97428 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
97429 + e_QM_FQ_CHANNEL_RMAN_SP1,
97430 +
97431 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
97432 + connected to SEC */
97433 +} e_QmFQChannel;
97434 +
97435 +/*****************************************************************************
97436 + BMan INTEGRATION-SPECIFIC DEFINITIONS
97437 +******************************************************************************/
97438 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
97439 +
97440 +/*****************************************************************************
97441 + SEC INTEGRATION-SPECIFIC DEFINITIONS
97442 +******************************************************************************/
97443 +#define SEC_NUM_OF_DECOS 3
97444 +#define SEC_ALL_DECOS_MASK 0x00000003
97445 +
97446 +
97447 +/*****************************************************************************
97448 + FM INTEGRATION-SPECIFIC DEFINITIONS
97449 +******************************************************************************/
97450 +#define INTG_MAX_NUM_OF_FM 2
97451 +/* Ports defines */
97452 +#define FM_MAX_NUM_OF_1G_MACS 6
97453 +#define FM_MAX_NUM_OF_10G_MACS 2
97454 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
97455 +#define FM_MAX_NUM_OF_OH_PORTS 6
97456 +
97457 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
97458 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
97459 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
97460 +
97461 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
97462 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
97463 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
97464 +
97465 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
97466 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
97467 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
97468 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
97469 +
97470 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
97471 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
97472 +
97473 +/* RAMs defines */
97474 +#define FM_MURAM_SIZE (384 * KILOBYTE)
97475 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
97476 +#define FM_NUM_OF_CTRL 4
97477 +
97478 +/* PCD defines */
97479 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
97480 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
97481 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
97482 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
97483 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
97484 +
97485 +/* RTC defines */
97486 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
97487 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
97488 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
97489 +
97490 +/* QMI defines */
97491 +#define QMI_MAX_NUM_OF_TNUMS 64
97492 +#define QMI_DEF_TNUMS_THRESH 32
97493 +/* FPM defines */
97494 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
97495 +
97496 +/* DMA defines */
97497 +#define DMA_THRESH_MAX_COMMQ 83
97498 +#define DMA_THRESH_MAX_BUF 127
97499 +
97500 +/* BMI defines */
97501 +#define BMI_MAX_NUM_OF_TASKS 128
97502 +#define BMI_MAX_NUM_OF_DMAS 84
97503 +
97504 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
97505 +#define PORT_MAX_WEIGHT 16
97506 +
97507 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
97508 +
97509 +/* Unique T4240 */
97510 +#define FM_OP_OPEN_DMA_MIN_LIMIT
97511 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
97512 +#define FM_NO_OP_OBSERVED_POOLS
97513 +#define FM_FRAME_END_PARAMS_FOR_OP
97514 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
97515 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
97516 +
97517 +#define FM_NO_GUARANTEED_RESET_VALUES
97518 +
97519 +/* FM errata */
97520 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
97521 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
97522 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
97523 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
97524 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
97525 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
97526 +
97527 +#define FM_BCB_ERRATA_BMI_SW001
97528 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
97529 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
97530 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
97531 +
97532 +/*****************************************************************************
97533 + RMan INTEGRATION-SPECIFIC DEFINITIONS
97534 +******************************************************************************/
97535 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
97536 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
97537 +
97538 +/* RMan erratas */
97539 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
97540 +
97541 +/*****************************************************************************
97542 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
97543 +******************************************************************************/
97544 +#define NUM_OF_RX_SC 16
97545 +#define NUM_OF_TX_SC 16
97546 +
97547 +#define NUM_OF_SA_PER_RX_SC 2
97548 +#define NUM_OF_SA_PER_TX_SC 2
97549 +
97550 +#endif /* __DPAA_INTEGRATION_EXT_H */
97551 --- /dev/null
97552 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
97553 @@ -0,0 +1,71 @@
97554 +/*
97555 + * Copyright 2012 Freescale Semiconductor Inc.
97556 + *
97557 + * Redistribution and use in source and binary forms, with or without
97558 + * modification, are permitted provided that the following conditions are met:
97559 + * * Redistributions of source code must retain the above copyright
97560 + * notice, this list of conditions and the following disclaimer.
97561 + * * Redistributions in binary form must reproduce the above copyright
97562 + * notice, this list of conditions and the following disclaimer in the
97563 + * documentation and/or other materials provided with the distribution.
97564 + * * Neither the name of Freescale Semiconductor nor the
97565 + * names of its contributors may be used to endorse or promote products
97566 + * derived from this software without specific prior written permission.
97567 + *
97568 + *
97569 + * ALTERNATIVELY, this software may be distributed under the terms of the
97570 + * GNU General Public License ("GPL") as published by the Free Software
97571 + * Foundation, either version 2 of that License or (at your option) any
97572 + * later version.
97573 + *
97574 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97575 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97576 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97577 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97578 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97579 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97580 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97581 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97582 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97583 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97584 + */
97585 +
97586 +/**************************************************************************//**
97587 +
97588 + @File part_ext.h
97589 +
97590 + @Description Definitions for the part (integration) module.
97591 +*//***************************************************************************/
97592 +
97593 +#ifndef __PART_EXT_H
97594 +#define __PART_EXT_H
97595 +
97596 +#include "std_ext.h"
97597 +#include "part_integration_ext.h"
97598 +
97599 +#if !(defined(P1023) || \
97600 + defined(P2041) || \
97601 + defined(P3041) || \
97602 + defined(P4080) || \
97603 + defined(P5020) || \
97604 + defined(P5040) || \
97605 + defined(B4860) || \
97606 + defined(T4240))
97607 +#error "unable to proceed without chip-definition"
97608 +#endif
97609 +
97610 +
97611 +/**************************************************************************//*
97612 + @Description Part data structure - must be contained in any integration
97613 + data structure.
97614 +*//***************************************************************************/
97615 +typedef struct t_Part
97616 +{
97617 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
97618 + /**< Returns the address of the module's memory map base. */
97619 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
97620 + /**< Returns the module's ID according to its memory map base. */
97621 +} t_Part;
97622 +
97623 +
97624 +#endif /* __PART_EXT_H */
97625 --- /dev/null
97626 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
97627 @@ -0,0 +1,304 @@
97628 +/*
97629 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97630 + *
97631 + * Redistribution and use in source and binary forms, with or without
97632 + * modification, are permitted provided that the following conditions are met:
97633 + * * Redistributions of source code must retain the above copyright
97634 + * notice, this list of conditions and the following disclaimer.
97635 + * * Redistributions in binary form must reproduce the above copyright
97636 + * notice, this list of conditions and the following disclaimer in the
97637 + * documentation and/or other materials provided with the distribution.
97638 + * * Neither the name of Freescale Semiconductor nor the
97639 + * names of its contributors may be used to endorse or promote products
97640 + * derived from this software without specific prior written permission.
97641 + *
97642 + *
97643 + * ALTERNATIVELY, this software may be distributed under the terms of the
97644 + * GNU General Public License ("GPL") as published by the Free Software
97645 + * Foundation, either version 2 of that License or (at your option) any
97646 + * later version.
97647 + *
97648 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97649 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97650 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97651 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97652 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97653 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97654 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97655 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97656 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97657 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97658 + */
97659 +
97660 +/**
97661 +
97662 + @File part_integration_ext.h
97663 +
97664 + @Description T4240 external definitions and structures.
97665 +*//***************************************************************************/
97666 +#ifndef __PART_INTEGRATION_EXT_H
97667 +#define __PART_INTEGRATION_EXT_H
97668 +
97669 +#include "std_ext.h"
97670 +#include "ddr_std_ext.h"
97671 +#include "enet_ext.h"
97672 +#include "dpaa_integration_ext.h"
97673 +
97674 +
97675 +/**************************************************************************//**
97676 + @Group T4240_chip_id T4240 Application Programming Interface
97677 +
97678 + @Description T4240 Chip functions,definitions and enums.
97679 +
97680 + @{
97681 +*//***************************************************************************/
97682 +
97683 +#define CORE_E6500
97684 +
97685 +#define INTG_MAX_NUM_OF_CORES 24
97686 +
97687 +
97688 +/**************************************************************************//**
97689 + @Description Module types.
97690 +*//***************************************************************************/
97691 +typedef enum e_ModuleId
97692 +{
97693 + e_MODULE_ID_DUART_1 = 0,
97694 + e_MODULE_ID_DUART_2,
97695 + e_MODULE_ID_DUART_3,
97696 + e_MODULE_ID_DUART_4,
97697 + e_MODULE_ID_LAW,
97698 + e_MODULE_ID_IFC,
97699 + e_MODULE_ID_PAMU,
97700 + e_MODULE_ID_QM, /**< Queue manager module */
97701 + e_MODULE_ID_BM, /**< Buffer manager module */
97702 + e_MODULE_ID_QM_CE_PORTAL_0,
97703 + e_MODULE_ID_QM_CI_PORTAL_0,
97704 + e_MODULE_ID_QM_CE_PORTAL_1,
97705 + e_MODULE_ID_QM_CI_PORTAL_1,
97706 + e_MODULE_ID_QM_CE_PORTAL_2,
97707 + e_MODULE_ID_QM_CI_PORTAL_2,
97708 + e_MODULE_ID_QM_CE_PORTAL_3,
97709 + e_MODULE_ID_QM_CI_PORTAL_3,
97710 + e_MODULE_ID_QM_CE_PORTAL_4,
97711 + e_MODULE_ID_QM_CI_PORTAL_4,
97712 + e_MODULE_ID_QM_CE_PORTAL_5,
97713 + e_MODULE_ID_QM_CI_PORTAL_5,
97714 + e_MODULE_ID_QM_CE_PORTAL_6,
97715 + e_MODULE_ID_QM_CI_PORTAL_6,
97716 + e_MODULE_ID_QM_CE_PORTAL_7,
97717 + e_MODULE_ID_QM_CI_PORTAL_7,
97718 + e_MODULE_ID_QM_CE_PORTAL_8,
97719 + e_MODULE_ID_QM_CI_PORTAL_8,
97720 + e_MODULE_ID_QM_CE_PORTAL_9,
97721 + e_MODULE_ID_QM_CI_PORTAL_9,
97722 + e_MODULE_ID_BM_CE_PORTAL_0,
97723 + e_MODULE_ID_BM_CI_PORTAL_0,
97724 + e_MODULE_ID_BM_CE_PORTAL_1,
97725 + e_MODULE_ID_BM_CI_PORTAL_1,
97726 + e_MODULE_ID_BM_CE_PORTAL_2,
97727 + e_MODULE_ID_BM_CI_PORTAL_2,
97728 + e_MODULE_ID_BM_CE_PORTAL_3,
97729 + e_MODULE_ID_BM_CI_PORTAL_3,
97730 + e_MODULE_ID_BM_CE_PORTAL_4,
97731 + e_MODULE_ID_BM_CI_PORTAL_4,
97732 + e_MODULE_ID_BM_CE_PORTAL_5,
97733 + e_MODULE_ID_BM_CI_PORTAL_5,
97734 + e_MODULE_ID_BM_CE_PORTAL_6,
97735 + e_MODULE_ID_BM_CI_PORTAL_6,
97736 + e_MODULE_ID_BM_CE_PORTAL_7,
97737 + e_MODULE_ID_BM_CI_PORTAL_7,
97738 + e_MODULE_ID_BM_CE_PORTAL_8,
97739 + e_MODULE_ID_BM_CI_PORTAL_8,
97740 + e_MODULE_ID_BM_CE_PORTAL_9,
97741 + e_MODULE_ID_BM_CI_PORTAL_9,
97742 + e_MODULE_ID_FM, /**< Frame manager module */
97743 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
97744 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
97745 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
97746 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
97747 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
97748 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
97749 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
97750 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
97751 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
97752 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
97753 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
97754 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
97755 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
97756 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
97757 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
97758 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
97759 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
97760 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
97761 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
97762 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
97763 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
97764 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
97765 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
97766 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
97767 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
97768 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
97769 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
97770 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
97771 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
97772 + e_MODULE_ID_FM_KG, /**< FM Keygen */
97773 + e_MODULE_ID_FM_DMA, /**< FM DMA */
97774 + e_MODULE_ID_FM_FPM, /**< FM FPM */
97775 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
97776 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
97777 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
97778 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
97779 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
97780 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
97781 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
97782 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
97783 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
97784 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
97785 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
97786 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
97787 +
97788 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
97789 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
97790 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
97791 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
97792 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
97793 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
97794 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
97795 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
97796 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
97797 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
97798 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
97799 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
97800 +
97801 + e_MODULE_ID_PIC, /**< PIC */
97802 + e_MODULE_ID_GPIO, /**< GPIO */
97803 + e_MODULE_ID_SERDES, /**< SERDES */
97804 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
97805 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
97806 +
97807 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
97808 +
97809 + e_MODULE_ID_DUMMY_LAST
97810 +} e_ModuleId;
97811 +
97812 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
97813 +
97814 +#if 0 /* using unified values */
97815 +/*****************************************************************************
97816 + INTEGRATION-SPECIFIC MODULE CODES
97817 +******************************************************************************/
97818 +#define MODULE_UNKNOWN 0x00000000
97819 +#define MODULE_MEM 0x00010000
97820 +#define MODULE_MM 0x00020000
97821 +#define MODULE_CORE 0x00030000
97822 +#define MODULE_T4240 0x00040000
97823 +#define MODULE_T4240_PLATFORM 0x00050000
97824 +#define MODULE_PM 0x00060000
97825 +#define MODULE_MMU 0x00070000
97826 +#define MODULE_PIC 0x00080000
97827 +#define MODULE_CPC 0x00090000
97828 +#define MODULE_DUART 0x000a0000
97829 +#define MODULE_SERDES 0x000b0000
97830 +#define MODULE_PIO 0x000c0000
97831 +#define MODULE_QM 0x000d0000
97832 +#define MODULE_BM 0x000e0000
97833 +#define MODULE_SEC 0x000f0000
97834 +#define MODULE_LAW 0x00100000
97835 +#define MODULE_LBC 0x00110000
97836 +#define MODULE_PAMU 0x00120000
97837 +#define MODULE_FM 0x00130000
97838 +#define MODULE_FM_MURAM 0x00140000
97839 +#define MODULE_FM_PCD 0x00150000
97840 +#define MODULE_FM_RTC 0x00160000
97841 +#define MODULE_FM_MAC 0x00170000
97842 +#define MODULE_FM_PORT 0x00180000
97843 +#define MODULE_FM_SP 0x00190000
97844 +#define MODULE_DPA_PORT 0x001a0000
97845 +#define MODULE_MII 0x001b0000
97846 +#define MODULE_I2C 0x001c0000
97847 +#define MODULE_DMA 0x001d0000
97848 +#define MODULE_DDR 0x001e0000
97849 +#define MODULE_ESPI 0x001f0000
97850 +#define MODULE_DPAA_IPSEC 0x00200000
97851 +#endif /* using unified values */
97852 +
97853 +/*****************************************************************************
97854 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
97855 +******************************************************************************/
97856 +#define PAMU_NUM_OF_PARTITIONS 4
97857 +
97858 +/*****************************************************************************
97859 + LAW INTEGRATION-SPECIFIC DEFINITIONS
97860 +******************************************************************************/
97861 +#define LAW_NUM_OF_WINDOWS 32
97862 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
97863 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
97864 +
97865 +
97866 +/*****************************************************************************
97867 + LBC INTEGRATION-SPECIFIC DEFINITIONS
97868 +******************************************************************************/
97869 +/**************************************************************************//**
97870 + @Group lbc_exception_grp LBC Exception Unit
97871 +
97872 + @Description LBC Exception unit API functions, definitions and enums
97873 +
97874 + @{
97875 +*//***************************************************************************/
97876 +
97877 +/**************************************************************************//**
97878 + @Anchor lbc_exbm
97879 +
97880 + @Collection LBC Errors Bit Mask
97881 +
97882 + These errors are reported through the exceptions callback..
97883 + The values can be or'ed in any combination in the errors mask
97884 + parameter of the errors report structure.
97885 +
97886 + These errors can also be passed as a bit-mask to
97887 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
97888 + for enabling or disabling error checking.
97889 + @{
97890 +*//***************************************************************************/
97891 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
97892 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
97893 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
97894 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
97895 +
97896 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
97897 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
97898 + /**< All possible errors */
97899 +/* @} */
97900 +/** @} */ /* end of lbc_exception_grp group */
97901 +
97902 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
97903 +
97904 +#define LBC_NUM_OF_BANKS 8
97905 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
97906 +#define LBC_PARITY_SUPPORT
97907 +#define LBC_ADDRESS_HOLD_TIME_CTRL
97908 +#define LBC_HIGH_CLK_DIVIDERS
97909 +#define LBC_FCM_AVAILABLE
97910 +
97911 +/*****************************************************************************
97912 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
97913 +******************************************************************************/
97914 +#define GPIO_PORT_OFFSET_0x1000
97915 +
97916 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
97917 + Each port contains up to 32 I/O pins. */
97918 +
97919 +#define GPIO_VALID_PIN_MASKS \
97920 + { /* Port A */ 0xFFFFFFFF, \
97921 + /* Port B */ 0xFFFFFFFF, \
97922 + /* Port C */ 0xFFFFFFFF }
97923 +
97924 +#define GPIO_VALID_INTR_MASKS \
97925 + { /* Port A */ 0xFFFFFFFF, \
97926 + /* Port B */ 0xFFFFFFFF, \
97927 + /* Port C */ 0xFFFFFFFF }
97928 +
97929 +
97930 +
97931 +#endif /* __PART_INTEGRATION_EXT_H */
97932 --- /dev/null
97933 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
97934 @@ -0,0 +1,293 @@
97935 +/*
97936 + * Copyright 2012 Freescale Semiconductor Inc.
97937 + *
97938 + * Redistribution and use in source and binary forms, with or without
97939 + * modification, are permitted provided that the following conditions are met:
97940 + * * Redistributions of source code must retain the above copyright
97941 + * notice, this list of conditions and the following disclaimer.
97942 + * * Redistributions in binary form must reproduce the above copyright
97943 + * notice, this list of conditions and the following disclaimer in the
97944 + * documentation and/or other materials provided with the distribution.
97945 + * * Neither the name of Freescale Semiconductor nor the
97946 + * names of its contributors may be used to endorse or promote products
97947 + * derived from this software without specific prior written permission.
97948 + *
97949 + *
97950 + * ALTERNATIVELY, this software may be distributed under the terms of the
97951 + * GNU General Public License ("GPL") as published by the Free Software
97952 + * Foundation, either version 2 of that License or (at your option) any
97953 + * later version.
97954 + *
97955 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97956 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97957 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97958 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97959 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97960 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97961 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97962 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97963 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97964 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97965 + */
97966 +
97967 +/**
97968 +
97969 + @File dpaa_integration_ext.h
97970 +
97971 + @Description T4240 FM external definitions and structures.
97972 +*//***************************************************************************/
97973 +#ifndef __DPAA_INTEGRATION_EXT_H
97974 +#define __DPAA_INTEGRATION_EXT_H
97975 +
97976 +#include "std_ext.h"
97977 +
97978 +
97979 +#define DPAA_VERSION 11
97980 +
97981 +/**************************************************************************//**
97982 + @Description DPAA SW Portals Enumeration.
97983 +*//***************************************************************************/
97984 +typedef enum
97985 +{
97986 + e_DPAA_SWPORTAL0 = 0,
97987 + e_DPAA_SWPORTAL1,
97988 + e_DPAA_SWPORTAL2,
97989 + e_DPAA_SWPORTAL3,
97990 + e_DPAA_SWPORTAL4,
97991 + e_DPAA_SWPORTAL5,
97992 + e_DPAA_SWPORTAL6,
97993 + e_DPAA_SWPORTAL7,
97994 + e_DPAA_SWPORTAL8,
97995 + e_DPAA_SWPORTAL9,
97996 + e_DPAA_SWPORTAL10,
97997 + e_DPAA_SWPORTAL11,
97998 + e_DPAA_SWPORTAL12,
97999 + e_DPAA_SWPORTAL13,
98000 + e_DPAA_SWPORTAL14,
98001 + e_DPAA_SWPORTAL15,
98002 + e_DPAA_SWPORTAL16,
98003 + e_DPAA_SWPORTAL17,
98004 + e_DPAA_SWPORTAL18,
98005 + e_DPAA_SWPORTAL19,
98006 + e_DPAA_SWPORTAL20,
98007 + e_DPAA_SWPORTAL21,
98008 + e_DPAA_SWPORTAL22,
98009 + e_DPAA_SWPORTAL23,
98010 + e_DPAA_SWPORTAL24,
98011 + e_DPAA_SWPORTAL_DUMMY_LAST
98012 +} e_DpaaSwPortal;
98013 +
98014 +/**************************************************************************//**
98015 + @Description DPAA Direct Connect Portals Enumeration.
98016 +*//***************************************************************************/
98017 +typedef enum
98018 +{
98019 + e_DPAA_DCPORTAL0 = 0,
98020 + e_DPAA_DCPORTAL1,
98021 + e_DPAA_DCPORTAL2,
98022 + e_DPAA_DCPORTAL_DUMMY_LAST
98023 +} e_DpaaDcPortal;
98024 +
98025 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98026 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98027 +
98028 +/*****************************************************************************
98029 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98030 +******************************************************************************/
98031 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98032 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98033 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98034 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98035 + /**< FQIDs range - 24 bits */
98036 +
98037 +/**************************************************************************//**
98038 + @Description Work Queue Channel assignments in QMan.
98039 +*//***************************************************************************/
98040 +typedef enum
98041 +{
98042 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98043 + e_QM_FQ_CHANNEL_SWPORTAL1,
98044 + e_QM_FQ_CHANNEL_SWPORTAL2,
98045 + e_QM_FQ_CHANNEL_SWPORTAL3,
98046 + e_QM_FQ_CHANNEL_SWPORTAL4,
98047 + e_QM_FQ_CHANNEL_SWPORTAL5,
98048 + e_QM_FQ_CHANNEL_SWPORTAL6,
98049 + e_QM_FQ_CHANNEL_SWPORTAL7,
98050 + e_QM_FQ_CHANNEL_SWPORTAL8,
98051 + e_QM_FQ_CHANNEL_SWPORTAL9,
98052 + e_QM_FQ_CHANNEL_SWPORTAL10,
98053 + e_QM_FQ_CHANNEL_SWPORTAL11,
98054 + e_QM_FQ_CHANNEL_SWPORTAL12,
98055 + e_QM_FQ_CHANNEL_SWPORTAL13,
98056 + e_QM_FQ_CHANNEL_SWPORTAL14,
98057 + e_QM_FQ_CHANNEL_SWPORTAL15,
98058 + e_QM_FQ_CHANNEL_SWPORTAL16,
98059 + e_QM_FQ_CHANNEL_SWPORTAL17,
98060 + e_QM_FQ_CHANNEL_SWPORTAL18,
98061 + e_QM_FQ_CHANNEL_SWPORTAL19,
98062 + e_QM_FQ_CHANNEL_SWPORTAL20,
98063 + e_QM_FQ_CHANNEL_SWPORTAL21,
98064 + e_QM_FQ_CHANNEL_SWPORTAL22,
98065 + e_QM_FQ_CHANNEL_SWPORTAL23,
98066 + e_QM_FQ_CHANNEL_SWPORTAL24,
98067 +
98068 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98069 + e_QM_FQ_CHANNEL_POOL2,
98070 + e_QM_FQ_CHANNEL_POOL3,
98071 + e_QM_FQ_CHANNEL_POOL4,
98072 + e_QM_FQ_CHANNEL_POOL5,
98073 + e_QM_FQ_CHANNEL_POOL6,
98074 + e_QM_FQ_CHANNEL_POOL7,
98075 + e_QM_FQ_CHANNEL_POOL8,
98076 + e_QM_FQ_CHANNEL_POOL9,
98077 + e_QM_FQ_CHANNEL_POOL10,
98078 + e_QM_FQ_CHANNEL_POOL11,
98079 + e_QM_FQ_CHANNEL_POOL12,
98080 + e_QM_FQ_CHANNEL_POOL13,
98081 + e_QM_FQ_CHANNEL_POOL14,
98082 + e_QM_FQ_CHANNEL_POOL15,
98083 +
98084 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98085 + connected to FMan 0; assigned in incrementing order to
98086 + each sub-portal (SP) in the portal */
98087 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98088 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98089 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98090 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98091 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98092 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98093 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98094 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98095 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98096 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98097 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98098 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98099 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98100 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98101 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98102 +
98103 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98104 + e_QM_FQ_CHANNEL_RMAN_SP1,
98105 +
98106 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98107 + connected to SEC */
98108 +} e_QmFQChannel;
98109 +
98110 +/*****************************************************************************
98111 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98112 +******************************************************************************/
98113 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98114 +
98115 +/*****************************************************************************
98116 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98117 +******************************************************************************/
98118 +#define SEC_NUM_OF_DECOS 3
98119 +#define SEC_ALL_DECOS_MASK 0x00000003
98120 +
98121 +
98122 +/*****************************************************************************
98123 + FM INTEGRATION-SPECIFIC DEFINITIONS
98124 +******************************************************************************/
98125 +#define INTG_MAX_NUM_OF_FM 1
98126 +/* Ports defines */
98127 +#define FM_MAX_NUM_OF_1G_MACS 5
98128 +#define FM_MAX_NUM_OF_10G_MACS 1
98129 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98130 +#define FM_MAX_NUM_OF_OH_PORTS 4
98131 +
98132 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98133 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98134 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98135 +
98136 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98137 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98138 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98139 +
98140 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
98141 +
98142 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98143 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98144 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98145 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98146 +
98147 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
98148 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98149 +
98150 +/* RAMs defines */
98151 +#define FM_MURAM_SIZE (192 * KILOBYTE)
98152 +#define FM_IRAM_SIZE(major, minor) \
98153 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
98154 +#define FM_NUM_OF_CTRL 2
98155 +
98156 +/* PCD defines */
98157 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98158 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98159 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98160 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98161 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98162 +
98163 +/* RTC defines */
98164 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98165 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98166 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98167 +
98168 +/* QMI defines */
98169 +#define QMI_MAX_NUM_OF_TNUMS 64
98170 +#define QMI_DEF_TNUMS_THRESH 32
98171 +/* FPM defines */
98172 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98173 +
98174 +/* DMA defines */
98175 +#define DMA_THRESH_MAX_COMMQ 83
98176 +#define DMA_THRESH_MAX_BUF 127
98177 +
98178 +/* BMI defines */
98179 +#define BMI_MAX_NUM_OF_TASKS 64
98180 +#define BMI_MAX_NUM_OF_DMAS 32
98181 +
98182 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98183 +#define PORT_MAX_WEIGHT 16
98184 +
98185 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98186 +
98187 +/* Unique T4240 */
98188 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98189 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98190 +#define FM_NO_OP_OBSERVED_POOLS
98191 +#define FM_FRAME_END_PARAMS_FOR_OP
98192 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98193 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98194 +
98195 +#define FM_NO_GUARANTEED_RESET_VALUES
98196 +
98197 +/* FM errata */
98198 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98199 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98200 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98201 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98202 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
98203 +
98204 +#define FM_BCB_ERRATA_BMI_SW001
98205 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98206 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98207 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98208 +
98209 +/*****************************************************************************
98210 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98211 +******************************************************************************/
98212 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98213 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98214 +
98215 +/* RMan erratas */
98216 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98217 +
98218 +/*****************************************************************************
98219 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98220 +******************************************************************************/
98221 +#define NUM_OF_RX_SC 16
98222 +#define NUM_OF_TX_SC 16
98223 +
98224 +#define NUM_OF_SA_PER_RX_SC 2
98225 +#define NUM_OF_SA_PER_TX_SC 2
98226 +
98227 +#endif /* __DPAA_INTEGRATION_EXT_H */
98228 --- /dev/null
98229 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
98230 @@ -0,0 +1,59 @@
98231 +/*
98232 + * Copyright 2012 Freescale Semiconductor Inc.
98233 + *
98234 + * Redistribution and use in source and binary forms, with or without
98235 + * modification, are permitted provided that the following conditions are met:
98236 + * * Redistributions of source code must retain the above copyright
98237 + * notice, this list of conditions and the following disclaimer.
98238 + * * Redistributions in binary form must reproduce the above copyright
98239 + * notice, this list of conditions and the following disclaimer in the
98240 + * documentation and/or other materials provided with the distribution.
98241 + * * Neither the name of Freescale Semiconductor nor the
98242 + * names of its contributors may be used to endorse or promote products
98243 + * derived from this software without specific prior written permission.
98244 + *
98245 + *
98246 + * ALTERNATIVELY, this software may be distributed under the terms of the
98247 + * GNU General Public License ("GPL") as published by the Free Software
98248 + * Foundation, either version 2 of that License or (at your option) any
98249 + * later version.
98250 + *
98251 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98252 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98253 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98254 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98255 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98256 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98257 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98258 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98259 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98260 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98261 + */
98262 +
98263 +/**************************************************************************//**
98264 +
98265 + @File part_ext.h
98266 +
98267 + @Description Definitions for the part (integration) module.
98268 +*//***************************************************************************/
98269 +
98270 +#ifndef __PART_EXT_H
98271 +#define __PART_EXT_H
98272 +
98273 +#include "std_ext.h"
98274 +#include "part_integration_ext.h"
98275 +
98276 +/**************************************************************************//*
98277 + @Description Part data structure - must be contained in any integration
98278 + data structure.
98279 +*//***************************************************************************/
98280 +typedef struct t_Part
98281 +{
98282 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98283 + /**< Returns the address of the module's memory map base. */
98284 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98285 + /**< Returns the module's ID according to its memory map base. */
98286 +} t_Part;
98287 +
98288 +
98289 +#endif /* __PART_EXT_H */
98290 --- /dev/null
98291 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
98292 @@ -0,0 +1,304 @@
98293 +/*
98294 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98295 + *
98296 + * Redistribution and use in source and binary forms, with or without
98297 + * modification, are permitted provided that the following conditions are met:
98298 + * * Redistributions of source code must retain the above copyright
98299 + * notice, this list of conditions and the following disclaimer.
98300 + * * Redistributions in binary form must reproduce the above copyright
98301 + * notice, this list of conditions and the following disclaimer in the
98302 + * documentation and/or other materials provided with the distribution.
98303 + * * Neither the name of Freescale Semiconductor nor the
98304 + * names of its contributors may be used to endorse or promote products
98305 + * derived from this software without specific prior written permission.
98306 + *
98307 + *
98308 + * ALTERNATIVELY, this software may be distributed under the terms of the
98309 + * GNU General Public License ("GPL") as published by the Free Software
98310 + * Foundation, either version 2 of that License or (at your option) any
98311 + * later version.
98312 + *
98313 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98314 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98315 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98316 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98317 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98318 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98319 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98320 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98321 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98322 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98323 + */
98324 +
98325 +/**
98326 +
98327 + @File part_integration_ext.h
98328 +
98329 + @Description T4240 external definitions and structures.
98330 +*//***************************************************************************/
98331 +#ifndef __PART_INTEGRATION_EXT_H
98332 +#define __PART_INTEGRATION_EXT_H
98333 +
98334 +#include "std_ext.h"
98335 +#include "ddr_std_ext.h"
98336 +#include "enet_ext.h"
98337 +#include "dpaa_integration_ext.h"
98338 +
98339 +
98340 +/**************************************************************************//**
98341 + @Group T4240_chip_id T4240 Application Programming Interface
98342 +
98343 + @Description T4240 Chip functions,definitions and enums.
98344 +
98345 + @{
98346 +*//***************************************************************************/
98347 +
98348 +#define CORE_E6500
98349 +
98350 +#define INTG_MAX_NUM_OF_CORES 24
98351 +
98352 +
98353 +/**************************************************************************//**
98354 + @Description Module types.
98355 +*//***************************************************************************/
98356 +typedef enum e_ModuleId
98357 +{
98358 + e_MODULE_ID_DUART_1 = 0,
98359 + e_MODULE_ID_DUART_2,
98360 + e_MODULE_ID_DUART_3,
98361 + e_MODULE_ID_DUART_4,
98362 + e_MODULE_ID_LAW,
98363 + e_MODULE_ID_IFC,
98364 + e_MODULE_ID_PAMU,
98365 + e_MODULE_ID_QM, /**< Queue manager module */
98366 + e_MODULE_ID_BM, /**< Buffer manager module */
98367 + e_MODULE_ID_QM_CE_PORTAL_0,
98368 + e_MODULE_ID_QM_CI_PORTAL_0,
98369 + e_MODULE_ID_QM_CE_PORTAL_1,
98370 + e_MODULE_ID_QM_CI_PORTAL_1,
98371 + e_MODULE_ID_QM_CE_PORTAL_2,
98372 + e_MODULE_ID_QM_CI_PORTAL_2,
98373 + e_MODULE_ID_QM_CE_PORTAL_3,
98374 + e_MODULE_ID_QM_CI_PORTAL_3,
98375 + e_MODULE_ID_QM_CE_PORTAL_4,
98376 + e_MODULE_ID_QM_CI_PORTAL_4,
98377 + e_MODULE_ID_QM_CE_PORTAL_5,
98378 + e_MODULE_ID_QM_CI_PORTAL_5,
98379 + e_MODULE_ID_QM_CE_PORTAL_6,
98380 + e_MODULE_ID_QM_CI_PORTAL_6,
98381 + e_MODULE_ID_QM_CE_PORTAL_7,
98382 + e_MODULE_ID_QM_CI_PORTAL_7,
98383 + e_MODULE_ID_QM_CE_PORTAL_8,
98384 + e_MODULE_ID_QM_CI_PORTAL_8,
98385 + e_MODULE_ID_QM_CE_PORTAL_9,
98386 + e_MODULE_ID_QM_CI_PORTAL_9,
98387 + e_MODULE_ID_BM_CE_PORTAL_0,
98388 + e_MODULE_ID_BM_CI_PORTAL_0,
98389 + e_MODULE_ID_BM_CE_PORTAL_1,
98390 + e_MODULE_ID_BM_CI_PORTAL_1,
98391 + e_MODULE_ID_BM_CE_PORTAL_2,
98392 + e_MODULE_ID_BM_CI_PORTAL_2,
98393 + e_MODULE_ID_BM_CE_PORTAL_3,
98394 + e_MODULE_ID_BM_CI_PORTAL_3,
98395 + e_MODULE_ID_BM_CE_PORTAL_4,
98396 + e_MODULE_ID_BM_CI_PORTAL_4,
98397 + e_MODULE_ID_BM_CE_PORTAL_5,
98398 + e_MODULE_ID_BM_CI_PORTAL_5,
98399 + e_MODULE_ID_BM_CE_PORTAL_6,
98400 + e_MODULE_ID_BM_CI_PORTAL_6,
98401 + e_MODULE_ID_BM_CE_PORTAL_7,
98402 + e_MODULE_ID_BM_CI_PORTAL_7,
98403 + e_MODULE_ID_BM_CE_PORTAL_8,
98404 + e_MODULE_ID_BM_CI_PORTAL_8,
98405 + e_MODULE_ID_BM_CE_PORTAL_9,
98406 + e_MODULE_ID_BM_CI_PORTAL_9,
98407 + e_MODULE_ID_FM, /**< Frame manager module */
98408 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
98409 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
98410 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
98411 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
98412 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
98413 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
98414 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
98415 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
98416 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
98417 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
98418 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
98419 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
98420 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
98421 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
98422 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
98423 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
98424 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
98425 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
98426 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
98427 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
98428 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
98429 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
98430 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
98431 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
98432 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
98433 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
98434 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
98435 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
98436 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
98437 + e_MODULE_ID_FM_KG, /**< FM Keygen */
98438 + e_MODULE_ID_FM_DMA, /**< FM DMA */
98439 + e_MODULE_ID_FM_FPM, /**< FM FPM */
98440 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
98441 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
98442 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
98443 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
98444 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
98445 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
98446 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
98447 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
98448 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
98449 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
98450 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
98451 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
98452 +
98453 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
98454 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
98455 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
98456 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
98457 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
98458 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
98459 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
98460 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
98461 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
98462 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
98463 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
98464 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
98465 +
98466 + e_MODULE_ID_PIC, /**< PIC */
98467 + e_MODULE_ID_GPIO, /**< GPIO */
98468 + e_MODULE_ID_SERDES, /**< SERDES */
98469 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
98470 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
98471 +
98472 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
98473 +
98474 + e_MODULE_ID_DUMMY_LAST
98475 +} e_ModuleId;
98476 +
98477 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
98478 +
98479 +#if 0 /* using unified values */
98480 +/*****************************************************************************
98481 + INTEGRATION-SPECIFIC MODULE CODES
98482 +******************************************************************************/
98483 +#define MODULE_UNKNOWN 0x00000000
98484 +#define MODULE_MEM 0x00010000
98485 +#define MODULE_MM 0x00020000
98486 +#define MODULE_CORE 0x00030000
98487 +#define MODULE_T4240 0x00040000
98488 +#define MODULE_T4240_PLATFORM 0x00050000
98489 +#define MODULE_PM 0x00060000
98490 +#define MODULE_MMU 0x00070000
98491 +#define MODULE_PIC 0x00080000
98492 +#define MODULE_CPC 0x00090000
98493 +#define MODULE_DUART 0x000a0000
98494 +#define MODULE_SERDES 0x000b0000
98495 +#define MODULE_PIO 0x000c0000
98496 +#define MODULE_QM 0x000d0000
98497 +#define MODULE_BM 0x000e0000
98498 +#define MODULE_SEC 0x000f0000
98499 +#define MODULE_LAW 0x00100000
98500 +#define MODULE_LBC 0x00110000
98501 +#define MODULE_PAMU 0x00120000
98502 +#define MODULE_FM 0x00130000
98503 +#define MODULE_FM_MURAM 0x00140000
98504 +#define MODULE_FM_PCD 0x00150000
98505 +#define MODULE_FM_RTC 0x00160000
98506 +#define MODULE_FM_MAC 0x00170000
98507 +#define MODULE_FM_PORT 0x00180000
98508 +#define MODULE_FM_SP 0x00190000
98509 +#define MODULE_DPA_PORT 0x001a0000
98510 +#define MODULE_MII 0x001b0000
98511 +#define MODULE_I2C 0x001c0000
98512 +#define MODULE_DMA 0x001d0000
98513 +#define MODULE_DDR 0x001e0000
98514 +#define MODULE_ESPI 0x001f0000
98515 +#define MODULE_DPAA_IPSEC 0x00200000
98516 +#endif /* using unified values */
98517 +
98518 +/*****************************************************************************
98519 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
98520 +******************************************************************************/
98521 +#define PAMU_NUM_OF_PARTITIONS 4
98522 +
98523 +/*****************************************************************************
98524 + LAW INTEGRATION-SPECIFIC DEFINITIONS
98525 +******************************************************************************/
98526 +#define LAW_NUM_OF_WINDOWS 32
98527 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
98528 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
98529 +
98530 +
98531 +/*****************************************************************************
98532 + LBC INTEGRATION-SPECIFIC DEFINITIONS
98533 +******************************************************************************/
98534 +/**************************************************************************//**
98535 + @Group lbc_exception_grp LBC Exception Unit
98536 +
98537 + @Description LBC Exception unit API functions, definitions and enums
98538 +
98539 + @{
98540 +*//***************************************************************************/
98541 +
98542 +/**************************************************************************//**
98543 + @Anchor lbc_exbm
98544 +
98545 + @Collection LBC Errors Bit Mask
98546 +
98547 + These errors are reported through the exceptions callback..
98548 + The values can be or'ed in any combination in the errors mask
98549 + parameter of the errors report structure.
98550 +
98551 + These errors can also be passed as a bit-mask to
98552 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
98553 + for enabling or disabling error checking.
98554 + @{
98555 +*//***************************************************************************/
98556 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
98557 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
98558 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
98559 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
98560 +
98561 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
98562 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
98563 + /**< All possible errors */
98564 +/* @} */
98565 +/** @} */ /* end of lbc_exception_grp group */
98566 +
98567 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
98568 +
98569 +#define LBC_NUM_OF_BANKS 8
98570 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
98571 +#define LBC_PARITY_SUPPORT
98572 +#define LBC_ADDRESS_HOLD_TIME_CTRL
98573 +#define LBC_HIGH_CLK_DIVIDERS
98574 +#define LBC_FCM_AVAILABLE
98575 +
98576 +/*****************************************************************************
98577 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
98578 +******************************************************************************/
98579 +#define GPIO_PORT_OFFSET_0x1000
98580 +
98581 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
98582 + Each port contains up to 32 I/O pins. */
98583 +
98584 +#define GPIO_VALID_PIN_MASKS \
98585 + { /* Port A */ 0xFFFFFFFF, \
98586 + /* Port B */ 0xFFFFFFFF, \
98587 + /* Port C */ 0xFFFFFFFF }
98588 +
98589 +#define GPIO_VALID_INTR_MASKS \
98590 + { /* Port A */ 0xFFFFFFFF, \
98591 + /* Port B */ 0xFFFFFFFF, \
98592 + /* Port C */ 0xFFFFFFFF }
98593 +
98594 +
98595 +
98596 +#endif /* __PART_INTEGRATION_EXT_H */
98597 --- /dev/null
98598 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
98599 @@ -0,0 +1,291 @@
98600 +/*
98601 + * Copyright 2012 Freescale Semiconductor Inc.
98602 + *
98603 + * Redistribution and use in source and binary forms, with or without
98604 + * modification, are permitted provided that the following conditions are met:
98605 + * * Redistributions of source code must retain the above copyright
98606 + * notice, this list of conditions and the following disclaimer.
98607 + * * Redistributions in binary form must reproduce the above copyright
98608 + * notice, this list of conditions and the following disclaimer in the
98609 + * documentation and/or other materials provided with the distribution.
98610 + * * Neither the name of Freescale Semiconductor nor the
98611 + * names of its contributors may be used to endorse or promote products
98612 + * derived from this software without specific prior written permission.
98613 + *
98614 + *
98615 + * ALTERNATIVELY, this software may be distributed under the terms of the
98616 + * GNU General Public License ("GPL") as published by the Free Software
98617 + * Foundation, either version 2 of that License or (at your option) any
98618 + * later version.
98619 + *
98620 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98621 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98622 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98623 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98624 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98625 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98626 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98627 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98628 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98629 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98630 + */
98631 +
98632 +/**
98633 +
98634 + @File dpaa_integration_ext.h
98635 +
98636 + @Description T4240 FM external definitions and structures.
98637 +*//***************************************************************************/
98638 +#ifndef __DPAA_INTEGRATION_EXT_H
98639 +#define __DPAA_INTEGRATION_EXT_H
98640 +
98641 +#include "std_ext.h"
98642 +
98643 +
98644 +#define DPAA_VERSION 11
98645 +
98646 +/**************************************************************************//**
98647 + @Description DPAA SW Portals Enumeration.
98648 +*//***************************************************************************/
98649 +typedef enum
98650 +{
98651 + e_DPAA_SWPORTAL0 = 0,
98652 + e_DPAA_SWPORTAL1,
98653 + e_DPAA_SWPORTAL2,
98654 + e_DPAA_SWPORTAL3,
98655 + e_DPAA_SWPORTAL4,
98656 + e_DPAA_SWPORTAL5,
98657 + e_DPAA_SWPORTAL6,
98658 + e_DPAA_SWPORTAL7,
98659 + e_DPAA_SWPORTAL8,
98660 + e_DPAA_SWPORTAL9,
98661 + e_DPAA_SWPORTAL10,
98662 + e_DPAA_SWPORTAL11,
98663 + e_DPAA_SWPORTAL12,
98664 + e_DPAA_SWPORTAL13,
98665 + e_DPAA_SWPORTAL14,
98666 + e_DPAA_SWPORTAL15,
98667 + e_DPAA_SWPORTAL16,
98668 + e_DPAA_SWPORTAL17,
98669 + e_DPAA_SWPORTAL18,
98670 + e_DPAA_SWPORTAL19,
98671 + e_DPAA_SWPORTAL20,
98672 + e_DPAA_SWPORTAL21,
98673 + e_DPAA_SWPORTAL22,
98674 + e_DPAA_SWPORTAL23,
98675 + e_DPAA_SWPORTAL24,
98676 + e_DPAA_SWPORTAL_DUMMY_LAST
98677 +} e_DpaaSwPortal;
98678 +
98679 +/**************************************************************************//**
98680 + @Description DPAA Direct Connect Portals Enumeration.
98681 +*//***************************************************************************/
98682 +typedef enum
98683 +{
98684 + e_DPAA_DCPORTAL0 = 0,
98685 + e_DPAA_DCPORTAL1,
98686 + e_DPAA_DCPORTAL2,
98687 + e_DPAA_DCPORTAL_DUMMY_LAST
98688 +} e_DpaaDcPortal;
98689 +
98690 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
98691 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
98692 +
98693 +/*****************************************************************************
98694 + QMan INTEGRATION-SPECIFIC DEFINITIONS
98695 +******************************************************************************/
98696 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
98697 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
98698 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
98699 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
98700 + /**< FQIDs range - 24 bits */
98701 +
98702 +/**************************************************************************//**
98703 + @Description Work Queue Channel assignments in QMan.
98704 +*//***************************************************************************/
98705 +typedef enum
98706 +{
98707 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
98708 + e_QM_FQ_CHANNEL_SWPORTAL1,
98709 + e_QM_FQ_CHANNEL_SWPORTAL2,
98710 + e_QM_FQ_CHANNEL_SWPORTAL3,
98711 + e_QM_FQ_CHANNEL_SWPORTAL4,
98712 + e_QM_FQ_CHANNEL_SWPORTAL5,
98713 + e_QM_FQ_CHANNEL_SWPORTAL6,
98714 + e_QM_FQ_CHANNEL_SWPORTAL7,
98715 + e_QM_FQ_CHANNEL_SWPORTAL8,
98716 + e_QM_FQ_CHANNEL_SWPORTAL9,
98717 + e_QM_FQ_CHANNEL_SWPORTAL10,
98718 + e_QM_FQ_CHANNEL_SWPORTAL11,
98719 + e_QM_FQ_CHANNEL_SWPORTAL12,
98720 + e_QM_FQ_CHANNEL_SWPORTAL13,
98721 + e_QM_FQ_CHANNEL_SWPORTAL14,
98722 + e_QM_FQ_CHANNEL_SWPORTAL15,
98723 + e_QM_FQ_CHANNEL_SWPORTAL16,
98724 + e_QM_FQ_CHANNEL_SWPORTAL17,
98725 + e_QM_FQ_CHANNEL_SWPORTAL18,
98726 + e_QM_FQ_CHANNEL_SWPORTAL19,
98727 + e_QM_FQ_CHANNEL_SWPORTAL20,
98728 + e_QM_FQ_CHANNEL_SWPORTAL21,
98729 + e_QM_FQ_CHANNEL_SWPORTAL22,
98730 + e_QM_FQ_CHANNEL_SWPORTAL23,
98731 + e_QM_FQ_CHANNEL_SWPORTAL24,
98732 +
98733 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
98734 + e_QM_FQ_CHANNEL_POOL2,
98735 + e_QM_FQ_CHANNEL_POOL3,
98736 + e_QM_FQ_CHANNEL_POOL4,
98737 + e_QM_FQ_CHANNEL_POOL5,
98738 + e_QM_FQ_CHANNEL_POOL6,
98739 + e_QM_FQ_CHANNEL_POOL7,
98740 + e_QM_FQ_CHANNEL_POOL8,
98741 + e_QM_FQ_CHANNEL_POOL9,
98742 + e_QM_FQ_CHANNEL_POOL10,
98743 + e_QM_FQ_CHANNEL_POOL11,
98744 + e_QM_FQ_CHANNEL_POOL12,
98745 + e_QM_FQ_CHANNEL_POOL13,
98746 + e_QM_FQ_CHANNEL_POOL14,
98747 + e_QM_FQ_CHANNEL_POOL15,
98748 +
98749 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
98750 + connected to FMan 0; assigned in incrementing order to
98751 + each sub-portal (SP) in the portal */
98752 + e_QM_FQ_CHANNEL_FMAN0_SP1,
98753 + e_QM_FQ_CHANNEL_FMAN0_SP2,
98754 + e_QM_FQ_CHANNEL_FMAN0_SP3,
98755 + e_QM_FQ_CHANNEL_FMAN0_SP4,
98756 + e_QM_FQ_CHANNEL_FMAN0_SP5,
98757 + e_QM_FQ_CHANNEL_FMAN0_SP6,
98758 + e_QM_FQ_CHANNEL_FMAN0_SP7,
98759 + e_QM_FQ_CHANNEL_FMAN0_SP8,
98760 + e_QM_FQ_CHANNEL_FMAN0_SP9,
98761 + e_QM_FQ_CHANNEL_FMAN0_SP10,
98762 + e_QM_FQ_CHANNEL_FMAN0_SP11,
98763 + e_QM_FQ_CHANNEL_FMAN0_SP12,
98764 + e_QM_FQ_CHANNEL_FMAN0_SP13,
98765 + e_QM_FQ_CHANNEL_FMAN0_SP14,
98766 + e_QM_FQ_CHANNEL_FMAN0_SP15,
98767 +
98768 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
98769 + e_QM_FQ_CHANNEL_RMAN_SP1,
98770 +
98771 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
98772 + connected to SEC */
98773 +} e_QmFQChannel;
98774 +
98775 +/*****************************************************************************
98776 + BMan INTEGRATION-SPECIFIC DEFINITIONS
98777 +******************************************************************************/
98778 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
98779 +
98780 +/*****************************************************************************
98781 + SEC INTEGRATION-SPECIFIC DEFINITIONS
98782 +******************************************************************************/
98783 +#define SEC_NUM_OF_DECOS 3
98784 +#define SEC_ALL_DECOS_MASK 0x00000003
98785 +
98786 +
98787 +/*****************************************************************************
98788 + FM INTEGRATION-SPECIFIC DEFINITIONS
98789 +******************************************************************************/
98790 +#define INTG_MAX_NUM_OF_FM 2
98791 +
98792 +/* Ports defines */
98793 +#define FM_MAX_NUM_OF_1G_MACS 6
98794 +#define FM_MAX_NUM_OF_10G_MACS 2
98795 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
98796 +#define FM_MAX_NUM_OF_OH_PORTS 6
98797 +
98798 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
98799 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
98800 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
98801 +
98802 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
98803 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
98804 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
98805 +
98806 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
98807 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
98808 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
98809 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
98810 +
98811 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
98812 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
98813 +
98814 +/* RAMs defines */
98815 +#define FM_MURAM_SIZE (384 * KILOBYTE)
98816 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
98817 +#define FM_NUM_OF_CTRL 4
98818 +
98819 +/* PCD defines */
98820 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
98821 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
98822 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
98823 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
98824 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
98825 +
98826 +/* RTC defines */
98827 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
98828 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
98829 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
98830 +
98831 +/* QMI defines */
98832 +#define QMI_MAX_NUM_OF_TNUMS 64
98833 +#define QMI_DEF_TNUMS_THRESH 32
98834 +/* FPM defines */
98835 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
98836 +
98837 +/* DMA defines */
98838 +#define DMA_THRESH_MAX_COMMQ 83
98839 +#define DMA_THRESH_MAX_BUF 127
98840 +
98841 +/* BMI defines */
98842 +#define BMI_MAX_NUM_OF_TASKS 128
98843 +#define BMI_MAX_NUM_OF_DMAS 84
98844 +
98845 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
98846 +#define PORT_MAX_WEIGHT 16
98847 +
98848 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
98849 +
98850 +/* Unique T4240 */
98851 +#define FM_OP_OPEN_DMA_MIN_LIMIT
98852 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
98853 +#define FM_NO_OP_OBSERVED_POOLS
98854 +#define FM_FRAME_END_PARAMS_FOR_OP
98855 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
98856 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
98857 +
98858 +#define FM_NO_GUARANTEED_RESET_VALUES
98859 +
98860 +/* FM errata */
98861 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
98862 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
98863 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
98864 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
98865 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
98866 +
98867 +#define FM_BCB_ERRATA_BMI_SW001
98868 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
98869 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
98870 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
98871 +
98872 +/*****************************************************************************
98873 + RMan INTEGRATION-SPECIFIC DEFINITIONS
98874 +******************************************************************************/
98875 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
98876 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
98877 +
98878 +/* RMan erratas */
98879 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
98880 +
98881 +/*****************************************************************************
98882 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
98883 +******************************************************************************/
98884 +#define NUM_OF_RX_SC 16
98885 +#define NUM_OF_TX_SC 16
98886 +
98887 +#define NUM_OF_SA_PER_RX_SC 2
98888 +#define NUM_OF_SA_PER_TX_SC 2
98889 +
98890 +#endif /* __DPAA_INTEGRATION_EXT_H */
98891 --- /dev/null
98892 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
98893 @@ -0,0 +1,64 @@
98894 +/*
98895 + * Copyright 2012 Freescale Semiconductor Inc.
98896 + *
98897 + * Redistribution and use in source and binary forms, with or without
98898 + * modification, are permitted provided that the following conditions are met:
98899 + * * Redistributions of source code must retain the above copyright
98900 + * notice, this list of conditions and the following disclaimer.
98901 + * * Redistributions in binary form must reproduce the above copyright
98902 + * notice, this list of conditions and the following disclaimer in the
98903 + * documentation and/or other materials provided with the distribution.
98904 + * * Neither the name of Freescale Semiconductor nor the
98905 + * names of its contributors may be used to endorse or promote products
98906 + * derived from this software without specific prior written permission.
98907 + *
98908 + *
98909 + * ALTERNATIVELY, this software may be distributed under the terms of the
98910 + * GNU General Public License ("GPL") as published by the Free Software
98911 + * Foundation, either version 2 of that License or (at your option) any
98912 + * later version.
98913 + *
98914 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98915 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98916 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98917 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98918 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98919 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98920 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98921 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98922 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98923 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98924 + */
98925 +
98926 +/**************************************************************************//**
98927 +
98928 + @File part_ext.h
98929 +
98930 + @Description Definitions for the part (integration) module.
98931 +*//***************************************************************************/
98932 +
98933 +#ifndef __PART_EXT_H
98934 +#define __PART_EXT_H
98935 +
98936 +#include "std_ext.h"
98937 +#include "part_integration_ext.h"
98938 +
98939 +#if !(defined(LS1043))
98940 +#error "unable to proceed without chip-definition"
98941 +#endif
98942 +
98943 +
98944 +/**************************************************************************//*
98945 + @Description Part data structure - must be contained in any integration
98946 + data structure.
98947 +*//***************************************************************************/
98948 +typedef struct t_Part
98949 +{
98950 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
98951 + /**< Returns the address of the module's memory map base. */
98952 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
98953 + /**< Returns the module's ID according to its memory map base. */
98954 +} t_Part;
98955 +
98956 +
98957 +#endif /* __PART_EXT_H */
98958 --- /dev/null
98959 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
98960 @@ -0,0 +1,185 @@
98961 +/*
98962 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98963 + *
98964 + * Redistribution and use in source and binary forms, with or without
98965 + * modification, are permitted provided that the following conditions are met:
98966 + * * Redistributions of source code must retain the above copyright
98967 + * notice, this list of conditions and the following disclaimer.
98968 + * * Redistributions in binary form must reproduce the above copyright
98969 + * notice, this list of conditions and the following disclaimer in the
98970 + * documentation and/or other materials provided with the distribution.
98971 + * * Neither the name of Freescale Semiconductor nor the
98972 + * names of its contributors may be used to endorse or promote products
98973 + * derived from this software without specific prior written permission.
98974 + *
98975 + *
98976 + * ALTERNATIVELY, this software may be distributed under the terms of the
98977 + * GNU General Public License ("GPL") as published by the Free Software
98978 + * Foundation, either version 2 of that License or (at your option) any
98979 + * later version.
98980 + *
98981 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98982 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98983 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98984 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98985 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98986 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98987 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98988 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98989 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98990 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98991 + */
98992 +
98993 +/**
98994 +
98995 + @File part_integration_ext.h
98996 +
98997 + @Description T4240 external definitions and structures.
98998 +*//***************************************************************************/
98999 +#ifndef __PART_INTEGRATION_EXT_H
99000 +#define __PART_INTEGRATION_EXT_H
99001 +
99002 +#include "std_ext.h"
99003 +#include "ddr_std_ext.h"
99004 +#include "enet_ext.h"
99005 +#include "dpaa_integration_ext.h"
99006 +
99007 +
99008 +/**************************************************************************//**
99009 + @Group T4240_chip_id T4240 Application Programming Interface
99010 +
99011 + @Description T4240 Chip functions,definitions and enums.
99012 +
99013 + @{
99014 +*//***************************************************************************/
99015 +
99016 +#define INTG_MAX_NUM_OF_CORES 4
99017 +
99018 +/**************************************************************************//**
99019 + @Description Module types.
99020 +*//***************************************************************************/
99021 +typedef enum e_ModuleId
99022 +{
99023 + e_MODULE_ID_DUART_1 = 0,
99024 + e_MODULE_ID_DUART_2,
99025 + e_MODULE_ID_DUART_3,
99026 + e_MODULE_ID_DUART_4,
99027 + e_MODULE_ID_LAW,
99028 + e_MODULE_ID_IFC,
99029 + e_MODULE_ID_PAMU,
99030 + e_MODULE_ID_QM, /**< Queue manager module */
99031 + e_MODULE_ID_BM, /**< Buffer manager module */
99032 + e_MODULE_ID_QM_CE_PORTAL_0,
99033 + e_MODULE_ID_QM_CI_PORTAL_0,
99034 + e_MODULE_ID_QM_CE_PORTAL_1,
99035 + e_MODULE_ID_QM_CI_PORTAL_1,
99036 + e_MODULE_ID_QM_CE_PORTAL_2,
99037 + e_MODULE_ID_QM_CI_PORTAL_2,
99038 + e_MODULE_ID_QM_CE_PORTAL_3,
99039 + e_MODULE_ID_QM_CI_PORTAL_3,
99040 + e_MODULE_ID_QM_CE_PORTAL_4,
99041 + e_MODULE_ID_QM_CI_PORTAL_4,
99042 + e_MODULE_ID_QM_CE_PORTAL_5,
99043 + e_MODULE_ID_QM_CI_PORTAL_5,
99044 + e_MODULE_ID_QM_CE_PORTAL_6,
99045 + e_MODULE_ID_QM_CI_PORTAL_6,
99046 + e_MODULE_ID_QM_CE_PORTAL_7,
99047 + e_MODULE_ID_QM_CI_PORTAL_7,
99048 + e_MODULE_ID_QM_CE_PORTAL_8,
99049 + e_MODULE_ID_QM_CI_PORTAL_8,
99050 + e_MODULE_ID_QM_CE_PORTAL_9,
99051 + e_MODULE_ID_QM_CI_PORTAL_9,
99052 + e_MODULE_ID_BM_CE_PORTAL_0,
99053 + e_MODULE_ID_BM_CI_PORTAL_0,
99054 + e_MODULE_ID_BM_CE_PORTAL_1,
99055 + e_MODULE_ID_BM_CI_PORTAL_1,
99056 + e_MODULE_ID_BM_CE_PORTAL_2,
99057 + e_MODULE_ID_BM_CI_PORTAL_2,
99058 + e_MODULE_ID_BM_CE_PORTAL_3,
99059 + e_MODULE_ID_BM_CI_PORTAL_3,
99060 + e_MODULE_ID_BM_CE_PORTAL_4,
99061 + e_MODULE_ID_BM_CI_PORTAL_4,
99062 + e_MODULE_ID_BM_CE_PORTAL_5,
99063 + e_MODULE_ID_BM_CI_PORTAL_5,
99064 + e_MODULE_ID_BM_CE_PORTAL_6,
99065 + e_MODULE_ID_BM_CI_PORTAL_6,
99066 + e_MODULE_ID_BM_CE_PORTAL_7,
99067 + e_MODULE_ID_BM_CI_PORTAL_7,
99068 + e_MODULE_ID_BM_CE_PORTAL_8,
99069 + e_MODULE_ID_BM_CI_PORTAL_8,
99070 + e_MODULE_ID_BM_CE_PORTAL_9,
99071 + e_MODULE_ID_BM_CI_PORTAL_9,
99072 + e_MODULE_ID_FM, /**< Frame manager module */
99073 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99074 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99075 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99076 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99077 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99078 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99079 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99080 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99081 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99082 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99083 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99084 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99085 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99086 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99087 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99088 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99089 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99090 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99091 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99092 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99093 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99094 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99095 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99096 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99097 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99098 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99099 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99100 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99101 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99102 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99103 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99104 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99105 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99106 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99107 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99108 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99109 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99110 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99111 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99112 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99113 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99114 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99115 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99116 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99117 +
99118 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99119 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99120 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99121 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99122 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99123 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99124 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99125 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99126 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99127 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99128 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99129 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99130 +
99131 + e_MODULE_ID_PIC, /**< PIC */
99132 + e_MODULE_ID_GPIO, /**< GPIO */
99133 + e_MODULE_ID_SERDES, /**< SERDES */
99134 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99135 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99136 +
99137 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99138 +
99139 + e_MODULE_ID_DUMMY_LAST
99140 +} e_ModuleId;
99141 +
99142 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99143 +
99144 +
99145 +#endif /* __PART_INTEGRATION_EXT_H */
99146 --- /dev/null
99147 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
99148 @@ -0,0 +1,213 @@
99149 +/*
99150 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99151 + *
99152 + * Redistribution and use in source and binary forms, with or without
99153 + * modification, are permitted provided that the following conditions are met:
99154 + * * Redistributions of source code must retain the above copyright
99155 + * notice, this list of conditions and the following disclaimer.
99156 + * * Redistributions in binary form must reproduce the above copyright
99157 + * notice, this list of conditions and the following disclaimer in the
99158 + * documentation and/or other materials provided with the distribution.
99159 + * * Neither the name of Freescale Semiconductor nor the
99160 + * names of its contributors may be used to endorse or promote products
99161 + * derived from this software without specific prior written permission.
99162 + *
99163 + *
99164 + * ALTERNATIVELY, this software may be distributed under the terms of the
99165 + * GNU General Public License ("GPL") as published by the Free Software
99166 + * Foundation, either version 2 of that License or (at your option) any
99167 + * later version.
99168 + *
99169 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99170 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99171 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99172 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99173 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99174 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99175 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99176 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99177 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99178 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99179 + */
99180 +
99181 +
99182 +/**
99183 +
99184 + @File dpaa_integration_ext.h
99185 +
99186 + @Description P1023 FM external definitions and structures.
99187 +*//***************************************************************************/
99188 +#ifndef __DPAA_INTEGRATION_EXT_H
99189 +#define __DPAA_INTEGRATION_EXT_H
99190 +
99191 +#include "std_ext.h"
99192 +
99193 +
99194 +#define DPAA_VERSION 10
99195 +
99196 +typedef enum e_DpaaSwPortal {
99197 + e_DPAA_SWPORTAL0 = 0,
99198 + e_DPAA_SWPORTAL1,
99199 + e_DPAA_SWPORTAL2,
99200 + e_DPAA_SWPORTAL_DUMMY_LAST
99201 +} e_DpaaSwPortal;
99202 +
99203 +typedef enum {
99204 + e_DPAA_DCPORTAL0 = 0,
99205 + e_DPAA_DCPORTAL2,
99206 + e_DPAA_DCPORTAL_DUMMY_LAST
99207 +} e_DpaaDcPortal;
99208 +
99209 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99210 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99211 +
99212 +/*****************************************************************************
99213 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
99214 +******************************************************************************/
99215 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
99216 +#define QM_MAX_NUM_OF_WQ 8
99217 +#define QM_MAX_NUM_OF_SWP_AS 2
99218 +#define QM_MAX_NUM_OF_CGS 64
99219 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
99220 +
99221 +typedef enum {
99222 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
99223 + e_QM_FQ_CHANNEL_SWPORTAL1,
99224 + e_QM_FQ_CHANNEL_SWPORTAL2,
99225 +
99226 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
99227 + e_QM_FQ_CHANNEL_POOL2,
99228 + e_QM_FQ_CHANNEL_POOL3,
99229 +
99230 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
99231 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99232 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99233 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99234 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99235 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99236 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99237 +
99238 +
99239 + e_QM_FQ_CHANNEL_CAAM = 0x80
99240 +} e_QmFQChannel;
99241 +
99242 +/*****************************************************************************
99243 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
99244 +******************************************************************************/
99245 +#define BM_MAX_NUM_OF_POOLS 8
99246 +
99247 +/*****************************************************************************
99248 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99249 +******************************************************************************/
99250 +#define SEC_NUM_OF_DECOS 2
99251 +#define SEC_ALL_DECOS_MASK 0x00000003
99252 +#define SEC_RNGB
99253 +#define SEC_NO_ESP_TRAILER_REMOVAL
99254 +
99255 +/*****************************************************************************
99256 + FM INTEGRATION-SPECIFIC DEFINITIONS
99257 +******************************************************************************/
99258 +#define INTG_MAX_NUM_OF_FM 1
99259 +
99260 +/* Ports defines */
99261 +#define FM_MAX_NUM_OF_1G_MACS 2
99262 +#define FM_MAX_NUM_OF_10G_MACS 0
99263 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99264 +#define FM_MAX_NUM_OF_OH_PORTS 5
99265 +
99266 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99267 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99268 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99269 +
99270 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99271 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99272 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99273 +
99274 +#define FM_MAX_NUM_OF_MACSECS 1
99275 +
99276 +#define FM_MACSEC_SUPPORT
99277 +
99278 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
99279 +
99280 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99281 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
99282 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
99283 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
99284 +
99285 +/* Rams defines */
99286 +#define FM_MURAM_SIZE (64*KILOBYTE)
99287 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
99288 +#define FM_NUM_OF_CTRL 2
99289 +
99290 +/* PCD defines */
99291 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
99292 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
99293 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
99294 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
99295 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99296 +
99297 +/* RTC defines */
99298 +#define FM_RTC_NUM_OF_ALARMS 2
99299 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
99300 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
99301 +
99302 +/* QMI defines */
99303 +#define QMI_MAX_NUM_OF_TNUMS 15
99304 +
99305 +/* FPM defines */
99306 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99307 +
99308 +/* DMA defines */
99309 +#define DMA_THRESH_MAX_COMMQ 15
99310 +#define DMA_THRESH_MAX_BUF 7
99311 +
99312 +/* BMI defines */
99313 +#define BMI_MAX_NUM_OF_TASKS 64
99314 +#define BMI_MAX_NUM_OF_DMAS 16
99315 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99316 +#define PORT_MAX_WEIGHT 4
99317 +
99318 +/*****************************************************************************
99319 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99320 +******************************************************************************/
99321 +#define NUM_OF_RX_SC 16
99322 +#define NUM_OF_TX_SC 16
99323 +
99324 +#define NUM_OF_SA_PER_RX_SC 2
99325 +#define NUM_OF_SA_PER_TX_SC 2
99326 +
99327 +/**************************************************************************//**
99328 + @Description Enum for inter-module interrupts registration
99329 +*//***************************************************************************/
99330 +
99331 +/* 1023 unique features */
99332 +#define FM_QMI_NO_ECC_EXCEPTIONS
99333 +#define FM_CSI_CFED_LIMIT
99334 +#define FM_PEDANTIC_DMA
99335 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
99336 +#define FM_FIFO_ALLOCATION_ALG
99337 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99338 +#define FM_HAS_TOTAL_DMAS
99339 +#define FM_KG_NO_IPPID_SUPPORT
99340 +#define FM_NO_GUARANTEED_RESET_VALUES
99341 +#define FM_MAC_RESET
99342 +
99343 +/* FM erratas */
99344 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
99345 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
99346 +
99347 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
99348 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
99349 +
99350 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
99351 +
99352 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
99353 +
99354 +/*
99355 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
99356 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
99357 +*/
99358 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
99359 +
99360 +
99361 +#endif /* __DPAA_INTEGRATION_EXT_H */
99362 --- /dev/null
99363 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
99364 @@ -0,0 +1,82 @@
99365 +/*
99366 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99367 + *
99368 + * Redistribution and use in source and binary forms, with or without
99369 + * modification, are permitted provided that the following conditions are met:
99370 + * * Redistributions of source code must retain the above copyright
99371 + * notice, this list of conditions and the following disclaimer.
99372 + * * Redistributions in binary form must reproduce the above copyright
99373 + * notice, this list of conditions and the following disclaimer in the
99374 + * documentation and/or other materials provided with the distribution.
99375 + * * Neither the name of Freescale Semiconductor nor the
99376 + * names of its contributors may be used to endorse or promote products
99377 + * derived from this software without specific prior written permission.
99378 + *
99379 + *
99380 + * ALTERNATIVELY, this software may be distributed under the terms of the
99381 + * GNU General Public License ("GPL") as published by the Free Software
99382 + * Foundation, either version 2 of that License or (at your option) any
99383 + * later version.
99384 + *
99385 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99386 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99387 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99388 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99389 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99390 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99391 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99392 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99393 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99394 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99395 + */
99396 +
99397 +
99398 +/**************************************************************************//**
99399 +
99400 + @File part_ext.h
99401 +
99402 + @Description Definitions for the part (integration) module.
99403 +*//***************************************************************************/
99404 +
99405 +#ifndef __PART_EXT_H
99406 +#define __PART_EXT_H
99407 +
99408 +#include "std_ext.h"
99409 +#include "part_integration_ext.h"
99410 +
99411 +
99412 +#if !(defined(MPC8306) || \
99413 + defined(MPC8309) || \
99414 + defined(MPC834x) || \
99415 + defined(MPC836x) || \
99416 + defined(MPC832x) || \
99417 + defined(MPC837x) || \
99418 + defined(MPC8568) || \
99419 + defined(MPC8569) || \
99420 + defined(P1020) || \
99421 + defined(P1021) || \
99422 + defined(P1022) || \
99423 + defined(P1023) || \
99424 + defined(P2020) || \
99425 + defined(P3041) || \
99426 + defined(P4080) || \
99427 + defined(P5020) || \
99428 + defined(MSC814x))
99429 +#error "unable to proceed without chip-definition"
99430 +#endif
99431 +
99432 +
99433 +/**************************************************************************//*
99434 + @Description Part data structure - must be contained in any integration
99435 + data structure.
99436 +*//***************************************************************************/
99437 +typedef struct t_Part
99438 +{
99439 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99440 + /**< Returns the address of the module's memory map base. */
99441 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
99442 + /**< Returns the module's ID according to its memory map base. */
99443 +} t_Part;
99444 +
99445 +
99446 +#endif /* __PART_EXT_H */
99447 --- /dev/null
99448 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
99449 @@ -0,0 +1,635 @@
99450 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
99451 + * All rights reserved.
99452 + *
99453 + * Redistribution and use in source and binary forms, with or without
99454 + * modification, are permitted provided that the following conditions are met:
99455 + * * Redistributions of source code must retain the above copyright
99456 + * notice, this list of conditions and the following disclaimer.
99457 + * * Redistributions in binary form must reproduce the above copyright
99458 + * notice, this list of conditions and the following disclaimer in the
99459 + * documentation and/or other materials provided with the distribution.
99460 + * * Neither the name of Freescale Semiconductor nor the
99461 + * names of its contributors may be used to endorse or promote products
99462 + * derived from this software without specific prior written permission.
99463 + *
99464 + *
99465 + * ALTERNATIVELY, this software may be distributed under the terms of the
99466 + * GNU General Public License ("GPL") as published by the Free Software
99467 + * Foundation, either version 2 of that License or (at your option) any
99468 + * later version.
99469 + *
99470 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99471 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99472 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99473 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99474 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99475 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99476 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99477 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99478 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99479 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99480 + */
99481 +
99482 +/**************************************************************************//**
99483 + @File part_integration_ext.h
99484 +
99485 + @Description P1023 external definitions and structures.
99486 +*//***************************************************************************/
99487 +#ifndef __PART_INTEGRATION_EXT_H
99488 +#define __PART_INTEGRATION_EXT_H
99489 +
99490 +#include "std_ext.h"
99491 +#include "dpaa_integration_ext.h"
99492 +
99493 +
99494 +/**************************************************************************//**
99495 + @Group 1023_chip_id P1023 Application Programming Interface
99496 +
99497 + @Description P1023 Chip functions,definitions and enums.
99498 +
99499 + @{
99500 +*//***************************************************************************/
99501 +
99502 +#define INTG_MAX_NUM_OF_CORES 2
99503 +
99504 +
99505 +/**************************************************************************//**
99506 + @Description Module types.
99507 +*//***************************************************************************/
99508 +typedef enum e_ModuleId
99509 +{
99510 + e_MODULE_ID_LAW, /**< Local Access module */
99511 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
99512 + e_MODULE_ID_DDR, /**< DDR memory controller */
99513 + e_MODULE_ID_I2C_1, /**< I2C 1 */
99514 + e_MODULE_ID_I2C_2, /**< I2C 1 */
99515 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
99516 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
99517 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
99518 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
99519 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
99520 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
99521 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
99522 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
99523 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
99524 + e_MODULE_ID_MSI, /**< MSI registers */
99525 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
99526 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
99527 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
99528 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
99529 + e_MODULE_ID_ESPI, /**< ESPI module */
99530 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
99531 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99532 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99533 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99534 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99535 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99536 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99537 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99538 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99539 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99540 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99541 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99542 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99543 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
99544 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
99545 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
99546 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
99547 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
99548 + e_MODULE_ID_GUTS, /**< Serial DMA */
99549 + e_MODULE_ID_PM, /**< Performance Monitor module */
99550 + e_MODULE_ID_QM, /**< Queue manager module */
99551 + e_MODULE_ID_BM, /**< Buffer manager module */
99552 + e_MODULE_ID_QM_CE_PORTAL,
99553 + e_MODULE_ID_QM_CI_PORTAL,
99554 + e_MODULE_ID_BM_CE_PORTAL,
99555 + e_MODULE_ID_BM_CI_PORTAL,
99556 + e_MODULE_ID_FM, /**< Frame manager #1 module */
99557 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99558 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99559 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99560 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99561 + e_MODULE_ID_FM_PRS, /**< FM parser block */
99562 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
99563 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99564 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99565 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99566 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99567 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
99568 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99569 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
99570 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99571 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99572 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99573 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99574 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99575 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99576 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
99577 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
99578 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99579 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
99580 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
99581 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
99582 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99583 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
99584 +
99585 + e_MODULE_ID_DUMMY_LAST
99586 +} e_ModuleId;
99587 +
99588 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99589 +
99590 +
99591 +#define P1023_OFFSET_LAW 0x00000C08
99592 +#define P1023_OFFSET_ECM 0x00001000
99593 +#define P1023_OFFSET_DDR 0x00002000
99594 +#define P1023_OFFSET_I2C1 0x00003000
99595 +#define P1023_OFFSET_I2C2 0x00003100
99596 +#define P1023_OFFSET_DUART1 0x00004500
99597 +#define P1023_OFFSET_DUART2 0x00004600
99598 +#define P1023_OFFSET_LBC 0x00005000
99599 +#define P1023_OFFSET_ESPI 0x00007000
99600 +#define P1023_OFFSET_PCIE2 0x00009000
99601 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
99602 +#define P1023_OFFSET_PCIE1 0x0000A000
99603 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
99604 +#define P1023_OFFSET_PCIE3 0x0000B000
99605 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
99606 +#define P1023_OFFSET_DMA2 0x0000C100
99607 +#define P1023_OFFSET_GPIO 0x0000F000
99608 +#define P1023_OFFSET_L2_SRAM 0x00020000
99609 +#define P1023_OFFSET_DMA1 0x00021100
99610 +#define P1023_OFFSET_USB1 0x00022000
99611 +#define P1023_OFFSET_SEC_GEN 0x00030000
99612 +#define P1023_OFFSET_SEC_JQ0 0x00031000
99613 +#define P1023_OFFSET_SEC_JQ1 0x00032000
99614 +#define P1023_OFFSET_SEC_JQ2 0x00033000
99615 +#define P1023_OFFSET_SEC_JQ3 0x00034000
99616 +#define P1023_OFFSET_SEC_RTIC 0x00036000
99617 +#define P1023_OFFSET_SEC_QI 0x00037000
99618 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
99619 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
99620 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
99621 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
99622 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
99623 +#define P1023_OFFSET_PIC 0x00040000
99624 +#define P1023_OFFSET_MSI 0x00041600
99625 +#define P1023_OFFSET_AXI 0x00081000
99626 +#define P1023_OFFSET_QM 0x00088000
99627 +#define P1023_OFFSET_BM 0x0008A000
99628 +#define P1022_OFFSET_PM 0x000E1000
99629 +
99630 +#define P1023_OFFSET_GUTIL 0x000E0000
99631 +#define P1023_OFFSET_PM 0x000E1000
99632 +#define P1023_OFFSET_DEBUG 0x000E2000
99633 +#define P1023_OFFSET_SERDES 0x000E3000
99634 +#define P1023_OFFSET_ROM 0x000F0000
99635 +#define P1023_OFFSET_FM 0x00100000
99636 +
99637 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
99638 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
99639 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
99640 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
99641 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
99642 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
99643 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
99644 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
99645 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
99646 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
99647 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
99648 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
99649 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
99650 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
99651 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
99652 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
99653 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
99654 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
99655 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
99656 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
99657 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
99658 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
99659 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
99660 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
99661 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
99662 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
99663 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
99664 +
99665 +/* Offsets relative to QM or BM portals base */
99666 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
99667 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
99668 +
99669 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
99670 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
99671 +
99672 +/**************************************************************************//**
99673 + @Description Transaction source ID (for memory controllers error reporting).
99674 +*//***************************************************************************/
99675 +typedef enum e_TransSrc
99676 +{
99677 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
99678 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
99679 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
99680 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
99681 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
99682 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
99683 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
99684 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
99685 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
99686 +} e_TransSrc;
99687 +
99688 +/**************************************************************************//**
99689 + @Description Local Access Window Target interface ID
99690 +*//***************************************************************************/
99691 +typedef enum e_P1023LawTargetId
99692 +{
99693 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
99694 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
99695 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
99696 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
99697 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
99698 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
99699 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
99700 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
99701 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
99702 +} e_P1023LawTargetId;
99703 +
99704 +
99705 +/**************************************************************************//**
99706 + @Group 1023_init_grp P1023 Initialization Unit
99707 +
99708 + @Description P1023 initialization unit API functions, definitions and enums
99709 +
99710 + @{
99711 +*//***************************************************************************/
99712 +
99713 +/**************************************************************************//**
99714 + @Description Part ID and revision number
99715 +*//***************************************************************************/
99716 +typedef enum e_P1023DeviceName
99717 +{
99718 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
99719 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
99720 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
99721 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
99722 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
99723 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
99724 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
99725 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
99726 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
99727 +} e_P1023DeviceName;
99728 +
99729 +/**************************************************************************//**
99730 + @Description structure representing P1023 initialization parameters
99731 +*//***************************************************************************/
99732 +typedef struct t_P1023Params
99733 +{
99734 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
99735 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
99736 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
99737 +} t_P1023Params;
99738 +
99739 +/**************************************************************************//**
99740 + @Function P1023_ConfigAndInit
99741 +
99742 + @Description General initiation of the chip registers.
99743 +
99744 + @Param[in] p_P1023Params - A pointer to data structure of parameters
99745 +
99746 + @Return A handle to the P1023 data structure.
99747 +*//***************************************************************************/
99748 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
99749 +
99750 +/**************************************************************************//**
99751 + @Function P1023_Free
99752 +
99753 + @Description Free all resources.
99754 +
99755 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
99756 +
99757 + @Return E_OK on success; Other value otherwise.
99758 +*//***************************************************************************/
99759 +t_Error P1023_Free(t_Handle h_P1023);
99760 +
99761 +/**************************************************************************//**
99762 + @Function P1023_GetRevInfo
99763 +
99764 + @Description This routine enables access to chip and revision information.
99765 +
99766 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99767 +
99768 + @Return Part ID and revision.
99769 +*//***************************************************************************/
99770 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
99771 +
99772 +/**************************************************************************//**
99773 + @Function P1023_GetE500Factor
99774 +
99775 + @Description Returns E500 core clock multiplication factor.
99776 +
99777 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99778 + @Param[in] coreId - Id of the requested core.
99779 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
99780 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
99781 +
99782 + @Return E_OK on success; Other value otherwise.
99783 +*
99784 +*//***************************************************************************/
99785 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
99786 + uint32_t coreId,
99787 + uint32_t *p_E500MulFactor,
99788 + uint32_t *p_E500DivFactor);
99789 +
99790 +/**************************************************************************//**
99791 + @Function P1023_GetFmFactor
99792 +
99793 + @Description returns FM multiplication factors. (This value is returned using
99794 + two parameters to avoid using float parameter).
99795 +
99796 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99797 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
99798 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
99799 +
99800 + @Return E_OK on success; Other value otherwise.
99801 +*//***************************************************************************/
99802 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
99803 +
99804 +/**************************************************************************//**
99805 + @Function P1023_GetCcbFactor
99806 +
99807 + @Description returns system multiplication factor.
99808 +
99809 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99810 +
99811 + @Return System multiplication factor.
99812 +*//***************************************************************************/
99813 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
99814 +
99815 +#if 0
99816 +/**************************************************************************//**
99817 + @Function P1023_GetDdrFactor
99818 +
99819 + @Description returns the multiplication factor of the clock in for the DDR clock .
99820 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
99821 +
99822 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99823 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
99824 + @Param p_DdrDivFactor - returns DDR division factor.
99825 +
99826 + @Return E_OK on success; Other value otherwise..
99827 +*//***************************************************************************/
99828 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
99829 + uint32_t *p_DdrMulFactor,
99830 + uint32_t *p_DdrDivFactor);
99831 +
99832 +/**************************************************************************//**
99833 + @Function P1023_GetDdrType
99834 +
99835 + @Description returns the multiplication factor of the clock in for the DDR clock .
99836 +
99837 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
99838 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
99839 +
99840 + @Return E_OK on success; Other value otherwise.
99841 +*//***************************************************************************/
99842 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
99843 +#endif
99844 +
99845 +/** @} */ /* end of 1023_init_grp group */
99846 +/** @} */ /* end of 1023_grp group */
99847 +
99848 +#define CORE_E500V2
99849 +
99850 +#if 0 /* using unified values */
99851 +/*****************************************************************************
99852 + INTEGRATION-SPECIFIC MODULE CODES
99853 +******************************************************************************/
99854 +#define MODULE_UNKNOWN 0x00000000
99855 +#define MODULE_MEM 0x00010000
99856 +#define MODULE_MM 0x00020000
99857 +#define MODULE_CORE 0x00030000
99858 +#define MODULE_P1023 0x00040000
99859 +#define MODULE_MII 0x00050000
99860 +#define MODULE_PM 0x00060000
99861 +#define MODULE_MMU 0x00070000
99862 +#define MODULE_PIC 0x00080000
99863 +#define MODULE_L2_CACHE 0x00090000
99864 +#define MODULE_DUART 0x000a0000
99865 +#define MODULE_SERDES 0x000b0000
99866 +#define MODULE_PIO 0x000c0000
99867 +#define MODULE_QM 0x000d0000
99868 +#define MODULE_BM 0x000e0000
99869 +#define MODULE_SEC 0x000f0000
99870 +#define MODULE_FM 0x00100000
99871 +#define MODULE_FM_MURAM 0x00110000
99872 +#define MODULE_FM_PCD 0x00120000
99873 +#define MODULE_FM_RTC 0x00130000
99874 +#define MODULE_FM_MAC 0x00140000
99875 +#define MODULE_FM_PORT 0x00150000
99876 +#define MODULE_FM_MACSEC 0x00160000
99877 +#define MODULE_FM_MACSEC_SECY 0x00170000
99878 +#define MODULE_FM_SP 0x00280000
99879 +#define MODULE_ECM 0x00190000
99880 +#define MODULE_DMA 0x001a0000
99881 +#define MODULE_DDR 0x001b0000
99882 +#define MODULE_LAW 0x001c0000
99883 +#define MODULE_LBC 0x001d0000
99884 +#define MODULE_I2C 0x001e0000
99885 +#define MODULE_ESPI 0x001f0000
99886 +#define MODULE_PCI 0x00200000
99887 +#define MODULE_DPA_PORT 0x00210000
99888 +#define MODULE_USB 0x00220000
99889 +#endif /* using unified values */
99890 +
99891 +/*****************************************************************************
99892 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99893 +******************************************************************************/
99894 +/**************************************************************************//**
99895 + @Group lbc_exception_grp LBC Exception Unit
99896 +
99897 + @Description LBC Exception unit API functions, definitions and enums
99898 +
99899 + @{
99900 +*//***************************************************************************/
99901 +
99902 +/**************************************************************************//**
99903 + @Anchor lbc_exbm
99904 +
99905 + @Collection LBC Errors Bit Mask
99906 +
99907 + These errors are reported through the exceptions callback..
99908 + The values can be or'ed in any combination in the errors mask
99909 + parameter of the errors report structure.
99910 +
99911 + These errors can also be passed as a bit-mask to
99912 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99913 + for enabling or disabling error checking.
99914 + @{
99915 +*//***************************************************************************/
99916 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99917 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99918 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99919 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99920 +
99921 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99922 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99923 + /**< All possible errors */
99924 +/* @} */
99925 +/** @} */ /* end of lbc_exception_grp group */
99926 +
99927 +#define LBC_NUM_OF_BANKS 2
99928 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
99929 +#define LBC_ATOMIC_OPERATION_SUPPORT
99930 +#define LBC_PARITY_SUPPORT
99931 +#define LBC_ADDRESS_SHIFT_SUPPORT
99932 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99933 +#define LBC_HIGH_CLK_DIVIDERS
99934 +#define LBC_FCM_AVAILABLE
99935 +
99936 +
99937 +/*****************************************************************************
99938 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99939 +******************************************************************************/
99940 +#define LAW_ARCH_CCB
99941 +#define LAW_NUM_OF_WINDOWS 12
99942 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
99943 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
99944 +
99945 +
99946 +/*****************************************************************************
99947 + SPI INTEGRATION-SPECIFIC DEFINITIONS
99948 +******************************************************************************/
99949 +#define SPI_NUM_OF_CONTROLLERS 1
99950 +
99951 +/*****************************************************************************
99952 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
99953 +******************************************************************************/
99954 +
99955 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
99956 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
99957 +
99958 +/**************************************************************************//**
99959 + @Description Target interface of an inbound window
99960 +*//***************************************************************************/
99961 +typedef enum e_PciTargetInterface
99962 +{
99963 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
99964 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
99965 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
99966 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
99967 +
99968 +} e_PciTargetInterface;
99969 +
99970 +/*****************************************************************************
99971 + DDR INTEGRATION-SPECIFIC DEFINITIONS
99972 +******************************************************************************/
99973 +#define DDR_NUM_OF_VALID_CS 2
99974 +
99975 +/*****************************************************************************
99976 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99977 +******************************************************************************/
99978 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
99979 +
99980 +/*****************************************************************************
99981 + DMA INTEGRATION-SPECIFIC DEFINITIONS
99982 +******************************************************************************/
99983 +#define DMA_NUM_OF_CONTROLLERS 2
99984 +
99985 +
99986 +
99987 +
99988 +/*****************************************************************************
99989 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
99990 +******************************************************************************/
99991 +#define PTP_V2
99992 +
99993 +/**************************************************************************//**
99994 + @Function P1023_GetMuxControlReg
99995 +
99996 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
99997 + Control Register)
99998 +
99999 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100000 +
100001 + @Return Value of PMUXCR
100002 +*//***************************************************************************/
100003 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
100004 +
100005 +/**************************************************************************//**
100006 + @Function P1023_SetMuxControlReg
100007 +
100008 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
100009 + Control Register)
100010 +
100011 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100012 + @Param[in] val - the new value for PMUXCR.
100013 +
100014 + @Return None
100015 +*//***************************************************************************/
100016 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
100017 +
100018 +/**************************************************************************//**
100019 + @Function P1023_GetDeviceDisableStatusRegister
100020 +
100021 + @Description Returns the value of DEVDISR (Device Disable Register)
100022 +
100023 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100024 +
100025 + @Return Value of DEVDISR
100026 +*//***************************************************************************/
100027 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
100028 +
100029 +/**************************************************************************//**
100030 + @Function P1023_GetPorDeviceStatusRegister
100031 +
100032 + @Description Returns the value of POR Device Status Register
100033 +
100034 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100035 +
100036 + @Return POR Device Status Register
100037 +*//***************************************************************************/
100038 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
100039 +
100040 +/**************************************************************************//**
100041 + @Function P1023_GetPorBootModeStatusRegister
100042 +
100043 + @Description Returns the value of POR Boot Mode Status Register
100044 +
100045 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
100046 +
100047 + @Return POR Boot Mode Status Register value
100048 +*//***************************************************************************/
100049 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
100050 +
100051 +
100052 +#define PORDEVSR_SGMII1_DIS 0x10000000
100053 +#define PORDEVSR_SGMII2_DIS 0x08000000
100054 +#define PORDEVSR_ECP1 0x02000000
100055 +#define PORDEVSR_IO_SEL 0x00780000
100056 +#define PORDEVSR_IO_SEL_SHIFT 19
100057 +#define PORBMSR_HA 0x00070000
100058 +#define PORBMSR_HA_SHIFT 16
100059 +
100060 +#define DEVDISR_QM_BM 0x80000000
100061 +#define DEVDISR_FM 0x40000000
100062 +#define DEVDISR_PCIE1 0x20000000
100063 +#define DEVDISR_MAC_SEC 0x10000000
100064 +#define DEVDISR_ELBC 0x08000000
100065 +#define DEVDISR_PCIE2 0x04000000
100066 +#define DEVDISR_PCIE3 0x02000000
100067 +#define DEVDISR_CAAM 0x01000000
100068 +#define DEVDISR_USB0 0x00800000
100069 +#define DEVDISR_1588 0x00020000
100070 +#define DEVDISR_CORE0 0x00008000
100071 +#define DEVDISR_TB0 0x00004000
100072 +#define DEVDISR_CORE1 0x00002000
100073 +#define DEVDISR_TB1 0x00001000
100074 +#define DEVDISR_DMA1 0x00000400
100075 +#define DEVDISR_DMA2 0x00000200
100076 +#define DEVDISR_DDR 0x00000010
100077 +#define DEVDISR_TSEC1 0x00000080
100078 +#define DEVDISR_TSEC2 0x00000040
100079 +#define DEVDISR_SPI 0x00000008
100080 +#define DEVDISR_I2C 0x00000004
100081 +#define DEVDISR_DUART 0x00000002
100082 +
100083 +
100084 +#endif /* __PART_INTEGRATION_EXT_H */
100085 --- /dev/null
100086 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
100087 @@ -0,0 +1,276 @@
100088 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
100089 + * All rights reserved.
100090 + *
100091 + * Redistribution and use in source and binary forms, with or without
100092 + * modification, are permitted provided that the following conditions are met:
100093 + * * Redistributions of source code must retain the above copyright
100094 + * notice, this list of conditions and the following disclaimer.
100095 + * * Redistributions in binary form must reproduce the above copyright
100096 + * notice, this list of conditions and the following disclaimer in the
100097 + * documentation and/or other materials provided with the distribution.
100098 + * * Neither the name of Freescale Semiconductor nor the
100099 + * names of its contributors may be used to endorse or promote products
100100 + * derived from this software without specific prior written permission.
100101 + *
100102 + *
100103 + * ALTERNATIVELY, this software may be distributed under the terms of the
100104 + * GNU General Public License ("GPL") as published by the Free Software
100105 + * Foundation, either version 2 of that License or (at your option) any
100106 + * later version.
100107 + *
100108 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100109 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100110 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100111 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100112 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100113 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100114 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100115 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100116 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100117 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100118 + */
100119 +
100120 +/**************************************************************************//**
100121 + @File dpaa_integration_ext.h
100122 +
100123 + @Description P3040/P4080/P5020 FM external definitions and structures.
100124 +*//***************************************************************************/
100125 +#ifndef __DPAA_INTEGRATION_EXT_H
100126 +#define __DPAA_INTEGRATION_EXT_H
100127 +
100128 +#include "std_ext.h"
100129 +
100130 +
100131 +#define DPAA_VERSION 10
100132 +
100133 +typedef enum {
100134 + e_DPAA_SWPORTAL0 = 0,
100135 + e_DPAA_SWPORTAL1,
100136 + e_DPAA_SWPORTAL2,
100137 + e_DPAA_SWPORTAL3,
100138 + e_DPAA_SWPORTAL4,
100139 + e_DPAA_SWPORTAL5,
100140 + e_DPAA_SWPORTAL6,
100141 + e_DPAA_SWPORTAL7,
100142 + e_DPAA_SWPORTAL8,
100143 + e_DPAA_SWPORTAL9,
100144 + e_DPAA_SWPORTAL_DUMMY_LAST
100145 +} e_DpaaSwPortal;
100146 +
100147 +typedef enum {
100148 + e_DPAA_DCPORTAL0 = 0,
100149 + e_DPAA_DCPORTAL1,
100150 + e_DPAA_DCPORTAL2,
100151 + e_DPAA_DCPORTAL3,
100152 + e_DPAA_DCPORTAL4,
100153 + e_DPAA_DCPORTAL_DUMMY_LAST
100154 +} e_DpaaDcPortal;
100155 +
100156 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100157 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100158 +
100159 +/*****************************************************************************
100160 + QMan INTEGRATION-SPECIFIC DEFINITIONS
100161 +******************************************************************************/
100162 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
100163 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
100164 +#define QM_MAX_NUM_OF_SWP_AS 4
100165 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
100166 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
100167 +
100168 +/**************************************************************************//**
100169 + @Description Work Queue Channel assignments in QMan.
100170 +*//***************************************************************************/
100171 +typedef enum
100172 +{
100173 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
100174 + e_QM_FQ_CHANNEL_SWPORTAL1,
100175 + e_QM_FQ_CHANNEL_SWPORTAL2,
100176 + e_QM_FQ_CHANNEL_SWPORTAL3,
100177 + e_QM_FQ_CHANNEL_SWPORTAL4,
100178 + e_QM_FQ_CHANNEL_SWPORTAL5,
100179 + e_QM_FQ_CHANNEL_SWPORTAL6,
100180 + e_QM_FQ_CHANNEL_SWPORTAL7,
100181 + e_QM_FQ_CHANNEL_SWPORTAL8,
100182 + e_QM_FQ_CHANNEL_SWPORTAL9,
100183 +
100184 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
100185 + e_QM_FQ_CHANNEL_POOL2,
100186 + e_QM_FQ_CHANNEL_POOL3,
100187 + e_QM_FQ_CHANNEL_POOL4,
100188 + e_QM_FQ_CHANNEL_POOL5,
100189 + e_QM_FQ_CHANNEL_POOL6,
100190 + e_QM_FQ_CHANNEL_POOL7,
100191 + e_QM_FQ_CHANNEL_POOL8,
100192 + e_QM_FQ_CHANNEL_POOL9,
100193 + e_QM_FQ_CHANNEL_POOL10,
100194 + e_QM_FQ_CHANNEL_POOL11,
100195 + e_QM_FQ_CHANNEL_POOL12,
100196 + e_QM_FQ_CHANNEL_POOL13,
100197 + e_QM_FQ_CHANNEL_POOL14,
100198 + e_QM_FQ_CHANNEL_POOL15,
100199 +
100200 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
100201 + connected to FMan 0; assigned in incrementing order to
100202 + each sub-portal (SP) in the portal */
100203 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100204 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100205 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100206 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100207 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100208 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100209 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100210 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100211 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100212 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100213 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100214 +/* difference between 5020 and 4080 :) */
100215 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
100216 + e_QM_FQ_CHANNEL_FMAN1_SP1,
100217 + e_QM_FQ_CHANNEL_FMAN1_SP2,
100218 + e_QM_FQ_CHANNEL_FMAN1_SP3,
100219 + e_QM_FQ_CHANNEL_FMAN1_SP4,
100220 + e_QM_FQ_CHANNEL_FMAN1_SP5,
100221 + e_QM_FQ_CHANNEL_FMAN1_SP6,
100222 + e_QM_FQ_CHANNEL_FMAN1_SP7,
100223 + e_QM_FQ_CHANNEL_FMAN1_SP8,
100224 + e_QM_FQ_CHANNEL_FMAN1_SP9,
100225 + e_QM_FQ_CHANNEL_FMAN1_SP10,
100226 + e_QM_FQ_CHANNEL_FMAN1_SP11,
100227 +
100228 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
100229 + connected to SEC 4.x */
100230 +
100231 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
100232 + connected to PME */
100233 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
100234 + connected to RAID */
100235 +} e_QmFQChannel;
100236 +
100237 +/*****************************************************************************
100238 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100239 +******************************************************************************/
100240 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100241 +
100242 +
100243 +/*****************************************************************************
100244 + FM INTEGRATION-SPECIFIC DEFINITIONS
100245 +******************************************************************************/
100246 +#define INTG_MAX_NUM_OF_FM 2
100247 +
100248 +/* Ports defines */
100249 +#define FM_MAX_NUM_OF_1G_MACS 5
100250 +#define FM_MAX_NUM_OF_10G_MACS 1
100251 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100252 +#define FM_MAX_NUM_OF_OH_PORTS 7
100253 +
100254 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100255 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100256 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100257 +
100258 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100259 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100260 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100261 +
100262 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
100263 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100264 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
100265 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100266 +
100267 +/* Rams defines */
100268 +#define FM_MURAM_SIZE (160*KILOBYTE)
100269 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100270 +#define FM_NUM_OF_CTRL 2
100271 +
100272 +/* PCD defines */
100273 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100274 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100275 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100276 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
100277 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100278 +
100279 +/* RTC defines */
100280 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100281 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
100282 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100283 +
100284 +/* QMI defines */
100285 +#define QMI_MAX_NUM_OF_TNUMS 64
100286 +#define QMI_DEF_TNUMS_THRESH 48
100287 +
100288 +/* FPM defines */
100289 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100290 +
100291 +/* DMA defines */
100292 +#define DMA_THRESH_MAX_COMMQ 31
100293 +#define DMA_THRESH_MAX_BUF 127
100294 +
100295 +/* BMI defines */
100296 +#define BMI_MAX_NUM_OF_TASKS 128
100297 +#define BMI_MAX_NUM_OF_DMAS 32
100298 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100299 +#define PORT_MAX_WEIGHT 16
100300 +
100301 +
100302 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100303 +
100304 +/* p4080-rev1 unique features */
100305 +#define QM_CGS_NO_FRAME_MODE
100306 +
100307 +/* p4080 unique features */
100308 +#define FM_NO_DISPATCH_RAM_ECC
100309 +#define FM_NO_WATCHDOG
100310 +#define FM_NO_TNUM_AGING
100311 +#define FM_KG_NO_BYPASS_FQID_GEN
100312 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
100313 +#define FM_NO_BACKUP_POOLS
100314 +#define FM_NO_OP_OBSERVED_POOLS
100315 +#define FM_NO_ADVANCED_RATE_LIMITER
100316 +#define FM_NO_OP_OBSERVED_CGS
100317 +#define FM_HAS_TOTAL_DMAS
100318 +#define FM_KG_NO_IPPID_SUPPORT
100319 +#define FM_NO_GUARANTEED_RESET_VALUES
100320 +#define FM_MAC_RESET
100321 +
100322 +/* FM erratas */
100323 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
100324 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
100325 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
100326 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
100327 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
100328 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
100329 +
100330 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
100331 +#define FM_GRS_ERRATA_DTSEC_A002
100332 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
100333 +#define FM_GTS_ERRATA_DTSEC_A004
100334 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
100335 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
100336 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
100337 +
100338 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
100339 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
100340 +
100341 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
100342 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
100343 +
100344 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
100345 +
100346 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
100347 +
100348 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100349 +
100350 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
100351 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
100352 +
100353 +/*****************************************************************************
100354 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100355 +******************************************************************************/
100356 +#define NUM_OF_RX_SC 16
100357 +#define NUM_OF_TX_SC 16
100358 +
100359 +#define NUM_OF_SA_PER_RX_SC 2
100360 +#define NUM_OF_SA_PER_TX_SC 2
100361 +
100362 +
100363 +#endif /* __DPAA_INTEGRATION_EXT_H */
100364 --- /dev/null
100365 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
100366 @@ -0,0 +1,83 @@
100367 +/*
100368 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100369 + *
100370 + * Redistribution and use in source and binary forms, with or without
100371 + * modification, are permitted provided that the following conditions are met:
100372 + * * Redistributions of source code must retain the above copyright
100373 + * notice, this list of conditions and the following disclaimer.
100374 + * * Redistributions in binary form must reproduce the above copyright
100375 + * notice, this list of conditions and the following disclaimer in the
100376 + * documentation and/or other materials provided with the distribution.
100377 + * * Neither the name of Freescale Semiconductor nor the
100378 + * names of its contributors may be used to endorse or promote products
100379 + * derived from this software without specific prior written permission.
100380 + *
100381 + *
100382 + * ALTERNATIVELY, this software may be distributed under the terms of the
100383 + * GNU General Public License ("GPL") as published by the Free Software
100384 + * Foundation, either version 2 of that License or (at your option) any
100385 + * later version.
100386 + *
100387 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100388 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100389 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100390 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100391 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100392 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100393 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100394 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100395 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100396 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100397 + */
100398 +
100399 +/**************************************************************************//**
100400 +
100401 + @File part_ext.h
100402 +
100403 + @Description Definitions for the part (integration) module.
100404 +*//***************************************************************************/
100405 +
100406 +#ifndef __PART_EXT_H
100407 +#define __PART_EXT_H
100408 +
100409 +#include "std_ext.h"
100410 +#include "part_integration_ext.h"
100411 +
100412 +
100413 +#if !(defined(MPC8306) || \
100414 + defined(MPC8309) || \
100415 + defined(MPC834x) || \
100416 + defined(MPC836x) || \
100417 + defined(MPC832x) || \
100418 + defined(MPC837x) || \
100419 + defined(MPC8568) || \
100420 + defined(MPC8569) || \
100421 + defined(P1020) || \
100422 + defined(P1021) || \
100423 + defined(P1022) || \
100424 + defined(P1023) || \
100425 + defined(P2020) || \
100426 + defined(P2040) || \
100427 + defined(P3041) || \
100428 + defined(P4080) || \
100429 + defined(SC4080) || \
100430 + defined(P5020) || \
100431 + defined(MSC814x))
100432 +#error "unable to proceed without chip-definition"
100433 +#endif /* !(defined(MPC834x) || ... */
100434 +
100435 +
100436 +/**************************************************************************//*
100437 + @Description Part data structure - must be contained in any integration
100438 + data structure.
100439 +*//***************************************************************************/
100440 +typedef struct t_Part
100441 +{
100442 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100443 + /**< Returns the address of the module's memory map base. */
100444 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100445 + /**< Returns the module's ID according to its memory map base. */
100446 +} t_Part;
100447 +
100448 +
100449 +#endif /* __PART_EXT_H */
100450 --- /dev/null
100451 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
100452 @@ -0,0 +1,336 @@
100453 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100454 + * All rights reserved.
100455 + *
100456 + * Redistribution and use in source and binary forms, with or without
100457 + * modification, are permitted provided that the following conditions are met:
100458 + * * Redistributions of source code must retain the above copyright
100459 + * notice, this list of conditions and the following disclaimer.
100460 + * * Redistributions in binary form must reproduce the above copyright
100461 + * notice, this list of conditions and the following disclaimer in the
100462 + * documentation and/or other materials provided with the distribution.
100463 + * * Neither the name of Freescale Semiconductor nor the
100464 + * names of its contributors may be used to endorse or promote products
100465 + * derived from this software without specific prior written permission.
100466 + *
100467 + *
100468 + * ALTERNATIVELY, this software may be distributed under the terms of the
100469 + * GNU General Public License ("GPL") as published by the Free Software
100470 + * Foundation, either version 2 of that License or (at your option) any
100471 + * later version.
100472 + *
100473 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100474 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100475 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100476 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100477 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100478 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100479 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100480 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100481 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100482 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100483 + */
100484 +
100485 +/**************************************************************************//**
100486 + @File part_integration_ext.h
100487 +
100488 + @Description P3040/P4080/P5020 external definitions and structures.
100489 +*//***************************************************************************/
100490 +#ifndef __PART_INTEGRATION_EXT_H
100491 +#define __PART_INTEGRATION_EXT_H
100492 +
100493 +#include "std_ext.h"
100494 +#include "dpaa_integration_ext.h"
100495 +
100496 +
100497 +/**************************************************************************//**
100498 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
100499 +
100500 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
100501 +
100502 + @{
100503 +*//***************************************************************************/
100504 +
100505 +#define CORE_E500MC
100506 +
100507 +#define INTG_MAX_NUM_OF_CORES 1
100508 +
100509 +
100510 +/**************************************************************************//**
100511 + @Description Module types.
100512 +*//***************************************************************************/
100513 +typedef enum e_ModuleId
100514 +{
100515 + e_MODULE_ID_DUART_1 = 0,
100516 + e_MODULE_ID_DUART_2,
100517 + e_MODULE_ID_DUART_3,
100518 + e_MODULE_ID_DUART_4,
100519 + e_MODULE_ID_LAW,
100520 + e_MODULE_ID_LBC,
100521 + e_MODULE_ID_PAMU,
100522 + e_MODULE_ID_QM, /**< Queue manager module */
100523 + e_MODULE_ID_BM, /**< Buffer manager module */
100524 + e_MODULE_ID_QM_CE_PORTAL_0,
100525 + e_MODULE_ID_QM_CI_PORTAL_0,
100526 + e_MODULE_ID_QM_CE_PORTAL_1,
100527 + e_MODULE_ID_QM_CI_PORTAL_1,
100528 + e_MODULE_ID_QM_CE_PORTAL_2,
100529 + e_MODULE_ID_QM_CI_PORTAL_2,
100530 + e_MODULE_ID_QM_CE_PORTAL_3,
100531 + e_MODULE_ID_QM_CI_PORTAL_3,
100532 + e_MODULE_ID_QM_CE_PORTAL_4,
100533 + e_MODULE_ID_QM_CI_PORTAL_4,
100534 + e_MODULE_ID_QM_CE_PORTAL_5,
100535 + e_MODULE_ID_QM_CI_PORTAL_5,
100536 + e_MODULE_ID_QM_CE_PORTAL_6,
100537 + e_MODULE_ID_QM_CI_PORTAL_6,
100538 + e_MODULE_ID_QM_CE_PORTAL_7,
100539 + e_MODULE_ID_QM_CI_PORTAL_7,
100540 + e_MODULE_ID_QM_CE_PORTAL_8,
100541 + e_MODULE_ID_QM_CI_PORTAL_8,
100542 + e_MODULE_ID_QM_CE_PORTAL_9,
100543 + e_MODULE_ID_QM_CI_PORTAL_9,
100544 + e_MODULE_ID_BM_CE_PORTAL_0,
100545 + e_MODULE_ID_BM_CI_PORTAL_0,
100546 + e_MODULE_ID_BM_CE_PORTAL_1,
100547 + e_MODULE_ID_BM_CI_PORTAL_1,
100548 + e_MODULE_ID_BM_CE_PORTAL_2,
100549 + e_MODULE_ID_BM_CI_PORTAL_2,
100550 + e_MODULE_ID_BM_CE_PORTAL_3,
100551 + e_MODULE_ID_BM_CI_PORTAL_3,
100552 + e_MODULE_ID_BM_CE_PORTAL_4,
100553 + e_MODULE_ID_BM_CI_PORTAL_4,
100554 + e_MODULE_ID_BM_CE_PORTAL_5,
100555 + e_MODULE_ID_BM_CI_PORTAL_5,
100556 + e_MODULE_ID_BM_CE_PORTAL_6,
100557 + e_MODULE_ID_BM_CI_PORTAL_6,
100558 + e_MODULE_ID_BM_CE_PORTAL_7,
100559 + e_MODULE_ID_BM_CI_PORTAL_7,
100560 + e_MODULE_ID_BM_CE_PORTAL_8,
100561 + e_MODULE_ID_BM_CI_PORTAL_8,
100562 + e_MODULE_ID_BM_CE_PORTAL_9,
100563 + e_MODULE_ID_BM_CI_PORTAL_9,
100564 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
100565 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
100566 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
100567 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
100568 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
100569 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
100570 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100571 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100572 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100573 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100574 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100575 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100576 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100577 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100578 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100579 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100580 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100581 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100582 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100583 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100584 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100585 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100586 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100587 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100588 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100589 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
100590 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
100591 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
100592 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
100593 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
100594 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100595 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100596 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100597 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100598 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
100599 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100600 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
100601 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
100602 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
100603 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
100604 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
100605 +
100606 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
100607 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
100608 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
100609 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
100610 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
100611 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
100612 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
100613 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100614 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100615 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100616 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100617 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100618 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100619 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
100620 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100621 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100622 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100623 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
100624 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
100625 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100626 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100627 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100628 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
100629 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
100630 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
100631 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
100632 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
100633 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
100634 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
100635 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
100636 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
100637 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
100638 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
100639 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100640 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
100641 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
100642 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
100643 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
100644 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
100645 +
100646 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100647 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100648 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100649 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100650 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100651 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100652 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100653 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100654 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100655 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100656 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100657 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100658 +
100659 + e_MODULE_ID_MPIC, /**< MPIC */
100660 + e_MODULE_ID_GPIO, /**< GPIO */
100661 + e_MODULE_ID_SERDES, /**< SERDES */
100662 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100663 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100664 +
100665 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100666 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
100667 +
100668 + e_MODULE_ID_DUMMY_LAST
100669 +} e_ModuleId;
100670 +
100671 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100672 +
100673 +#if 0 /* using unified values */
100674 +/*****************************************************************************
100675 + INTEGRATION-SPECIFIC MODULE CODES
100676 +******************************************************************************/
100677 +#define MODULE_UNKNOWN 0x00000000
100678 +#define MODULE_MEM 0x00010000
100679 +#define MODULE_MM 0x00020000
100680 +#define MODULE_CORE 0x00030000
100681 +#define MODULE_CHIP 0x00040000
100682 +#define MODULE_PLTFRM 0x00050000
100683 +#define MODULE_PM 0x00060000
100684 +#define MODULE_MMU 0x00070000
100685 +#define MODULE_PIC 0x00080000
100686 +#define MODULE_CPC 0x00090000
100687 +#define MODULE_DUART 0x000a0000
100688 +#define MODULE_SERDES 0x000b0000
100689 +#define MODULE_PIO 0x000c0000
100690 +#define MODULE_QM 0x000d0000
100691 +#define MODULE_BM 0x000e0000
100692 +#define MODULE_SEC 0x000f0000
100693 +#define MODULE_LAW 0x00100000
100694 +#define MODULE_LBC 0x00110000
100695 +#define MODULE_PAMU 0x00120000
100696 +#define MODULE_FM 0x00130000
100697 +#define MODULE_FM_MURAM 0x00140000
100698 +#define MODULE_FM_PCD 0x00150000
100699 +#define MODULE_FM_RTC 0x00160000
100700 +#define MODULE_FM_MAC 0x00170000
100701 +#define MODULE_FM_PORT 0x00180000
100702 +#define MODULE_FM_SP 0x00190000
100703 +#define MODULE_DPA_PORT 0x001a0000
100704 +#define MODULE_MII 0x001b0000
100705 +#define MODULE_I2C 0x001c0000
100706 +#define MODULE_DMA 0x001d0000
100707 +#define MODULE_DDR 0x001e0000
100708 +#define MODULE_ESPI 0x001f0000
100709 +#define MODULE_DPAA_IPSEC 0x00200000
100710 +#endif /* using unified values */
100711 +
100712 +/*****************************************************************************
100713 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100714 +******************************************************************************/
100715 +#define PAMU_NUM_OF_PARTITIONS 5
100716 +
100717 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
100718 +
100719 +/*****************************************************************************
100720 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100721 +******************************************************************************/
100722 +#define LAW_NUM_OF_WINDOWS 32
100723 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
100724 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
100725 +
100726 +
100727 +/*****************************************************************************
100728 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100729 +******************************************************************************/
100730 +/**************************************************************************//**
100731 + @Group lbc_exception_grp LBC Exception Unit
100732 +
100733 + @Description LBC Exception unit API functions, definitions and enums
100734 +
100735 + @{
100736 +*//***************************************************************************/
100737 +
100738 +/**************************************************************************//**
100739 + @Anchor lbc_exbm
100740 +
100741 + @Collection LBC Errors Bit Mask
100742 +
100743 + These errors are reported through the exceptions callback..
100744 + The values can be or'ed in any combination in the errors mask
100745 + parameter of the errors report structure.
100746 +
100747 + These errors can also be passed as a bit-mask to
100748 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100749 + for enabling or disabling error checking.
100750 + @{
100751 +*//***************************************************************************/
100752 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100753 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100754 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100755 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
100756 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
100757 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100758 +
100759 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100760 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
100761 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
100762 + /**< All possible errors */
100763 +/* @} */
100764 +/** @} */ /* end of lbc_exception_grp group */
100765 +
100766 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100767 +
100768 +#define LBC_NUM_OF_BANKS 8
100769 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
100770 +#define LBC_ATOMIC_OPERATION_SUPPORT
100771 +#define LBC_PARITY_SUPPORT
100772 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100773 +#define LBC_HIGH_CLK_DIVIDERS
100774 +#define LBC_FCM_AVAILABLE
100775 +
100776 +/*****************************************************************************
100777 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100778 +******************************************************************************/
100779 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
100780 + Each port contains up to 32 i/O pins. */
100781 +
100782 +#define GPIO_VALID_PIN_MASKS \
100783 + { /* Port A */ 0xFFFFFFFF }
100784 +
100785 +#define GPIO_VALID_INTR_MASKS \
100786 + { /* Port A */ 0xFFFFFFFF }
100787 +
100788 +#endif /* __PART_INTEGRATION_EXT_H */
100789 --- /dev/null
100790 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
100791 @@ -0,0 +1,100 @@
100792 +/*
100793 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100794 + *
100795 + * Redistribution and use in source and binary forms, with or without
100796 + * modification, are permitted provided that the following conditions are met:
100797 + * * Redistributions of source code must retain the above copyright
100798 + * notice, this list of conditions and the following disclaimer.
100799 + * * Redistributions in binary form must reproduce the above copyright
100800 + * notice, this list of conditions and the following disclaimer in the
100801 + * documentation and/or other materials provided with the distribution.
100802 + * * Neither the name of Freescale Semiconductor nor the
100803 + * names of its contributors may be used to endorse or promote products
100804 + * derived from this software without specific prior written permission.
100805 + *
100806 + *
100807 + * ALTERNATIVELY, this software may be distributed under the terms of the
100808 + * GNU General Public License ("GPL") as published by the Free Software
100809 + * Foundation, either version 2 of that License or (at your option) any
100810 + * later version.
100811 + *
100812 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100813 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100814 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100815 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100816 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100817 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100818 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100819 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100820 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100821 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100822 + */
100823 +
100824 +
100825 +#ifndef __MATH_EXT_H
100826 +#define __MATH_EXT_H
100827 +
100828 +
100829 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
100830 +#include <linux/math.h>
100831 +#include <linux/math64.h>
100832 +
100833 +#elif defined(__MWERKS__)
100834 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
100835 +#define HIGH(x) (*(int32_t*)&x)
100836 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
100837 +#define UHIGH(x) (*(uint32_t*)&x)
100838 +
100839 +static const double big = 1.0e300;
100840 +
100841 +/* Macro for checking if a number is a power of 2 */
100842 +static __inline__ double ceil(double x)
100843 +{
100844 + int32_t i0,i1,j0; /*- cc 020130 -*/
100845 + uint32_t i,j; /*- cc 020130 -*/
100846 + i0 = HIGH(x);
100847 + i1 = LOW(x);
100848 + j0 = ((i0>>20)&0x7ff)-0x3ff;
100849 + if(j0<20) {
100850 + if(j0<0) { /* raise inexact if x != 0 */
100851 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
100852 + if(i0<0) {i0=0x80000000;i1=0;}
100853 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
100854 + }
100855 + } else {
100856 + i = (uint32_t)(0x000fffff)>>j0;
100857 + if(((i0&i)|i1)==0) return x; /* x is integral */
100858 + if(big+x>0.0) { /* raise inexact flag */
100859 + if(i0>0) i0 += (0x00100000)>>j0;
100860 + i0 &= (~i); i1=0;
100861 + }
100862 + }
100863 + } else if (j0>51) {
100864 + if(j0==0x400) return x+x; /* inf or NaN */
100865 + else return x; /* x is integral */
100866 + } else {
100867 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
100868 + if((i1&i)==0) return x; /* x is integral */
100869 + if(big+x>0.0) { /* raise inexact flag */
100870 + if(i0>0) {
100871 + if(j0==20) i0+=1;
100872 + else {
100873 + j = (uint32_t)(i1 + (1<<(52-j0)));
100874 + if(j<i1) i0+=1; /* got a carry */
100875 + i1 = (int32_t)j;
100876 + }
100877 + }
100878 + i1 &= (~i);
100879 + }
100880 + }
100881 + HIGH(x) = i0;
100882 + LOW(x) = i1;
100883 + return x;
100884 +}
100885 +
100886 +#else
100887 +#include <math.h>
100888 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
100889 +
100890 +
100891 +#endif /* __MATH_EXT_H */
100892 --- /dev/null
100893 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
100894 @@ -0,0 +1,435 @@
100895 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
100896 + * All rights reserved.
100897 + *
100898 + * Redistribution and use in source and binary forms, with or without
100899 + * modification, are permitted provided that the following conditions are met:
100900 + * * Redistributions of source code must retain the above copyright
100901 + * notice, this list of conditions and the following disclaimer.
100902 + * * Redistributions in binary form must reproduce the above copyright
100903 + * notice, this list of conditions and the following disclaimer in the
100904 + * documentation and/or other materials provided with the distribution.
100905 + * * Neither the name of Freescale Semiconductor nor the
100906 + * names of its contributors may be used to endorse or promote products
100907 + * derived from this software without specific prior written permission.
100908 + *
100909 + *
100910 + * ALTERNATIVELY, this software may be distributed under the terms of the
100911 + * GNU General Public License ("GPL") as published by the Free Software
100912 + * Foundation, either version 2 of that License or (at your option) any
100913 + * later version.
100914 + *
100915 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100916 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100917 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100918 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100919 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100920 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100921 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100922 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100923 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100924 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100925 + */
100926 +
100927 +
100928 +/**************************************************************************//**
100929 + @File ncsw_ext.h
100930 +
100931 + @Description General NetCommSw Standard Definitions
100932 +*//***************************************************************************/
100933 +
100934 +#ifndef __NCSW_EXT_H
100935 +#define __NCSW_EXT_H
100936 +
100937 +
100938 +#include "memcpy_ext.h"
100939 +
100940 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
100941 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
100942 +
100943 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
100944 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
100945 +
100946 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
100947 +
100948 +
100949 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
100950 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
100951 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
100952 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
100953 +
100954 +/* Little-Endian access macros */
100955 +
100956 +#define WRITE_UINT16_LE(arg, data) \
100957 + WRITE_UINT16((arg), SwapUint16(data))
100958 +
100959 +#define WRITE_UINT32_LE(arg, data) \
100960 + WRITE_UINT32((arg), SwapUint32(data))
100961 +
100962 +#define WRITE_UINT64_LE(arg, data) \
100963 + WRITE_UINT64((arg), SwapUint64(data))
100964 +
100965 +#define GET_UINT16_LE(arg) \
100966 + SwapUint16(GET_UINT16(arg))
100967 +
100968 +#define GET_UINT32_LE(arg) \
100969 + SwapUint32(GET_UINT32(arg))
100970 +
100971 +#define GET_UINT64_LE(arg) \
100972 + SwapUint64(GET_UINT64(arg))
100973 +
100974 +/* Write and Read again macros */
100975 +#define WRITE_UINT_SYNC(size, arg, data) \
100976 + do { \
100977 + WRITE_UINT##size((arg), (data)); \
100978 + CORE_MemoryBarrier(); \
100979 + } while (0)
100980 +
100981 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
100982 +
100983 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
100984 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
100985 +
100986 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
100987 +
100988 +
100989 +/*----------------------*/
100990 +/* Miscellaneous macros */
100991 +/*----------------------*/
100992 +
100993 +#define UNUSED(_x) ((void)(_x))
100994 +
100995 +#define KILOBYTE 0x400UL /* 1024 */
100996 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
100997 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
100998 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
100999 +
101000 +#ifndef NO_IRQ
101001 +#define NO_IRQ (0)
101002 +#endif
101003 +#define NCSW_MASTER_ID (0)
101004 +
101005 +/* Macro for checking if a number is a power of 2 */
101006 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
101007 +
101008 +/* Macro for calculating log of base 2 */
101009 +#define LOG2(num, log2Num) \
101010 + do \
101011 + { \
101012 + uint64_t tmp = (num); \
101013 + log2Num = 0; \
101014 + while (tmp > 1) \
101015 + { \
101016 + log2Num++; \
101017 + tmp >>= 1; \
101018 + } \
101019 + } while (0)
101020 +
101021 +#define NEXT_POWER_OF_2(_num, _nextPow) \
101022 +do \
101023 +{ \
101024 + if (POWER_OF_2(_num)) \
101025 + _nextPow = (_num); \
101026 + else \
101027 + { \
101028 + uint64_t tmp = (_num); \
101029 + _nextPow = 1; \
101030 + while (tmp) \
101031 + { \
101032 + _nextPow <<= 1; \
101033 + tmp >>= 1; \
101034 + } \
101035 + } \
101036 +} while (0)
101037 +
101038 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
101039 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
101040 +
101041 +/* Round up a number to be a multiple of a second number */
101042 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
101043 +
101044 +/* Timing macro for converting usec units to number of ticks. */
101045 +/* (number of usec * clock_Hz) / 1,000,000) - since */
101046 +/* clk is in MHz units, no division needed. */
101047 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
101048 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
101049 +
101050 +/* Timing macros for converting between nsec units and number of clocks. */
101051 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
101052 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
101053 +
101054 +/* Timing macros for converting between psec units and number of clocks. */
101055 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
101056 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
101057 +
101058 +/* Min, Max macros */
101059 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
101060 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
101061 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
101062 +
101063 +#define ABS(a) ((a<0)?(a*-1):a)
101064 +
101065 +#if !(defined(ARRAY_SIZE))
101066 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
101067 +#endif /* !defined(ARRAY_SIZE) */
101068 +
101069 +
101070 +/* possible alignments */
101071 +#define HALF_WORD_ALIGNMENT 2
101072 +#define WORD_ALIGNMENT 4
101073 +#define DOUBLE_WORD_ALIGNMENT 8
101074 +#define BURST_ALIGNMENT 32
101075 +
101076 +#define HALF_WORD_ALIGNED 0x00000001
101077 +#define WORD_ALIGNED 0x00000003
101078 +#define DOUBLE_WORD_ALIGNED 0x00000007
101079 +#define BURST_ALIGNED 0x0000001f
101080 +#ifndef IS_ALIGNED
101081 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
101082 +#endif /* IS_ALIGNED */
101083 +
101084 +
101085 +#define LAST_BUF 1
101086 +#define FIRST_BUF 2
101087 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
101088 +#define MIDDLE_BUF 4
101089 +
101090 +#define ARRAY_END -1
101091 +
101092 +#define ILLEGAL_BASE (~0)
101093 +
101094 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
101095 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
101096 +
101097 +
101098 +/**************************************************************************//**
101099 + @Description Timers operation mode
101100 +*//***************************************************************************/
101101 +typedef enum e_TimerMode
101102 +{
101103 + e_TIMER_MODE_INVALID = 0,
101104 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
101105 + after reaching the reference value. */
101106 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
101107 + after reaching the reference value. */
101108 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
101109 + after reaching the reference value. */
101110 +} e_TimerMode;
101111 +
101112 +
101113 +/**************************************************************************//**
101114 + @Description Enumeration (bit flags) of communication modes (Transmit,
101115 + receive or both).
101116 +*//***************************************************************************/
101117 +typedef enum e_CommMode
101118 +{
101119 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
101120 + e_COMM_MODE_RX = 1, /**< Only receive communication */
101121 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
101122 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
101123 +} e_CommMode;
101124 +
101125 +/**************************************************************************//**
101126 + @Description General Diagnostic Mode
101127 +*//***************************************************************************/
101128 +typedef enum e_DiagMode
101129 +{
101130 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
101131 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
101132 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
101133 + controller; e.g. IO-pins, SerDes, etc. */
101134 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
101135 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
101136 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
101137 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
101138 +} e_DiagMode;
101139 +
101140 +/**************************************************************************//**
101141 + @Description Possible RxStore callback responses.
101142 +*//***************************************************************************/
101143 +typedef enum e_RxStoreResponse
101144 +{
101145 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
101146 + in polling mode, start again invoking callback
101147 + only next time user invokes the receive routine;
101148 + in interrupt mode, start again invoking callback
101149 + only next time a receive event triggers an interrupt;
101150 + in all cases, received data that are pending are not
101151 + lost, rather, their processing is temporarily deferred;
101152 + in all cases, received data are processed in the order
101153 + in which they were received. */
101154 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
101155 +} e_RxStoreResponse;
101156 +
101157 +
101158 +/**************************************************************************//**
101159 + @Description General Handle
101160 +*//***************************************************************************/
101161 +typedef void * t_Handle; /**< handle, used as object's descriptor */
101162 +
101163 +/**************************************************************************//**
101164 + @Description MUTEX type
101165 +*//***************************************************************************/
101166 +typedef uint32_t t_Mutex;
101167 +
101168 +/**************************************************************************//**
101169 + @Description Error Code.
101170 +
101171 + The high word of the error code is the code of the software
101172 + module (driver). The low word is the error type (e_ErrorType).
101173 + To get the values from the error code, use GET_ERROR_TYPE()
101174 + and GET_ERROR_MODULE().
101175 +*//***************************************************************************/
101176 +typedef uint32_t t_Error;
101177 +
101178 +/**************************************************************************//**
101179 + @Description General prototype of interrupt service routine (ISR).
101180 +
101181 + @Param[in] handle - Optional handle of the module handling the interrupt.
101182 +
101183 + @Return None
101184 + *//***************************************************************************/
101185 +typedef void (t_Isr)(t_Handle handle);
101186 +
101187 +/**************************************************************************//**
101188 + @Anchor mem_attr
101189 +
101190 + @Collection Memory Attributes
101191 +
101192 + Various attributes of memory partitions. These values may be
101193 + or'ed together to create a mask of all memory attributes.
101194 + @{
101195 +*//***************************************************************************/
101196 +#define MEMORY_ATTR_CACHEABLE 0x00000001
101197 + /**< Memory is cacheable */
101198 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
101199 + /**< Memory can be accessed by QUICC Engine
101200 + through its secondary bus interface */
101201 +
101202 +/* @} */
101203 +
101204 +
101205 +/**************************************************************************//**
101206 + @Function t_GetBufFunction
101207 +
101208 + @Description User callback function called by driver to get data buffer.
101209 +
101210 + User provides this function. Driver invokes it.
101211 +
101212 + @Param[in] h_BufferPool - A handle to buffer pool manager
101213 + @Param[out] p_BufContextHandle - Returns the user's private context that
101214 + should be associated with the buffer
101215 +
101216 + @Return Pointer to data buffer, NULL if error
101217 + *//***************************************************************************/
101218 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
101219 + t_Handle *p_BufContextHandle);
101220 +
101221 +/**************************************************************************//**
101222 + @Function t_PutBufFunction
101223 +
101224 + @Description User callback function called by driver to return data buffer.
101225 +
101226 + User provides this function. Driver invokes it.
101227 +
101228 + @Param[in] h_BufferPool - A handle to buffer pool manager
101229 + @Param[in] p_Buffer - A pointer to buffer to return
101230 + @Param[in] h_BufContext - The user's private context associated with
101231 + the returned buffer
101232 +
101233 + @Return E_OK on success; Error code otherwise
101234 + *//***************************************************************************/
101235 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
101236 + uint8_t *p_Buffer,
101237 + t_Handle h_BufContext);
101238 +
101239 +/**************************************************************************//**
101240 + @Function t_PhysToVirt
101241 +
101242 + @Description Translates a physical address to the matching virtual address.
101243 +
101244 + @Param[in] addr - The physical address to translate.
101245 +
101246 + @Return Virtual address.
101247 +*//***************************************************************************/
101248 +typedef void * t_PhysToVirt(physAddress_t addr);
101249 +
101250 +/**************************************************************************//**
101251 + @Function t_VirtToPhys
101252 +
101253 + @Description Translates a virtual address to the matching physical address.
101254 +
101255 + @Param[in] addr - The virtual address to translate.
101256 +
101257 + @Return Physical address.
101258 +*//***************************************************************************/
101259 +typedef physAddress_t t_VirtToPhys(void *addr);
101260 +
101261 +/**************************************************************************//**
101262 + @Description Buffer Pool Information Structure.
101263 +*//***************************************************************************/
101264 +typedef struct t_BufferPoolInfo
101265 +{
101266 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
101267 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
101268 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
101269 + uint16_t bufferSize; /**< Buffer size (in bytes) */
101270 +
101271 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
101272 + physical addresses to virtual addresses */
101273 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
101274 + virtual addresses to physical addresses */
101275 +} t_BufferPoolInfo;
101276 +
101277 +
101278 +/**************************************************************************//**
101279 + @Description User callback function called by driver when transmit completed.
101280 +
101281 + User provides this function. Driver invokes it.
101282 +
101283 + @Param[in] h_App - Application's handle, as was provided to the
101284 + driver by the user
101285 + @Param[in] queueId - Transmit queue ID
101286 + @Param[in] p_Data - Pointer to the data buffer
101287 + @Param[in] h_BufContext - The user's private context associated with
101288 + the given data buffer
101289 + @Param[in] status - Transmit status and errors
101290 + @Param[in] flags - Driver-dependent information
101291 + *//***************************************************************************/
101292 +typedef void (t_TxConfFunction)(t_Handle h_App,
101293 + uint32_t queueId,
101294 + uint8_t *p_Data,
101295 + t_Handle h_BufContext,
101296 + uint16_t status,
101297 + uint32_t flags);
101298 +
101299 +/**************************************************************************//**
101300 + @Description User callback function called by driver with receive data.
101301 +
101302 + User provides this function. Driver invokes it.
101303 +
101304 + @Param[in] h_App - Application's handle, as was provided to the
101305 + driver by the user
101306 + @Param[in] queueId - Receive queue ID
101307 + @Param[in] p_Data - Pointer to the buffer with received data
101308 + @Param[in] h_BufContext - The user's private context associated with
101309 + the given data buffer
101310 + @Param[in] length - Length of received data
101311 + @Param[in] status - Receive status and errors
101312 + @Param[in] position - Position of buffer in frame
101313 + @Param[in] flags - Driver-dependent information
101314 +
101315 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
101316 + operation for all ready data.
101317 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
101318 + *//***************************************************************************/
101319 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
101320 + uint32_t queueId,
101321 + uint8_t *p_Data,
101322 + t_Handle h_BufContext,
101323 + uint32_t length,
101324 + uint16_t status,
101325 + uint8_t position,
101326 + uint32_t flags);
101327 +
101328 +
101329 +#endif /* __NCSW_EXT_H */
101330 --- /dev/null
101331 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
101332 @@ -0,0 +1,430 @@
101333 +/*
101334 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101335 + *
101336 + * Redistribution and use in source and binary forms, with or without
101337 + * modification, are permitted provided that the following conditions are met:
101338 + * * Redistributions of source code must retain the above copyright
101339 + * notice, this list of conditions and the following disclaimer.
101340 + * * Redistributions in binary form must reproduce the above copyright
101341 + * notice, this list of conditions and the following disclaimer in the
101342 + * documentation and/or other materials provided with the distribution.
101343 + * * Neither the name of Freescale Semiconductor nor the
101344 + * names of its contributors may be used to endorse or promote products
101345 + * derived from this software without specific prior written permission.
101346 + *
101347 + *
101348 + * ALTERNATIVELY, this software may be distributed under the terms of the
101349 + * GNU General Public License ("GPL") as published by the Free Software
101350 + * Foundation, either version 2 of that License or (at your option) any
101351 + * later version.
101352 + *
101353 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101354 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101355 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101356 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101357 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101358 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101359 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101360 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101361 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101362 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101363 + */
101364 +
101365 +
101366 +/**************************************************************************//**
101367 + @File net_ext.h
101368 +
101369 + @Description This file contains common and general netcomm headers definitions.
101370 +*//***************************************************************************/
101371 +#ifndef __NET_EXT_H
101372 +#define __NET_EXT_H
101373 +
101374 +#include "std_ext.h"
101375 +
101376 +
101377 +typedef uint8_t headerFieldPpp_t;
101378 +
101379 +#define NET_HEADER_FIELD_PPP_PID (1)
101380 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
101381 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
101382 +
101383 +
101384 +typedef uint8_t headerFieldPppoe_t;
101385 +
101386 +#define NET_HEADER_FIELD_PPPoE_VER (1)
101387 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
101388 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
101389 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
101390 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
101391 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
101392 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
101393 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
101394 +
101395 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
101396 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
101397 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
101398 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
101399 +
101400 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
101401 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
101402 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
101403 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
101404 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
101405 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
101406 +
101407 +
101408 +typedef uint8_t headerFieldEth_t;
101409 +
101410 +#define NET_HEADER_FIELD_ETH_DA (1)
101411 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
101412 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
101413 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
101414 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
101415 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
101416 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
101417 +
101418 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
101419 +
101420 +typedef uint16_t headerFieldIp_t;
101421 +
101422 +#define NET_HEADER_FIELD_IP_VER (1)
101423 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
101424 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
101425 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
101426 +
101427 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
101428 +
101429 +typedef uint16_t headerFieldIpv4_t;
101430 +
101431 +#define NET_HEADER_FIELD_IPv4_VER (1)
101432 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
101433 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
101434 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
101435 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
101436 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
101437 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
101438 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
101439 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
101440 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
101441 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
101442 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
101443 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
101444 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
101445 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
101446 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
101447 +
101448 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
101449 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
101450 +
101451 +
101452 +typedef uint8_t headerFieldIpv6_t;
101453 +
101454 +#define NET_HEADER_FIELD_IPv6_VER (1)
101455 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
101456 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
101457 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
101458 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
101459 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
101460 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
101461 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
101462 +
101463 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
101464 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
101465 +
101466 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
101467 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
101468 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
101469 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
101470 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
101471 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
101472 +
101473 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
101474 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
101475 +
101476 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
101477 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
101478 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
101479 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
101480 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
101481 +
101482 +
101483 +typedef uint16_t headerFieldTcp_t;
101484 +
101485 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
101486 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
101487 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
101488 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
101489 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
101490 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
101491 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
101492 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
101493 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
101494 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
101495 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
101496 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
101497 +
101498 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
101499 +
101500 +
101501 +typedef uint8_t headerFieldSctp_t;
101502 +
101503 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
101504 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
101505 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
101506 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
101507 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
101508 +
101509 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
101510 +
101511 +typedef uint8_t headerFieldDccp_t;
101512 +
101513 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
101514 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
101515 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
101516 +
101517 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
101518 +
101519 +
101520 +typedef uint8_t headerFieldUdp_t;
101521 +
101522 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
101523 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
101524 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
101525 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
101526 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
101527 +
101528 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
101529 +
101530 +typedef uint8_t headerFieldUdpLite_t;
101531 +
101532 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
101533 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
101534 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
101535 +
101536 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
101537 +
101538 +typedef uint8_t headerFieldUdpEncapEsp_t;
101539 +
101540 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
101541 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
101542 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
101543 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
101544 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
101545 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
101546 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
101547 +
101548 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
101549 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
101550 +
101551 +#define NET_HEADER_FIELD_IPHC_CID (1)
101552 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
101553 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
101554 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
101555 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
101556 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
101557 +
101558 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
101559 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
101560 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
101561 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
101562 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
101563 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
101564 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
101565 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
101566 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
101567 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
101568 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
101569 +
101570 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
101571 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
101572 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
101573 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
101574 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
101575 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
101576 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
101577 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
101578 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
101579 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
101580 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
101581 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
101582 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
101583 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
101584 +
101585 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
101586 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
101587 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
101588 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
101589 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
101590 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
101591 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
101592 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
101593 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
101594 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
101595 +
101596 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
101597 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
101598 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
101599 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
101600 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
101601 +
101602 +
101603 +typedef uint8_t headerFieldVlan_t;
101604 +
101605 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
101606 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
101607 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
101608 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
101609 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
101610 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
101611 +
101612 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
101613 + NET_HEADER_FIELD_VLAN_CFI | \
101614 + NET_HEADER_FIELD_VLAN_VID)
101615 +
101616 +
101617 +typedef uint8_t headerFieldLlc_t;
101618 +
101619 +#define NET_HEADER_FIELD_LLC_DSAP (1)
101620 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
101621 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
101622 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
101623 +
101624 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
101625 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
101626 +
101627 +
101628 +typedef uint8_t headerFieldSnap_t;
101629 +
101630 +#define NET_HEADER_FIELD_SNAP_OUI (1)
101631 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
101632 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
101633 +
101634 +
101635 +typedef uint8_t headerFieldLlcSnap_t;
101636 +
101637 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
101638 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
101639 +
101640 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
101641 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
101642 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
101643 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
101644 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
101645 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
101646 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
101647 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
101648 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
101649 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
101650 +
101651 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
101652 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
101653 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
101654 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
101655 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
101656 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
101657 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
101658 +
101659 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
101660 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
101661 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
101662 +
101663 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
101664 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
101665 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
101666 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
101667 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
101668 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
101669 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
101670 +
101671 +
101672 +typedef uint8_t headerFieldGre_t;
101673 +
101674 +#define NET_HEADER_FIELD_GRE_TYPE (1)
101675 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
101676 +
101677 +
101678 +typedef uint8_t headerFieldMinencap_t;
101679 +
101680 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
101681 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
101682 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
101683 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
101684 +
101685 +
101686 +typedef uint8_t headerFieldIpsecAh_t;
101687 +
101688 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
101689 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
101690 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
101691 +
101692 +
101693 +typedef uint8_t headerFieldIpsecEsp_t;
101694 +
101695 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
101696 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
101697 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
101698 +
101699 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
101700 +
101701 +
101702 +typedef uint8_t headerFieldMpls_t;
101703 +
101704 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
101705 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
101706 +
101707 +
101708 +typedef uint8_t headerFieldMacsec_t;
101709 +
101710 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
101711 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
101712 +
101713 +
101714 +typedef enum {
101715 + HEADER_TYPE_NONE = 0,
101716 + HEADER_TYPE_PAYLOAD,
101717 + HEADER_TYPE_ETH,
101718 + HEADER_TYPE_VLAN,
101719 + HEADER_TYPE_IPv4,
101720 + HEADER_TYPE_IPv6,
101721 + HEADER_TYPE_IP,
101722 + HEADER_TYPE_TCP,
101723 + HEADER_TYPE_UDP,
101724 + HEADER_TYPE_UDP_LITE,
101725 + HEADER_TYPE_IPHC,
101726 + HEADER_TYPE_SCTP,
101727 + HEADER_TYPE_SCTP_CHUNK_DATA,
101728 + HEADER_TYPE_PPPoE,
101729 + HEADER_TYPE_PPP,
101730 + HEADER_TYPE_PPPMUX,
101731 + HEADER_TYPE_PPPMUX_SUBFRAME,
101732 + HEADER_TYPE_L2TPv2,
101733 + HEADER_TYPE_L2TPv3_CTRL,
101734 + HEADER_TYPE_L2TPv3_SESS,
101735 + HEADER_TYPE_LLC,
101736 + HEADER_TYPE_LLC_SNAP,
101737 + HEADER_TYPE_NLPID,
101738 + HEADER_TYPE_SNAP,
101739 + HEADER_TYPE_MPLS,
101740 + HEADER_TYPE_IPSEC_AH,
101741 + HEADER_TYPE_IPSEC_ESP,
101742 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
101743 + HEADER_TYPE_MACSEC,
101744 + HEADER_TYPE_GRE,
101745 + HEADER_TYPE_MINENCAP,
101746 + HEADER_TYPE_DCCP,
101747 + HEADER_TYPE_ICMP,
101748 + HEADER_TYPE_IGMP,
101749 + HEADER_TYPE_ARP,
101750 + HEADER_TYPE_CAPWAP,
101751 + HEADER_TYPE_CAPWAP_DTLS,
101752 + HEADER_TYPE_RFC2684,
101753 + HEADER_TYPE_USER_DEFINED_L2,
101754 + HEADER_TYPE_USER_DEFINED_L3,
101755 + HEADER_TYPE_USER_DEFINED_L4,
101756 + HEADER_TYPE_USER_DEFINED_SHIM1,
101757 + HEADER_TYPE_USER_DEFINED_SHIM2,
101758 + MAX_HEADER_TYPE_COUNT
101759 +} e_NetHeaderType;
101760 +
101761 +
101762 +#endif /* __NET_EXT_H */
101763 --- /dev/null
101764 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
101765 @@ -0,0 +1,48 @@
101766 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101767 + * All rights reserved.
101768 + *
101769 + * Redistribution and use in source and binary forms, with or without
101770 + * modification, are permitted provided that the following conditions are met:
101771 + * * Redistributions of source code must retain the above copyright
101772 + * notice, this list of conditions and the following disclaimer.
101773 + * * Redistributions in binary form must reproduce the above copyright
101774 + * notice, this list of conditions and the following disclaimer in the
101775 + * documentation and/or other materials provided with the distribution.
101776 + * * Neither the name of Freescale Semiconductor nor the
101777 + * names of its contributors may be used to endorse or promote products
101778 + * derived from this software without specific prior written permission.
101779 + *
101780 + *
101781 + * ALTERNATIVELY, this software may be distributed under the terms of the
101782 + * GNU General Public License ("GPL") as published by the Free Software
101783 + * Foundation, either version 2 of that License or (at your option) any
101784 + * later version.
101785 + *
101786 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101787 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101788 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101789 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101790 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101791 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101792 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101793 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101794 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101795 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101796 + */
101797 +
101798 +
101799 +/**************************************************************************//**
101800 + @File std_ext.h
101801 +
101802 + @Description General Standard Definitions
101803 +*//***************************************************************************/
101804 +
101805 +#ifndef __STD_EXT_H
101806 +#define __STD_EXT_H
101807 +
101808 +
101809 +#include "types_ext.h"
101810 +#include "ncsw_ext.h"
101811 +
101812 +
101813 +#endif /* __STD_EXT_H */
101814 --- /dev/null
101815 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
101816 @@ -0,0 +1,49 @@
101817 +/*
101818 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101819 + *
101820 + * Redistribution and use in source and binary forms, with or without
101821 + * modification, are permitted provided that the following conditions are met:
101822 + * * Redistributions of source code must retain the above copyright
101823 + * notice, this list of conditions and the following disclaimer.
101824 + * * Redistributions in binary form must reproduce the above copyright
101825 + * notice, this list of conditions and the following disclaimer in the
101826 + * documentation and/or other materials provided with the distribution.
101827 + * * Neither the name of Freescale Semiconductor nor the
101828 + * names of its contributors may be used to endorse or promote products
101829 + * derived from this software without specific prior written permission.
101830 + *
101831 + *
101832 + * ALTERNATIVELY, this software may be distributed under the terms of the
101833 + * GNU General Public License ("GPL") as published by the Free Software
101834 + * Foundation, either version 2 of that License or (at your option) any
101835 + * later version.
101836 + *
101837 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101838 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101839 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101840 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101841 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101842 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101843 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101844 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101845 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101846 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101847 + */
101848 +
101849 +
101850 +#ifndef __STDARG_EXT_H
101851 +#define __STDARG_EXT_H
101852 +
101853 +
101854 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
101855 +#include <stdarg.h>
101856 +
101857 +#else
101858 +#include <stdarg.h>
101859 +
101860 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
101861 +
101862 +#include "std_ext.h"
101863 +
101864 +
101865 +#endif /* __STDARG_EXT_H */
101866 --- /dev/null
101867 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
101868 @@ -0,0 +1,162 @@
101869 +/*
101870 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101871 + *
101872 + * Redistribution and use in source and binary forms, with or without
101873 + * modification, are permitted provided that the following conditions are met:
101874 + * * Redistributions of source code must retain the above copyright
101875 + * notice, this list of conditions and the following disclaimer.
101876 + * * Redistributions in binary form must reproduce the above copyright
101877 + * notice, this list of conditions and the following disclaimer in the
101878 + * documentation and/or other materials provided with the distribution.
101879 + * * Neither the name of Freescale Semiconductor nor the
101880 + * names of its contributors may be used to endorse or promote products
101881 + * derived from this software without specific prior written permission.
101882 + *
101883 + *
101884 + * ALTERNATIVELY, this software may be distributed under the terms of the
101885 + * GNU General Public License ("GPL") as published by the Free Software
101886 + * Foundation, either version 2 of that License or (at your option) any
101887 + * later version.
101888 + *
101889 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101890 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101891 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101892 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101893 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101894 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101895 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101896 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101897 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101898 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101899 + */
101900 +
101901 +
101902 +
101903 +#ifndef __STDLIB_EXT_H
101904 +#define __STDLIB_EXT_H
101905 +
101906 +
101907 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
101908 +#include "stdarg_ext.h"
101909 +#include "std_ext.h"
101910 +
101911 +
101912 +/**
101913 + * strtoul - convert a string to an uint32_t
101914 + * @cp: The start of the string
101915 + * @endp: A pointer to the end of the parsed string will be placed here
101916 + * @base: The number base to use
101917 + */
101918 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
101919 +
101920 +/**
101921 + * strtol - convert a string to a int32_t
101922 + * @cp: The start of the string
101923 + * @endp: A pointer to the end of the parsed string will be placed here
101924 + * @base: The number base to use
101925 + */
101926 +long strtol(const char *cp,char **endp,uint32_t base);
101927 +
101928 +/**
101929 + * strtoull - convert a string to an uint64_t
101930 + * @cp: The start of the string
101931 + * @endp: A pointer to the end of the parsed string will be placed here
101932 + * @base: The number base to use
101933 + */
101934 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
101935 +
101936 +/**
101937 + * strtoll - convert a string to a int64 long
101938 + * @cp: The start of the string
101939 + * @endp: A pointer to the end of the parsed string will be placed here
101940 + * @base: The number base to use
101941 + */
101942 +long long strtoll(const char *cp,char **endp,uint32_t base);
101943 +
101944 +/**
101945 + * atoi - convert a character to a int
101946 + * @s: The start of the string
101947 + */
101948 +int atoi(const char *s);
101949 +
101950 +/**
101951 + * strnlen - Find the length of a length-limited string
101952 + * @s: The string to be sized
101953 + * @count: The maximum number of bytes to search
101954 + */
101955 +size_t strnlen(const char * s, size_t count);
101956 +
101957 +/**
101958 + * strlen - Find the length of a string
101959 + * @s: The string to be sized
101960 + */
101961 +size_t strlen(const char * s);
101962 +
101963 +/**
101964 + * strtok - Split a string into tokens
101965 + * @s: The string to be searched
101966 + * @ct: The characters to search for
101967 + *
101968 + * WARNING: strtok is deprecated, use strsep instead.
101969 + */
101970 +char * strtok(char * s,const char * ct);
101971 +
101972 +/**
101973 + * strncpy - Copy a length-limited, %NUL-terminated string
101974 + * @dest: Where to copy the string to
101975 + * @src: Where to copy the string from
101976 + * @count: The maximum number of bytes to copy
101977 + *
101978 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
101979 + * However, the result is not %NUL-terminated if the source exceeds
101980 + * @count bytes.
101981 + */
101982 +char * strncpy(char * dest,const char *src,size_t count);
101983 +
101984 +/**
101985 + * strcpy - Copy a %NUL terminated string
101986 + * @dest: Where to copy the string to
101987 + * @src: Where to copy the string from
101988 + */
101989 +char * strcpy(char * dest,const char *src);
101990 +
101991 +/**
101992 + * vsscanf - Unformat a buffer into a list of arguments
101993 + * @buf: input buffer
101994 + * @fmt: format of buffer
101995 + * @args: arguments
101996 + */
101997 +int vsscanf(const char * buf, const char * fmt, va_list args);
101998 +
101999 +/**
102000 + * vsnprintf - Format a string and place it in a buffer
102001 + * @buf: The buffer to place the result into
102002 + * @size: The size of the buffer, including the trailing null space
102003 + * @fmt: The format string to use
102004 + * @args: Arguments for the format string
102005 + *
102006 + * Call this function if you are already dealing with a va_list.
102007 + * You probably want snprintf instead.
102008 + */
102009 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
102010 +
102011 +/**
102012 + * vsprintf - Format a string and place it in a buffer
102013 + * @buf: The buffer to place the result into
102014 + * @fmt: The format string to use
102015 + * @args: Arguments for the format string
102016 + *
102017 + * Call this function if you are already dealing with a va_list.
102018 + * You probably want sprintf instead.
102019 + */
102020 +int vsprintf(char *buf, const char *fmt, va_list args);
102021 +
102022 +#else
102023 +#include <stdlib.h>
102024 +#include <stdio.h>
102025 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102026 +
102027 +#include "std_ext.h"
102028 +
102029 +
102030 +#endif /* __STDLIB_EXT_H */
102031 --- /dev/null
102032 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
102033 @@ -0,0 +1,56 @@
102034 +/*
102035 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102036 + *
102037 + * Redistribution and use in source and binary forms, with or without
102038 + * modification, are permitted provided that the following conditions are met:
102039 + * * Redistributions of source code must retain the above copyright
102040 + * notice, this list of conditions and the following disclaimer.
102041 + * * Redistributions in binary form must reproduce the above copyright
102042 + * notice, this list of conditions and the following disclaimer in the
102043 + * documentation and/or other materials provided with the distribution.
102044 + * * Neither the name of Freescale Semiconductor nor the
102045 + * names of its contributors may be used to endorse or promote products
102046 + * derived from this software without specific prior written permission.
102047 + *
102048 + *
102049 + * ALTERNATIVELY, this software may be distributed under the terms of the
102050 + * GNU General Public License ("GPL") as published by the Free Software
102051 + * Foundation, either version 2 of that License or (at your option) any
102052 + * later version.
102053 + *
102054 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102055 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102056 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102057 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102058 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102059 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102060 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102061 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102062 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102063 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102064 + */
102065 +
102066 +
102067 +#ifndef __STRING_EXT_H
102068 +#define __STRING_EXT_H
102069 +
102070 +
102071 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102072 +#include <linux/kernel.h>
102073 +#include <linux/string.h>
102074 +extern char * strtok ( char * str, const char * delimiters );
102075 +
102076 +#elif defined(__KERNEL__)
102077 +#include "linux/types.h"
102078 +#include "linux/posix_types.h"
102079 +#include "linux/string.h"
102080 +
102081 +#else
102082 +#include <string.h>
102083 +
102084 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102085 +
102086 +#include "std_ext.h"
102087 +
102088 +
102089 +#endif /* __STRING_EXT_H */
102090 --- /dev/null
102091 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
102092 @@ -0,0 +1,62 @@
102093 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102094 + * All rights reserved.
102095 + *
102096 + * Redistribution and use in source and binary forms, with or without
102097 + * modification, are permitted provided that the following conditions are met:
102098 + * * Redistributions of source code must retain the above copyright
102099 + * notice, this list of conditions and the following disclaimer.
102100 + * * Redistributions in binary form must reproduce the above copyright
102101 + * notice, this list of conditions and the following disclaimer in the
102102 + * documentation and/or other materials provided with the distribution.
102103 + * * Neither the name of Freescale Semiconductor nor the
102104 + * names of its contributors may be used to endorse or promote products
102105 + * derived from this software without specific prior written permission.
102106 + *
102107 + *
102108 + * ALTERNATIVELY, this software may be distributed under the terms of the
102109 + * GNU General Public License ("GPL") as published by the Free Software
102110 + * Foundation, either version 2 of that License or (at your option) any
102111 + * later version.
102112 + *
102113 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102114 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102115 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102116 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102117 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102118 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102119 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102120 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102121 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102122 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102123 + */
102124 +
102125 +
102126 +/**************************************************************************//**
102127 + @File types_ext.h
102128 +
102129 + @Description General types Standard Definitions
102130 +*//***************************************************************************/
102131 +
102132 +#ifndef __TYPES_EXT_H
102133 +#define __TYPES_EXT_H
102134 +
102135 +#if defined(NCSW_LINUX)
102136 +#include "types_linux.h"
102137 +
102138 +#elif defined(NCSW_VXWORKS)
102139 +#include "types_vxworks.h"
102140 +
102141 +#elif defined(__GNUC__) && defined(__cplusplus)
102142 +#include "types_bb_gpp.h"
102143 +
102144 +#elif defined(__GNUC__)
102145 +#include "types_bb_gcc.h"
102146 +
102147 +#elif defined(__ghs__)
102148 +#include "types_ghs.h"
102149 +
102150 +#else
102151 +#include "types_dflt.h"
102152 +#endif /* defined (__ROCOO__) */
102153 +
102154 +#endif /* __TYPES_EXT_H */
102155 --- /dev/null
102156 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
102157 @@ -0,0 +1,56 @@
102158 +/*
102159 + * Copyright 2012 Freescale Semiconductor Inc.
102160 + *
102161 + * Redistribution and use in source and binary forms, with or without
102162 + * modification, are permitted provided that the following conditions are met:
102163 + * * Redistributions of source code must retain the above copyright
102164 + * notice, this list of conditions and the following disclaimer.
102165 + * * Redistributions in binary form must reproduce the above copyright
102166 + * notice, this list of conditions and the following disclaimer in the
102167 + * documentation and/or other materials provided with the distribution.
102168 + * * Neither the name of Freescale Semiconductor nor the
102169 + * names of its contributors may be used to endorse or promote products
102170 + * derived from this software without specific prior written permission.
102171 + *
102172 + *
102173 + * ALTERNATIVELY, this software may be distributed under the terms of the
102174 + * GNU General Public License ("GPL") as published by the Free Software
102175 + * Foundation, either version 2 of that License or (at your option) any
102176 + * later version.
102177 + *
102178 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102179 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102180 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102181 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102182 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102183 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102184 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102185 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102186 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102187 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102188 + */
102189 +
102190 +
102191 +/**************************************************************************//**
102192 + @File debug_ext.h
102193 +
102194 + @Description Debug mode definitions.
102195 +*//***************************************************************************/
102196 +
102197 +#ifndef __XX_COMMON_H
102198 +#define __XX_COMMON_H
102199 +
102200 +/*****************************************************************************
102201 + * UNIFIED MODULE CODES
102202 + *****************************************************************************/
102203 +#define MODULE_UNKNOWN 0x00000000
102204 +#define MODULE_FM 0x00010000
102205 +#define MODULE_FM_MURAM 0x00020000
102206 +#define MODULE_FM_PCD 0x00030000
102207 +#define MODULE_FM_RTC 0x00040000
102208 +#define MODULE_FM_MAC 0x00050000
102209 +#define MODULE_FM_PORT 0x00060000
102210 +#define MODULE_MM 0x00070000
102211 +#define MODULE_FM_SP 0x00080000
102212 +#define MODULE_FM_MACSEC 0x00090000
102213 +#endif /* __XX_COMMON_H */
102214 --- /dev/null
102215 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
102216 @@ -0,0 +1,791 @@
102217 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102218 + * All rights reserved.
102219 + *
102220 + * Redistribution and use in source and binary forms, with or without
102221 + * modification, are permitted provided that the following conditions are met:
102222 + * * Redistributions of source code must retain the above copyright
102223 + * notice, this list of conditions and the following disclaimer.
102224 + * * Redistributions in binary form must reproduce the above copyright
102225 + * notice, this list of conditions and the following disclaimer in the
102226 + * documentation and/or other materials provided with the distribution.
102227 + * * Neither the name of Freescale Semiconductor nor the
102228 + * names of its contributors may be used to endorse or promote products
102229 + * derived from this software without specific prior written permission.
102230 + *
102231 + *
102232 + * ALTERNATIVELY, this software may be distributed under the terms of the
102233 + * GNU General Public License ("GPL") as published by the Free Software
102234 + * Foundation, either version 2 of that License or (at your option) any
102235 + * later version.
102236 + *
102237 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102238 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102239 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102240 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102241 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102242 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102243 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102244 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102245 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102246 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102247 + */
102248 +
102249 +
102250 +/**************************************************************************//**
102251 + @File xx_ext.h
102252 +
102253 + @Description Prototypes, externals and typedefs for system-supplied
102254 + (external) routines
102255 +*//***************************************************************************/
102256 +
102257 +#ifndef __XX_EXT_H
102258 +#define __XX_EXT_H
102259 +
102260 +#include "std_ext.h"
102261 +#include "xx_common.h"
102262 +#include "part_ext.h"
102263 +
102264 +
102265 +
102266 +/**************************************************************************//**
102267 + @Group xx_id XX Interface (System call hooks)
102268 +
102269 + @Description Prototypes, externals and typedefs for system-supplied
102270 + (external) routines
102271 +
102272 + @{
102273 +*//***************************************************************************/
102274 +
102275 +#ifdef DEBUG_XX_MALLOC
102276 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
102277 +
102278 +void * XX_MallocSmartDebug(uint32_t size,
102279 + int memPartitionId,
102280 + uint32_t alignment,
102281 + char *fname,
102282 + int line);
102283 +
102284 +#define XX_Malloc(sz) \
102285 + XX_MallocDebug((sz), __FILE__, __LINE__)
102286 +
102287 +#define XX_MallocSmart(sz, memt, al) \
102288 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
102289 +
102290 +#else /* not DEBUG_XX_MALLOC */
102291 +/**************************************************************************//**
102292 + @Function XX_Malloc
102293 +
102294 + @Description allocates contiguous block of memory.
102295 +
102296 + @Param[in] size - Number of bytes to allocate.
102297 +
102298 + @Return The address of the newly allocated block on success, NULL on failure.
102299 +*//***************************************************************************/
102300 +void * XX_Malloc(uint32_t size);
102301 +
102302 +/**************************************************************************//**
102303 + @Function XX_MallocSmart
102304 +
102305 + @Description Allocates contiguous block of memory in a specified
102306 + alignment and from the specified segment.
102307 +
102308 + @Param[in] size - Number of bytes to allocate.
102309 + @Param[in] memPartitionId - Memory partition ID; The value zero must
102310 + be mapped to the default heap partition.
102311 + @Param[in] alignment - Required memory alignment (in bytes).
102312 +
102313 + @Return The address of the newly allocated block on success, NULL on failure.
102314 +*//***************************************************************************/
102315 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
102316 +#endif /* not DEBUG_XX_MALLOC */
102317 +
102318 +/**************************************************************************//**
102319 + @Function XX_FreeSmart
102320 +
102321 + @Description Frees the memory block pointed to by "p".
102322 + Only for memory allocated by XX_MallocSmart
102323 +
102324 + @Param[in] p_Memory - pointer to the memory block.
102325 +
102326 + @Return None.
102327 +*//***************************************************************************/
102328 +void XX_FreeSmart(void *p_Memory);
102329 +
102330 +/**************************************************************************//**
102331 + @Function XX_Free
102332 +
102333 + @Description frees the memory block pointed to by "p".
102334 +
102335 + @Param[in] p_Memory - pointer to the memory block.
102336 +
102337 + @Return None.
102338 +*//***************************************************************************/
102339 +void XX_Free(void *p_Memory);
102340 +
102341 +/**************************************************************************//**
102342 + @Function XX_Print
102343 +
102344 + @Description print a string.
102345 +
102346 + @Param[in] str - string to print.
102347 +
102348 + @Return None.
102349 +*//***************************************************************************/
102350 +void XX_Print(char *str, ...);
102351 +
102352 +/**************************************************************************//**
102353 + @Function XX_SetIntr
102354 +
102355 + @Description Set an interrupt service routine for a specific interrupt source.
102356 +
102357 + @Param[in] irq - Interrupt ID (system-specific number).
102358 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
102359 + @Param[in] handle - The argument for the user callback routine.
102360 +
102361 + @Return E_OK on success; error code otherwise..
102362 +*//***************************************************************************/
102363 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
102364 +
102365 +/**************************************************************************//**
102366 + @Function XX_FreeIntr
102367 +
102368 + @Description Free a specific interrupt and a specific callback routine.
102369 +
102370 + @Param[in] irq - Interrupt ID (system-specific number).
102371 +
102372 + @Return E_OK on success; error code otherwise..
102373 +*//***************************************************************************/
102374 +t_Error XX_FreeIntr(int irq);
102375 +
102376 +/**************************************************************************//**
102377 + @Function XX_EnableIntr
102378 +
102379 + @Description Enable a specific interrupt.
102380 +
102381 + @Param[in] irq - Interrupt ID (system-specific number).
102382 +
102383 + @Return E_OK on success; error code otherwise..
102384 +*//***************************************************************************/
102385 +t_Error XX_EnableIntr(int irq);
102386 +
102387 +/**************************************************************************//**
102388 + @Function XX_DisableIntr
102389 +
102390 + @Description Disable a specific interrupt.
102391 +
102392 + @Param[in] irq - Interrupt ID (system-specific number).
102393 +
102394 + @Return E_OK on success; error code otherwise..
102395 +*//***************************************************************************/
102396 +t_Error XX_DisableIntr(int irq);
102397 +
102398 +/**************************************************************************//**
102399 + @Function XX_DisableAllIntr
102400 +
102401 + @Description Disable all interrupts by masking them at the CPU.
102402 +
102403 + @Return A value that represents the interrupts state before the
102404 + operation, and should be passed to the matching
102405 + XX_RestoreAllIntr() call.
102406 +*//***************************************************************************/
102407 +uint32_t XX_DisableAllIntr(void);
102408 +
102409 +/**************************************************************************//**
102410 + @Function XX_RestoreAllIntr
102411 +
102412 + @Description Restore previous state of interrupts level at the CPU.
102413 +
102414 + @Param[in] flags - A value that represents the interrupts state to restore,
102415 + as returned by the matching call for XX_DisableAllIntr().
102416 +
102417 + @Return None.
102418 +*//***************************************************************************/
102419 +void XX_RestoreAllIntr(uint32_t flags);
102420 +
102421 +
102422 +/**************************************************************************//**
102423 + @Function XX_Exit
102424 +
102425 + @Description Stop execution and report status (where it is applicable)
102426 +
102427 + @Param[in] status - exit status
102428 +*//***************************************************************************/
102429 +void XX_Exit(int status);
102430 +
102431 +
102432 +/*****************************************************************************/
102433 +/* Tasklet Service Routines */
102434 +/*****************************************************************************/
102435 +typedef t_Handle t_TaskletHandle;
102436 +
102437 +/**************************************************************************//**
102438 + @Function XX_InitTasklet
102439 +
102440 + @Description Create and initialize a tasklet object.
102441 +
102442 + @Param[in] routine - A routine to be ran as a tasklet.
102443 + @Param[in] data - An argument to pass to the tasklet.
102444 +
102445 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
102446 +*//***************************************************************************/
102447 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
102448 +
102449 +/**************************************************************************//**
102450 + @Function XX_FreeTasklet
102451 +
102452 + @Description Free a tasklet object.
102453 +
102454 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
102455 +
102456 + @Return None.
102457 +*//***************************************************************************/
102458 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
102459 +
102460 +/**************************************************************************//**
102461 + @Function XX_ScheduleTask
102462 +
102463 + @Description Schedule a tasklet object.
102464 +
102465 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102466 + @Param[in] immediate - Indicate whether to schedule this tasklet on
102467 + the immediate queue or on the delayed one.
102468 +
102469 + @Return 0 - on success. Error code - otherwise.
102470 +*//***************************************************************************/
102471 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
102472 +
102473 +/**************************************************************************//**
102474 + @Function XX_FlushScheduledTasks
102475 +
102476 + @Description Flush all tasks there are in the scheduled tasks queue.
102477 +
102478 + @Return None.
102479 +*//***************************************************************************/
102480 +void XX_FlushScheduledTasks(void);
102481 +
102482 +/**************************************************************************//**
102483 + @Function XX_TaskletIsQueued
102484 +
102485 + @Description Check if task is queued.
102486 +
102487 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102488 +
102489 + @Return 1 - task is queued. 0 - otherwise.
102490 +*//***************************************************************************/
102491 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
102492 +
102493 +/**************************************************************************//**
102494 + @Function XX_SetTaskletData
102495 +
102496 + @Description Set data to a scheduled task. Used to change data of already
102497 + scheduled task.
102498 +
102499 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102500 + @Param[in] data - Data to be set.
102501 +*//***************************************************************************/
102502 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
102503 +
102504 +/**************************************************************************//**
102505 + @Function XX_GetTaskletData
102506 +
102507 + @Description Get the data of scheduled task.
102508 +
102509 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
102510 +
102511 + @Return handle to the data of the task.
102512 +*//***************************************************************************/
102513 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
102514 +
102515 +/**************************************************************************//**
102516 + @Function XX_BottomHalf
102517 +
102518 + @Description Bottom half implementation, invoked by the interrupt handler.
102519 +
102520 + This routine handles all bottom-half tasklets with interrupts
102521 + enabled.
102522 +
102523 + @Return None.
102524 +*//***************************************************************************/
102525 +void XX_BottomHalf(void);
102526 +
102527 +
102528 +/*****************************************************************************/
102529 +/* Spinlock Service Routines */
102530 +/*****************************************************************************/
102531 +
102532 +/**************************************************************************//**
102533 + @Function XX_InitSpinlock
102534 +
102535 + @Description Creates a spinlock.
102536 +
102537 + @Return Spinlock handle is returned on success; NULL otherwise.
102538 +*//***************************************************************************/
102539 +t_Handle XX_InitSpinlock(void);
102540 +
102541 +/**************************************************************************//**
102542 + @Function XX_FreeSpinlock
102543 +
102544 + @Description Frees the memory allocated for the spinlock creation.
102545 +
102546 + @Param[in] h_Spinlock - A handle to a spinlock.
102547 +
102548 + @Return None.
102549 +*//***************************************************************************/
102550 +void XX_FreeSpinlock(t_Handle h_Spinlock);
102551 +
102552 +/**************************************************************************//**
102553 + @Function XX_LockSpinlock
102554 +
102555 + @Description Locks a spinlock.
102556 +
102557 + @Param[in] h_Spinlock - A handle to a spinlock.
102558 +
102559 + @Return None.
102560 +*//***************************************************************************/
102561 +void XX_LockSpinlock(t_Handle h_Spinlock);
102562 +
102563 +/**************************************************************************//**
102564 + @Function XX_UnlockSpinlock
102565 +
102566 + @Description Unlocks a spinlock.
102567 +
102568 + @Param[in] h_Spinlock - A handle to a spinlock.
102569 +
102570 + @Return None.
102571 +*//***************************************************************************/
102572 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
102573 +
102574 +/**************************************************************************//**
102575 + @Function XX_LockIntrSpinlock
102576 +
102577 + @Description Locks a spinlock (interrupt safe).
102578 +
102579 + @Param[in] h_Spinlock - A handle to a spinlock.
102580 +
102581 + @Return A value that represents the interrupts state before the
102582 + operation, and should be passed to the matching
102583 + XX_UnlockIntrSpinlock() call.
102584 +*//***************************************************************************/
102585 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
102586 +
102587 +/**************************************************************************//**
102588 + @Function XX_UnlockIntrSpinlock
102589 +
102590 + @Description Unlocks a spinlock (interrupt safe).
102591 +
102592 + @Param[in] h_Spinlock - A handle to a spinlock.
102593 + @Param[in] intrFlags - A value that represents the interrupts state to
102594 + restore, as returned by the matching call for
102595 + XX_LockIntrSpinlock().
102596 +
102597 + @Return None.
102598 +*//***************************************************************************/
102599 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
102600 +
102601 +
102602 +/*****************************************************************************/
102603 +/* Timers Service Routines */
102604 +/*****************************************************************************/
102605 +
102606 +/**************************************************************************//**
102607 + @Function XX_CurrentTime
102608 +
102609 + @Description Returns current system time.
102610 +
102611 + @Return Current system time (in milliseconds).
102612 +*//***************************************************************************/
102613 +uint32_t XX_CurrentTime(void);
102614 +
102615 +/**************************************************************************//**
102616 + @Function XX_CreateTimer
102617 +
102618 + @Description Creates a timer.
102619 +
102620 + @Return Timer handle is returned on success; NULL otherwise.
102621 +*//***************************************************************************/
102622 +t_Handle XX_CreateTimer(void);
102623 +
102624 +/**************************************************************************//**
102625 + @Function XX_FreeTimer
102626 +
102627 + @Description Frees the memory allocated for the timer creation.
102628 +
102629 + @Param[in] h_Timer - A handle to a timer.
102630 +
102631 + @Return None.
102632 +*//***************************************************************************/
102633 +void XX_FreeTimer(t_Handle h_Timer);
102634 +
102635 +/**************************************************************************//**
102636 + @Function XX_StartTimer
102637 +
102638 + @Description Starts a timer.
102639 +
102640 + The user can select to start the timer as periodic timer or as
102641 + one-shot timer. The user should provide a callback routine that
102642 + will be called when the timer expires.
102643 +
102644 + @Param[in] h_Timer - A handle to a timer.
102645 + @Param[in] msecs - Timer expiration period (in milliseconds).
102646 + @Param[in] periodic - TRUE for a periodic timer;
102647 + FALSE for a one-shot timer..
102648 + @Param[in] f_TimerExpired - A callback routine to be called when the
102649 + timer expires.
102650 + @Param[in] h_Arg - The argument to pass in the timer-expired
102651 + callback routine.
102652 +
102653 + @Return None.
102654 +*//***************************************************************************/
102655 +void XX_StartTimer(t_Handle h_Timer,
102656 + uint32_t msecs,
102657 + bool periodic,
102658 + void (*f_TimerExpired)(t_Handle h_Arg),
102659 + t_Handle h_Arg);
102660 +
102661 +/**************************************************************************//**
102662 + @Function XX_StopTimer
102663 +
102664 + @Description Frees the memory allocated for the timer creation.
102665 +
102666 + @Param[in] h_Timer - A handle to a timer.
102667 +
102668 + @Return None.
102669 +*//***************************************************************************/
102670 +void XX_StopTimer(t_Handle h_Timer);
102671 +
102672 +/**************************************************************************//**
102673 + @Function XX_ModTimer
102674 +
102675 + @Description Updates the expiration time of a timer.
102676 +
102677 + This routine adds the given time to the current system time,
102678 + and sets this value as the new expiration time of the timer.
102679 +
102680 + @Param[in] h_Timer - A handle to a timer.
102681 + @Param[in] msecs - The new interval until timer expiration
102682 + (in milliseconds).
102683 +
102684 + @Return None.
102685 +*//***************************************************************************/
102686 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
102687 +
102688 +/**************************************************************************//**
102689 + @Function XX_Sleep
102690 +
102691 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
102692 +
102693 + @Param[in] msecs - The requested sleep time (in milliseconds).
102694 +
102695 + @Return Zero if the requested time has elapsed; Otherwise, the value
102696 + returned will be the unslept amount) in milliseconds.
102697 +
102698 + @Cautions This routine enables interrupts during its wait time.
102699 +*//***************************************************************************/
102700 +uint32_t XX_Sleep(uint32_t msecs);
102701 +
102702 +/**************************************************************************//**
102703 + @Function XX_UDelay
102704 +
102705 + @Description Busy-wait until the desired time (in microseconds) has passed.
102706 +
102707 + @Param[in] usecs - The requested delay time (in microseconds).
102708 +
102709 + @Return None.
102710 +
102711 + @Cautions It is highly unrecommended to call this routine during interrupt
102712 + time, because the system time may not be updated properly during
102713 + the delay loop. The behavior of this routine during interrupt
102714 + time is unexpected.
102715 +*//***************************************************************************/
102716 +void XX_UDelay(uint32_t usecs);
102717 +
102718 +
102719 +/*****************************************************************************/
102720 +/* Other Service Routines */
102721 +/*****************************************************************************/
102722 +
102723 +/**************************************************************************//**
102724 + @Function XX_PhysToVirt
102725 +
102726 + @Description Translates a physical address to the matching virtual address.
102727 +
102728 + @Param[in] addr - The physical address to translate.
102729 +
102730 + @Return Virtual address.
102731 +*//***************************************************************************/
102732 +void * XX_PhysToVirt(physAddress_t addr);
102733 +
102734 +/**************************************************************************//**
102735 + @Function XX_VirtToPhys
102736 +
102737 + @Description Translates a virtual address to the matching physical address.
102738 +
102739 + @Param[in] addr - The virtual address to translate.
102740 +
102741 + @Return Physical address.
102742 +*//***************************************************************************/
102743 +physAddress_t XX_VirtToPhys(void *addr);
102744 +
102745 +
102746 +/**************************************************************************//**
102747 + @Group xx_ipc XX Inter-Partition-Communication API
102748 +
102749 + @Description The following API is to be used when working with multiple
102750 + partitions configuration.
102751 +
102752 + @{
102753 +*//***************************************************************************/
102754 +
102755 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
102756 + The IPC service can use this constant to limit
102757 + the storage space for IPC endpoint names. */
102758 +
102759 +
102760 +/**************************************************************************//**
102761 + @Function t_IpcMsgCompletion
102762 +
102763 + @Description Callback function used upon IPC non-blocking transaction completion
102764 + to return message buffer to the caller and to forward reply if available.
102765 +
102766 + This callback function may be attached by the source endpoint to any outgoing
102767 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
102768 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
102769 + the IPC service invokes this callback routine to return the message buffer to the sender
102770 + and to provide the received reply, if requested.
102771 +
102772 + User provides this function. Driver invokes it.
102773 +
102774 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
102775 + in the XX_IpcSendMessage() function; This handle is typically used to point
102776 + to the internal data structure of the source endpoint.
102777 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
102778 + The source endpoint can free (or reuse) this buffer when message
102779 + completion callback is called.
102780 + @Param[in] p_Reply - Pointer to (received) reply buffer;
102781 + This pointer is the same as was provided by the source endpoint in
102782 + XX_IpcSendMessage().
102783 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
102784 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
102785 + timeout.
102786 +
102787 + @Return None
102788 + *//***************************************************************************/
102789 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
102790 + uint8_t *p_Msg,
102791 + uint8_t *p_Reply,
102792 + uint32_t replyLength,
102793 + t_Error status);
102794 +
102795 +/**************************************************************************//**
102796 + @Function t_IpcMsgHandler
102797 +
102798 + @Description Callback function used as IPC message handler.
102799 +
102800 + The IPC service invokes message handlers for each IPC message received.
102801 + The actual function pointer should be registered by each destination endpoint
102802 + via the XX_IpcRegisterMsgHandler() routine.
102803 +
102804 + User provides this function. Driver invokes it.
102805 +
102806 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
102807 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
102808 + typically used to point to the internal data structure of the destination
102809 + endpoint.
102810 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
102811 + @Param[in] msgLength - Length (in bytes) of message data.
102812 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
102813 + by the IPC service;
102814 + The reply buffer is allocated by the IPC service with size equals to the
102815 + replyLength parameter provided in message handler registration (see
102816 + XX_IpcRegisterMsgHandler() function);
102817 + If replyLength was initially specified as zero during message handler registration,
102818 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
102819 + The IPC service is also responsible for freeing the reply buffer after the
102820 + reply has been sent or dismissed.
102821 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102822 + [In] equals the replyLength parameter provided in message handler
102823 + registration (see XX_IpcRegisterMsgHandler() function), and
102824 + [Out] should be updated by message handler to the actual reply length; if
102825 + this value is set to zero, the IPC service must assume that a reply should
102826 + not be sent;
102827 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
102828 +
102829 + @Return E_OK on success; Error code otherwise.
102830 + *//***************************************************************************/
102831 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
102832 + uint8_t *p_Msg,
102833 + uint32_t msgLength,
102834 + uint8_t *p_Reply,
102835 + uint32_t *p_ReplyLength);
102836 +
102837 +/**************************************************************************//**
102838 + @Function XX_IpcRegisterMsgHandler
102839 +
102840 + @Description IPC mailbox registration.
102841 +
102842 + This function is used for registering an IPC message handler in the IPC service.
102843 + This function is called by each destination endpoint to indicate that it is ready
102844 + to handle incoming messages. The IPC service invokes the message handler upon receiving
102845 + a message addressed to the specified destination endpoint.
102846 +
102847 + @Param[in] addr - The address name string associated with the destination endpoint;
102848 + This address must be unique across the IPC service domain to ensure
102849 + correct message routing.
102850 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
102851 + message; invoked by the IPC service upon receiving a message
102852 + addressed to the destination endpoint specified by the addr
102853 + parameter.
102854 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
102855 + to f_MsgHandler callback function.
102856 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
102857 + may generate; the IPC service provides the message handler with buffer
102858 + for reply according to the length specified here (refer also to the description
102859 + of #t_IpcMsgHandler callback function type);
102860 + This size shall be zero if the message handler never generates replies.
102861 +
102862 + @Return E_OK on success; Error code otherwise.
102863 +*//***************************************************************************/
102864 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102865 + t_IpcMsgHandler *f_MsgHandler,
102866 + t_Handle h_Module,
102867 + uint32_t replyLength);
102868 +
102869 +/**************************************************************************//**
102870 + @Function XX_IpcUnregisterMsgHandler
102871 +
102872 + @Description Release IPC mailbox routine.
102873 +
102874 + This function is used for unregistering an IPC message handler from the IPC service.
102875 + This function is called by each destination endpoint to indicate that it is no longer
102876 + capable of handling incoming messages.
102877 +
102878 + @Param[in] addr - The address name string associated with the destination endpoint;
102879 + This address is the same as was used when the message handler was
102880 + registered via XX_IpcRegisterMsgHandler().
102881 +
102882 + @Return E_OK on success; Error code otherwise.
102883 +*//***************************************************************************/
102884 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102885 +
102886 +/**************************************************************************//**
102887 + @Function XX_IpcInitSession
102888 +
102889 + @Description This function is used for creating an IPC session between the source endpoint
102890 + and the destination endpoint.
102891 +
102892 + The actual implementation and representation of a session is left for the IPC service.
102893 + The function returns an abstract handle to the created session. This handle shall be used
102894 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
102895 + The IPC service assumes that before this function is called, no messages are sent from
102896 + the specified source endpoint to the specified destination endpoint.
102897 +
102898 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
102899 + as described below.
102900 +
102901 + @par Connection-Oriented Approach
102902 +
102903 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
102904 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
102905 + and a destination-to-source channel for replies. The returned handle should represent the internal
102906 + representation of these channels.
102907 +
102908 + @par Connectionless Approach
102909 +
102910 + The IPC service may implement a session in a connectionless approach - when this function is called, the
102911 + IPC service should not perform any particular steps, but it must store the pair of source and destination
102912 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
102913 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
102914 + through the connectionless medium.
102915 +
102916 + @Param[in] destAddr - The address name string associated with the destination endpoint.
102917 + @Param[in] srcAddr - The address name string associated with the source endpoint.
102918 +
102919 + @Return Abstract handle to the initialized session, or NULL on error.
102920 +*//***************************************************************************/
102921 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
102922 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
102923 +
102924 +/**************************************************************************//**
102925 + @Function XX_IpcFreeSession
102926 +
102927 + @Description This function is used for terminating an existing IPC session between a source endpoint
102928 + and a destination endpoint.
102929 +
102930 + The IPC service assumes that after this function is called, no messages shall be sent from
102931 + the associated source endpoint to the associated destination endpoint.
102932 +
102933 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102934 + returned by the XX_IpcInitSession() function.
102935 +
102936 + @Return E_OK on success; Error code otherwise.
102937 +*//***************************************************************************/
102938 +t_Error XX_IpcFreeSession(t_Handle h_Session);
102939 +
102940 +/**************************************************************************//**
102941 + @Function XX_IpcSendMessage
102942 +
102943 + @Description IPC message send routine.
102944 +
102945 + This function may be used by a source endpoint to send an IPC message to a destination
102946 + endpoint. The source endpoint cannot send a message to the destination endpoint without
102947 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
102948 +
102949 + The source endpoint must provide the buffer pointer and length of the outgoing message.
102950 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
102951 + transaction is not considered complete by the IPC service until the reply has been received.
102952 + If the source endpoint does not provide a reply buffer, the transaction is considered
102953 + complete after the message has been sent. The source endpoint must keep the message (and
102954 + optional reply) buffers valid until the transaction is complete.
102955 +
102956 + @par Non-blocking mode
102957 +
102958 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
102959 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
102960 + message and an optional reply), the IPC service invokes this callback routine to return the message
102961 + buffer to the sender and to provide the received reply, if requested.
102962 +
102963 + @par Blocking mode
102964 +
102965 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
102966 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
102967 + was requested) the message has been sent.
102968 +
102969 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
102970 + returned by the XX_IpcInitSession() function.
102971 + @Param[in] p_Msg - Pointer to message buffer to send.
102972 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
102973 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
102974 + fills this buffer with the received reply data;
102975 + In blocking mode, the reply data must be valid when the function returns;
102976 + In non-blocking mode, the reply data is valid when f_Completion is called;
102977 + If this pointer is NULL, no reply is expected.
102978 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
102979 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
102980 + p_Reply, and
102981 + [Out] in non-blocking mode this value is updated by the IPC service to the
102982 + actual reply length (in bytes).
102983 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
102984 + The completion callback is invoked by the IPC service upon
102985 + completion of the IPC transaction (consisting of a message and an optional
102986 + reply);
102987 + If this pointer is NULL, the function is expected to block until the IPC
102988 + transaction is complete.
102989 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
102990 + callback function as the first argument.
102991 +
102992 + @Return E_OK on success; Error code otherwise.
102993 +*//***************************************************************************/
102994 +t_Error XX_IpcSendMessage(t_Handle h_Session,
102995 + uint8_t *p_Msg,
102996 + uint32_t msgLength,
102997 + uint8_t *p_Reply,
102998 + uint32_t *p_ReplyLength,
102999 + t_IpcMsgCompletion *f_Completion,
103000 + t_Handle h_Arg);
103001 +
103002 +
103003 +/** @} */ /* end of xx_ipc group */
103004 +/** @} */ /* end of xx_id group */
103005 +
103006 +
103007 +#endif /* __XX_EXT_H */
103008 --- /dev/null
103009 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
103010 @@ -0,0 +1,56 @@
103011 +/*
103012 + * Copyright 2012 Freescale Semiconductor Inc.
103013 + *
103014 + * Redistribution and use in source and binary forms, with or without
103015 + * modification, are permitted provided that the following conditions are met:
103016 + * * Redistributions of source code must retain the above copyright
103017 + * notice, this list of conditions and the following disclaimer.
103018 + * * Redistributions in binary form must reproduce the above copyright
103019 + * notice, this list of conditions and the following disclaimer in the
103020 + * documentation and/or other materials provided with the distribution.
103021 + * * Neither the name of Freescale Semiconductor nor the
103022 + * names of its contributors may be used to endorse or promote products
103023 + * derived from this software without specific prior written permission.
103024 + *
103025 + *
103026 + * ALTERNATIVELY, this software may be distributed under the terms of the
103027 + * GNU General Public License ("GPL") as published by the Free Software
103028 + * Foundation, either version 2 of that License or (at your option) any
103029 + * later version.
103030 + *
103031 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103032 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103033 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103034 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103035 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103036 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103037 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103038 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103039 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103040 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103041 + */
103042 +
103043 +#ifndef __dflags_h
103044 +#define __dflags_h
103045 +
103046 +
103047 +#define NCSW_LINUX
103048 +
103049 +#define LS1043
103050 +
103051 +#define DEBUG_ERRORS 1
103052 +
103053 +#if defined(DEBUG)
103054 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103055 +
103056 +#define DEBUG_XX_MALLOC
103057 +#define DEBUG_MEM_LEAKS
103058 +
103059 +#else
103060 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103061 +#endif /* (DEBUG) */
103062 +
103063 +#define REPORT_EVENTS 1
103064 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103065 +
103066 +#endif /* __dflags_h */
103067 --- /dev/null
103068 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103069 @@ -0,0 +1,53 @@
103070 +#
103071 +# Makefile config for the Freescale NetcommSW
103072 +#
103073 +NET_DPA = $(srctree)/drivers/net
103074 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
103075 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
103076 +
103077 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103078 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
103079 +endif
103080 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103081 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
103082 +endif
103083 +ifdef CONFIG_FMAN_V3H
103084 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
103085 +endif
103086 +ifdef CONFIG_FMAN_V3L
103087 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
103088 +endif
103089 +ifdef CONFIG_FMAN_ARM
103090 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
103091 +endif
103092 +
103093 +ccflags-y += -I$(DRV_DPA)/
103094 +ccflags-y += -I$(FMAN)/inc
103095 +ccflags-y += -I$(FMAN)/inc/cores
103096 +ccflags-y += -I$(FMAN)/inc/etc
103097 +ccflags-y += -I$(FMAN)/inc/Peripherals
103098 +ccflags-y += -I$(FMAN)/inc/flib
103099 +
103100 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
103101 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
103102 +endif
103103 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
103104 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
103105 +endif
103106 +ifdef CONFIG_FMAN_V3H
103107 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
103108 +endif
103109 +ifdef CONFIG_FMAN_V3L
103110 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
103111 +endif
103112 +ifdef CONFIG_FMAN_ARM
103113 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
103114 +endif
103115 +
103116 +ccflags-y += -I$(FMAN)/src/inc
103117 +ccflags-y += -I$(FMAN)/src/inc/system
103118 +ccflags-y += -I$(FMAN)/src/inc/wrapper
103119 +ccflags-y += -I$(FMAN)/src/inc/xx
103120 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
103121 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
103122 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
103123 --- /dev/null
103124 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
103125 @@ -0,0 +1,65 @@
103126 +/*
103127 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103128 + *
103129 + * Redistribution and use in source and binary forms, with or without
103130 + * modification, are permitted provided that the following conditions are met:
103131 + * * Redistributions of source code must retain the above copyright
103132 + * notice, this list of conditions and the following disclaimer.
103133 + * * Redistributions in binary form must reproduce the above copyright
103134 + * notice, this list of conditions and the following disclaimer in the
103135 + * documentation and/or other materials provided with the distribution.
103136 + * * Neither the name of Freescale Semiconductor nor the
103137 + * names of its contributors may be used to endorse or promote products
103138 + * derived from this software without specific prior written permission.
103139 + *
103140 + *
103141 + * ALTERNATIVELY, this software may be distributed under the terms of the
103142 + * GNU General Public License ("GPL") as published by the Free Software
103143 + * Foundation, either version 2 of that License or (at your option) any
103144 + * later version.
103145 + *
103146 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103147 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103148 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103149 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103150 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103151 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103152 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103153 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103154 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103155 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103156 + */
103157 +
103158 +#ifndef __dflags_h
103159 +#define __dflags_h
103160 +
103161 +
103162 +#define NCSW_LINUX
103163 +#if 0
103164 +#define DEBUG
103165 +#endif
103166 +
103167 +#define P1023
103168 +#define NCSW_PPC_CORE
103169 +
103170 +#define DEBUG_ERRORS 1
103171 +
103172 +#if defined(DEBUG)
103173 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103174 +
103175 +#define DEBUG_XX_MALLOC
103176 +#define DEBUG_MEM_LEAKS
103177 +
103178 +#else
103179 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103180 +#endif /* (DEBUG) */
103181 +
103182 +#define REPORT_EVENTS 1
103183 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103184 +
103185 +#ifdef CONFIG_P4080_SIM
103186 +#error "Do not define CONFIG_P4080_SIM..."
103187 +#endif
103188 +
103189 +
103190 +#endif /* __dflags_h */
103191 --- /dev/null
103192 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
103193 @@ -0,0 +1,62 @@
103194 +/*
103195 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103196 + *
103197 + * Redistribution and use in source and binary forms, with or without
103198 + * modification, are permitted provided that the following conditions are met:
103199 + * * Redistributions of source code must retain the above copyright
103200 + * notice, this list of conditions and the following disclaimer.
103201 + * * Redistributions in binary form must reproduce the above copyright
103202 + * notice, this list of conditions and the following disclaimer in the
103203 + * documentation and/or other materials provided with the distribution.
103204 + * * Neither the name of Freescale Semiconductor nor the
103205 + * names of its contributors may be used to endorse or promote products
103206 + * derived from this software without specific prior written permission.
103207 + *
103208 + *
103209 + * ALTERNATIVELY, this software may be distributed under the terms of the
103210 + * GNU General Public License ("GPL") as published by the Free Software
103211 + * Foundation, either version 2 of that License or (at your option) any
103212 + * later version.
103213 + *
103214 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103215 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103216 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103217 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103218 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103219 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103220 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103221 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103222 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103223 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103224 + */
103225 +
103226 +#ifndef __dflags_h
103227 +#define __dflags_h
103228 +
103229 +
103230 +#define NCSW_LINUX
103231 +
103232 +#define P4080
103233 +#define NCSW_PPC_CORE
103234 +
103235 +#define DEBUG_ERRORS 1
103236 +
103237 +#if defined(DEBUG)
103238 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
103239 +
103240 +#define DEBUG_XX_MALLOC
103241 +#define DEBUG_MEM_LEAKS
103242 +
103243 +#else
103244 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
103245 +#endif /* (DEBUG) */
103246 +
103247 +#define REPORT_EVENTS 1
103248 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
103249 +
103250 +#ifdef CONFIG_P4080_SIM
103251 +#define SIMULATOR
103252 +#endif /* CONFIG_P4080_SIM */
103253 +
103254 +
103255 +#endif /* __dflags_h */
103256 --- /dev/null
103257 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
103258 @@ -0,0 +1,11 @@
103259 +#
103260 +# Makefile for the Freescale Ethernet controllers
103261 +#
103262 +ccflags-y += -DVERSION=\"\"
103263 +#
103264 +#Include netcomm SW specific definitions
103265 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
103266 +#
103267 +obj-y += system/
103268 +obj-y += wrapper/
103269 +obj-y += xx/
103270 --- /dev/null
103271 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
103272 @@ -0,0 +1,118 @@
103273 +/*
103274 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103275 + *
103276 + * Redistribution and use in source and binary forms, with or without
103277 + * modification, are permitted provided that the following conditions are met:
103278 + * * Redistributions of source code must retain the above copyright
103279 + * notice, this list of conditions and the following disclaimer.
103280 + * * Redistributions in binary form must reproduce the above copyright
103281 + * notice, this list of conditions and the following disclaimer in the
103282 + * documentation and/or other materials provided with the distribution.
103283 + * * Neither the name of Freescale Semiconductor nor the
103284 + * names of its contributors may be used to endorse or promote products
103285 + * derived from this software without specific prior written permission.
103286 + *
103287 + *
103288 + * ALTERNATIVELY, this software may be distributed under the terms of the
103289 + * GNU General Public License ("GPL") as published by the Free Software
103290 + * Foundation, either version 2 of that License or (at your option) any
103291 + * later version.
103292 + *
103293 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103294 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103295 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103296 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103297 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103298 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103299 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103300 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103301 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103302 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103303 + */
103304 +
103305 +#ifndef __SYS_EXT_H
103306 +#define __SYS_EXT_H
103307 +
103308 +#include "std_ext.h"
103309 +
103310 +
103311 +/**************************************************************************//**
103312 + @Group sys_grp System Interfaces
103313 +
103314 + @Description Linux system programming interfaces.
103315 +
103316 + @{
103317 +*//***************************************************************************/
103318 +
103319 +/**************************************************************************//**
103320 + @Group sys_gen_grp System General Interface
103321 +
103322 + @Description General definitions, structures and routines of the linux
103323 + system programming interface.
103324 +
103325 + @{
103326 +*//***************************************************************************/
103327 +
103328 +/**************************************************************************//**
103329 + @Collection Macros for Advanced Configuration Requests
103330 + @{
103331 +*//***************************************************************************/
103332 +#define SYS_MAX_ADV_CONFIG_ARGS 4
103333 + /**< Maximum number of arguments in
103334 + an advanced configuration entry */
103335 +/* @} */
103336 +
103337 +/**************************************************************************//**
103338 + @Description System Object Advanced Configuration Entry
103339 +
103340 + This structure represents a single request for an advanced
103341 + configuration call on the initialized object. An array of such
103342 + requests may be contained in the settings structure of the
103343 + corresponding object.
103344 +
103345 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
103346 +*//***************************************************************************/
103347 +typedef struct t_SysObjectAdvConfigEntry
103348 +{
103349 + void *p_Function; /**< Pointer to advanced configuration routine */
103350 +
103351 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
103352 + /**< Array of arguments for the specified routine;
103353 + All arguments should be casted to uint32_t. */
103354 +} t_SysObjectAdvConfigEntry;
103355 +
103356 +
103357 +/** @} */ /* end of sys_gen_grp */
103358 +/** @} */ /* end of sys_grp */
103359 +
103360 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
103361 +
103362 +#define ADV_CONFIG_PARAMS_1(_type) \
103363 + , (_type)p_Entry->args[0]
103364 +
103365 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
103366 + p_Entry->args[0] = (uintptr_t )(_arg0); \
103367 +
103368 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
103369 +
103370 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
103371 + { \
103372 + t_SysObjectAdvConfigEntry *p_Entry; \
103373 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
103374 + int i=0, max = (_maxEntries); \
103375 +
103376 +#define ADD_ADV_CONFIG_END \
103377 + }
103378 +
103379 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
103380 + { \
103381 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
103382 + t_Error errCode; \
103383 +
103384 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
103385 + if (p_Entry->p_Function == _func) \
103386 + { \
103387 + errCode = _func(_handle _params); \
103388 + } else
103389 +
103390 +#endif /* __SYS_EXT_H */
103391 --- /dev/null
103392 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
103393 @@ -0,0 +1,46 @@
103394 +/*
103395 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103396 + *
103397 + * Redistribution and use in source and binary forms, with or without
103398 + * modification, are permitted provided that the following conditions are met:
103399 + * * Redistributions of source code must retain the above copyright
103400 + * notice, this list of conditions and the following disclaimer.
103401 + * * Redistributions in binary form must reproduce the above copyright
103402 + * notice, this list of conditions and the following disclaimer in the
103403 + * documentation and/or other materials provided with the distribution.
103404 + * * Neither the name of Freescale Semiconductor nor the
103405 + * names of its contributors may be used to endorse or promote products
103406 + * derived from this software without specific prior written permission.
103407 + *
103408 + *
103409 + * ALTERNATIVELY, this software may be distributed under the terms of the
103410 + * GNU General Public License ("GPL") as published by the Free Software
103411 + * Foundation, either version 2 of that License or (at your option) any
103412 + * later version.
103413 + *
103414 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103415 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103416 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103417 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103418 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103419 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103420 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103421 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103422 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103423 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103424 + */
103425 +
103426 +#ifndef __SYS_IO_EXT_H
103427 +#define __SYS_IO_EXT_H
103428 +
103429 +#include "std_ext.h"
103430 +#include "error_ext.h"
103431 +
103432 +
103433 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
103434 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
103435 +uint64_t SYS_PhysToVirt (uint64_t addr);
103436 +uint64_t SYS_VirtToPhys (uint64_t addr);
103437 +
103438 +
103439 +#endif /* __SYS_IO_EXT_H */
103440 --- /dev/null
103441 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
103442 @@ -0,0 +1,208 @@
103443 +/*
103444 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103445 + *
103446 + * Redistribution and use in source and binary forms, with or without
103447 + * modification, are permitted provided that the following conditions are met:
103448 + * * Redistributions of source code must retain the above copyright
103449 + * notice, this list of conditions and the following disclaimer.
103450 + * * Redistributions in binary form must reproduce the above copyright
103451 + * notice, this list of conditions and the following disclaimer in the
103452 + * documentation and/or other materials provided with the distribution.
103453 + * * Neither the name of Freescale Semiconductor nor the
103454 + * names of its contributors may be used to endorse or promote products
103455 + * derived from this software without specific prior written permission.
103456 + *
103457 + *
103458 + * ALTERNATIVELY, this software may be distributed under the terms of the
103459 + * GNU General Public License ("GPL") as published by the Free Software
103460 + * Foundation, either version 2 of that License or (at your option) any
103461 + * later version.
103462 + *
103463 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103464 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103466 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103467 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103468 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103469 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103470 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103471 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103472 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103473 + */
103474 +
103475 +#ifndef __TYPES_LINUX_H__
103476 +#define __TYPES_LINUX_H__
103477 +
103478 +#include <linux/version.h>
103479 +
103480 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
103481 +#define MODVERSIONS
103482 +#endif
103483 +#ifdef MODVERSIONS
103484 +#include <config/modversions.h>
103485 +#endif /* MODVERSIONS */
103486 +
103487 +#include <linux/kernel.h>
103488 +#include <linux/types.h>
103489 +#include <asm/io.h>
103490 +#include <linux/delay.h>
103491 +
103492 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
103493 + #error "This kernel is probably not supported!!!"
103494 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
103495 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
103496 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
103497 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
103498 +#endif /* LINUX_VERSION_CODE */
103499 +
103500 +
103501 +typedef float float_t; /* Single precision floating point */
103502 +typedef double double_t; /* Double precision floating point */
103503 +
103504 +
103505 +#define _Packed
103506 +#define _PackedType __attribute__ ((packed))
103507 +
103508 +typedef phys_addr_t physAddress_t;
103509 +
103510 +#define UINT8_MAX 0xFF
103511 +#define UINT8_MIN 0
103512 +#define UINT16_MAX 0xFFFF
103513 +#define UINT16_MIN 0
103514 +#define UINT32_MAX 0xFFFFFFFF
103515 +#define UINT32_MIN 0
103516 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
103517 +#define UINT64_MIN 0
103518 +#define INT8_MAX 0x7F
103519 +#define INT8_MIN 0x80
103520 +#define INT16_MAX 0x7FFF
103521 +#define INT16_MIN 0x8000
103522 +#define INT32_MAX 0x7FFFFFFF
103523 +#define INT32_MIN 0x80000000
103524 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
103525 +#define INT64_MIN 0x8000000000000000LL
103526 +
103527 +#define ON 1
103528 +#define OFF 0
103529 +
103530 +#define FALSE false
103531 +#define TRUE true
103532 +
103533 +
103534 +/************************/
103535 +/* memory access macros */
103536 +/************************/
103537 +#ifdef CONFIG_FMAN_ARM
103538 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
103539 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
103540 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
103541 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
103542 +#endif
103543 +
103544 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
103545 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
103546 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
103547 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
103548 +
103549 +#ifdef VERBOSE_WRITE
103550 +void XX_Print(char *str, ...);
103551 +#define WRITE_UINT8(arg, data) \
103552 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
103553 +#define WRITE_UINT16(arg, data) \
103554 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%04x\r\n", (uint32_t)&(arg), (data)); out_be16(&(arg), data); /* *(volatile uint16_t*)(&(arg)) = (data);*/ } while (0)
103555 +#define WRITE_UINT32(arg, data) \
103556 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%08x\r\n", (uint32_t)&(arg), (data)); out_be32(&(arg), data); /* *(volatile uint32_t*)(&(arg)) = (data);*/ } while (0)
103557 +#define WRITE_UINT64(arg, data) \
103558 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
103559 +
103560 +#else /* not VERBOSE_WRITE */
103561 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
103562 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
103563 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
103564 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
103565 +#endif /* not VERBOSE_WRITE */
103566 +
103567 +
103568 +/*****************************************************************************/
103569 +/* General stuff */
103570 +/*****************************************************************************/
103571 +#ifdef ARRAY_SIZE
103572 +#undef ARRAY_SIZE
103573 +#endif /* ARRAY_SIZE */
103574 +
103575 +#ifdef MAJOR
103576 +#undef MAJOR
103577 +#endif /* MAJOR */
103578 +
103579 +#ifdef MINOR
103580 +#undef MINOR
103581 +#endif /* MINOR */
103582 +
103583 +#ifdef QE_SIZEOF_BD
103584 +#undef QE_SIZEOF_BD
103585 +#endif /* QE_SIZEOF_BD */
103586 +
103587 +#ifdef BD_BUFFER_CLEAR
103588 +#undef BD_BUFFER_CLEAR
103589 +#endif /* BD_BUFFER_CLEAR */
103590 +
103591 +#ifdef BD_BUFFER
103592 +#undef BD_BUFFER
103593 +#endif /* BD_BUFFER */
103594 +
103595 +#ifdef BD_STATUS_AND_LENGTH_SET
103596 +#undef BD_STATUS_AND_LENGTH_SET
103597 +#endif /* BD_STATUS_AND_LENGTH_SET */
103598 +
103599 +#ifdef BD_STATUS_AND_LENGTH
103600 +#undef BD_STATUS_AND_LENGTH
103601 +#endif /* BD_STATUS_AND_LENGTH */
103602 +
103603 +#ifdef BD_BUFFER_ARG
103604 +#undef BD_BUFFER_ARG
103605 +#endif /* BD_BUFFER_ARG */
103606 +
103607 +#ifdef BD_GET_NEXT
103608 +#undef BD_GET_NEXT
103609 +#endif /* BD_GET_NEXT */
103610 +
103611 +#ifdef QE_SDEBCR_BA_MASK
103612 +#undef QE_SDEBCR_BA_MASK
103613 +#endif /* QE_SDEBCR_BA_MASK */
103614 +
103615 +#ifdef BD_BUFFER_SET
103616 +#undef BD_BUFFER_SET
103617 +#endif /* BD_BUFFER_SET */
103618 +
103619 +#ifdef UPGCR_PROTOCOL
103620 +#undef UPGCR_PROTOCOL
103621 +#endif /* UPGCR_PROTOCOL */
103622 +
103623 +#ifdef UPGCR_TMS
103624 +#undef UPGCR_TMS
103625 +#endif /* UPGCR_TMS */
103626 +
103627 +#ifdef UPGCR_RMS
103628 +#undef UPGCR_RMS
103629 +#endif /* UPGCR_RMS */
103630 +
103631 +#ifdef UPGCR_ADDR
103632 +#undef UPGCR_ADDR
103633 +#endif /* UPGCR_ADDR */
103634 +
103635 +#ifdef UPGCR_DIAG
103636 +#undef UPGCR_DIAG
103637 +#endif /* UPGCR_DIAG */
103638 +
103639 +#ifdef NCSW_PARAMS
103640 +#undef NCSW_PARAMS
103641 +#endif /* NCSW_PARAMS */
103642 +
103643 +#ifdef NO_IRQ
103644 +#undef NO_IRQ
103645 +#endif /* NO_IRQ */
103646 +
103647 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
103648 +
103649 +
103650 +#endif /* __TYPES_LINUX_H__ */
103651 --- /dev/null
103652 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
103653 @@ -0,0 +1,84 @@
103654 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
103655 + * All rights reserved.
103656 + *
103657 + * Redistribution and use in source and binary forms, with or without
103658 + * modification, are permitted provided that the following conditions are met:
103659 + * * Redistributions of source code must retain the above copyright
103660 + * notice, this list of conditions and the following disclaimer.
103661 + * * Redistributions in binary form must reproduce the above copyright
103662 + * notice, this list of conditions and the following disclaimer in the
103663 + * documentation and/or other materials provided with the distribution.
103664 + * * Neither the name of Freescale Semiconductor nor the
103665 + * names of its contributors may be used to endorse or promote products
103666 + * derived from this software without specific prior written permission.
103667 + *
103668 + *
103669 + * ALTERNATIVELY, this software may be distributed under the terms of the
103670 + * GNU General Public License ("GPL") as published by the Free Software
103671 + * Foundation, either version 2 of that License or (at your option) any
103672 + * later version.
103673 + *
103674 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103675 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103676 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103677 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103678 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103679 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103680 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103681 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103682 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103683 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103684 + */
103685 +
103686 +/******************************************************************************
103687 + @File fsl_fman_test.h
103688 +
103689 + @Description
103690 +*//***************************************************************************/
103691 +
103692 +#ifndef __FSL_FMAN_TEST_H
103693 +#define __FSL_FMAN_TEST_H
103694 +
103695 +#include <linux/types.h>
103696 +#include <linux/smp.h> /* raw_smp_processor_id() */
103697 +
103698 +//#define FMT_K_DBG
103699 +//#define FMT_K_DBG_RUNTIME
103700 +
103701 +#define _fmt_prk(stage, format, arg...) \
103702 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
103703 +
103704 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
103705 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
103706 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
103707 +
103708 +/* there are two macros for debugging: for runtime and generic.
103709 + * Helps when the runtime functions are not targeted for debugging,
103710 + * thus all the unnecessary information will be skipped.
103711 + */
103712 +/* used for generic debugging */
103713 +#if defined(FMT_K_DBG)
103714 + #define _fmt_dbg(format, arg...) \
103715 + printk("fmt [%s:%u](cpu:%u) - " format, \
103716 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103717 +#else
103718 +# define _fmt_dbg(arg...)
103719 +#endif
103720 +
103721 +/* used for debugging runtime functions */
103722 +#if defined(FMT_K_DBG_RUNTIME)
103723 + #define _fmt_dbgr(format, arg...) \
103724 + printk("fmt [%s:%u](cpu:%u) - " format, \
103725 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
103726 +#else
103727 +# define _fmt_dbgr(arg...)
103728 +#endif
103729 +
103730 +#define FMT_RX_ERR_Q 0xffffffff
103731 +#define FMT_RX_DFLT_Q 0xfffffffe
103732 +#define FMT_TX_ERR_Q 0xfffffffd
103733 +#define FMT_TX_CONF_Q 0xfffffffc
103734 +
103735 +#define FMAN_TEST_MAX_TX_FQS 8
103736 +
103737 +#endif /* __FSL_FMAN_TEST_H */
103738 --- /dev/null
103739 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
103740 @@ -0,0 +1,130 @@
103741 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
103742 + * All rights reserved.
103743 + *
103744 + * Redistribution and use in source and binary forms, with or without
103745 + * modification, are permitted provided that the following conditions are met:
103746 + * * Redistributions of source code must retain the above copyright
103747 + * notice, this list of conditions and the following disclaimer.
103748 + * * Redistributions in binary form must reproduce the above copyright
103749 + * notice, this list of conditions and the following disclaimer in the
103750 + * documentation and/or other materials provided with the distribution.
103751 + * * Neither the name of Freescale Semiconductor nor the
103752 + * names of its contributors may be used to endorse or promote products
103753 + * derived from this software without specific prior written permission.
103754 + *
103755 + *
103756 + * ALTERNATIVELY, this software may be distributed under the terms of the
103757 + * GNU General Public License ("GPL") as published by the Free Software
103758 + * Foundation, either version 2 of that License or (at your option) any
103759 + * later version.
103760 + *
103761 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103762 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103763 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103764 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103765 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103766 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103767 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103768 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103769 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103770 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103771 + */
103772 +
103773 +/*
103774 + @File lnxwrp_exp_sym.h
103775 + @Description FMan exported routines
103776 +*/
103777 +
103778 +#ifndef __LNXWRP_EXP_SYM_H
103779 +#define __LNXWRP_EXP_SYM_H
103780 +
103781 +#include "fm_port_ext.h"
103782 +#include "fm_pcd_ext.h"
103783 +#include "fm_mac_ext.h"
103784 +
103785 +
103786 +/* FMAN Port exported routines */
103787 +EXPORT_SYMBOL(FM_PORT_Disable);
103788 +EXPORT_SYMBOL(FM_PORT_Enable);
103789 +EXPORT_SYMBOL(FM_PORT_SetPCD);
103790 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
103791 +
103792 +/* Runtime PCD exported routines */
103793 +EXPORT_SYMBOL(FM_PCD_Enable);
103794 +EXPORT_SYMBOL(FM_PCD_Disable);
103795 +EXPORT_SYMBOL(FM_PCD_GetCounter);
103796 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
103797 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
103798 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
103799 +EXPORT_SYMBOL(FM_PCD_SetException);
103800 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
103801 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
103802 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
103803 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
103804 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
103805 +
103806 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
103807 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
103808 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
103809 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
103810 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
103811 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
103812 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
103813 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
103814 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
103815 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
103816 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
103817 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
103818 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
103819 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
103820 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
103821 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
103822 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
103823 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
103824 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
103825 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
103826 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
103827 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
103828 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
103829 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
103830 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
103831 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
103832 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
103833 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
103834 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
103835 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
103836 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
103837 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
103838 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
103839 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
103840 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
103841 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
103842 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
103843 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
103844 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
103845 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
103846 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
103847 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
103848 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
103849 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
103850 +#if (DPAA_VERSION >= 11)
103851 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
103852 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
103853 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
103854 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
103855 +#endif /* DPAA_VERSION >= 11 */
103856 +
103857 +#ifdef FM_CAPWAP_SUPPORT
103858 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
103859 +#endif /* FM_CAPWAP_SUPPORT */
103860 +
103861 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
103862 +
103863 +/* FMAN MAC exported routines */
103864 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
103865 +
103866 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
103867 +
103868 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
103869 +
103870 +#endif /* __LNXWRP_EXP_SYM_H */
103871 --- /dev/null
103872 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
103873 @@ -0,0 +1,163 @@
103874 +/*
103875 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103876 + *
103877 + * Redistribution and use in source and binary forms, with or without
103878 + * modification, are permitted provided that the following conditions are met:
103879 + * * Redistributions of source code must retain the above copyright
103880 + * notice, this list of conditions and the following disclaimer.
103881 + * * Redistributions in binary form must reproduce the above copyright
103882 + * notice, this list of conditions and the following disclaimer in the
103883 + * documentation and/or other materials provided with the distribution.
103884 + * * Neither the name of Freescale Semiconductor nor the
103885 + * names of its contributors may be used to endorse or promote products
103886 + * derived from this software without specific prior written permission.
103887 + *
103888 + *
103889 + * ALTERNATIVELY, this software may be distributed under the terms of the
103890 + * GNU General Public License ("GPL") as published by the Free Software
103891 + * Foundation, either version 2 of that License or (at your option) any
103892 + * later version.
103893 + *
103894 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103895 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103896 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103897 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103898 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103899 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103900 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103901 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103902 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103903 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103904 + */
103905 +
103906 +/******************************************************************************
103907 + @File lnxwrp_fm_ext.h
103908 +
103909 + @Description TODO
103910 +*//***************************************************************************/
103911 +
103912 +#ifndef __LNXWRP_FM_EXT_H
103913 +#define __LNXWRP_FM_EXT_H
103914 +
103915 +#include "std_ext.h"
103916 +#include "sys_ext.h"
103917 +#include "fm_ext.h"
103918 +#include "fm_muram_ext.h"
103919 +#include "fm_pcd_ext.h"
103920 +#include "fm_port_ext.h"
103921 +#include "fm_mac_ext.h"
103922 +#include "fm_rtc_ext.h"
103923 +
103924 +
103925 +/**************************************************************************//**
103926 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
103927 +
103928 + @Description FM API functions, definitions and enums.
103929 +
103930 + @{
103931 +*//***************************************************************************/
103932 +
103933 +/**************************************************************************//**
103934 + @Group FM_LnxKern_init_grp Initialization Unit
103935 +
103936 + @Description Initialization Unit
103937 +
103938 + Initialization Flow:
103939 + Initialization of the FM Module will be carried out by the Linux
103940 + kernel according to the following sequence:
103941 + a. Calling the initialization routine with no parameters.
103942 + b. The driver will register to the Device-Tree.
103943 + c. The Linux Device-Tree will initiate a call to the driver for
103944 + initialization.
103945 + d. The driver will read the appropriate information from the Device-Tree
103946 + e. [Optional] Calling the advance initialization routines to change
103947 + driver's defaults.
103948 + f. Initialization of the device will be automatically upon using it.
103949 +
103950 + @{
103951 +*//***************************************************************************/
103952 +
103953 +typedef struct t_WrpFmDevSettings
103954 +{
103955 + t_FmParams param;
103956 + t_SysObjectAdvConfigEntry *advConfig;
103957 +} t_WrpFmDevSettings;
103958 +
103959 +typedef struct t_WrpFmPcdDevSettings
103960 +{
103961 + t_FmPcdParams param;
103962 + t_SysObjectAdvConfigEntry *advConfig;
103963 +} t_WrpFmPcdDevSettings;
103964 +
103965 +typedef struct t_WrpFmPortDevSettings
103966 +{
103967 + bool frag_enabled;
103968 + t_FmPortParams param;
103969 + t_SysObjectAdvConfigEntry *advConfig;
103970 +} t_WrpFmPortDevSettings;
103971 +
103972 +typedef struct t_WrpFmMacDevSettings
103973 +{
103974 + t_FmMacParams param;
103975 + t_SysObjectAdvConfigEntry *advConfig;
103976 +} t_WrpFmMacDevSettings;
103977 +
103978 +
103979 +/**************************************************************************//**
103980 + @Function LNXWRP_FM_Init
103981 +
103982 + @Description Initialize the FM linux wrapper.
103983 +
103984 + @Return A handle (descriptor) of the newly created FM Linux wrapper
103985 + structure.
103986 +*//***************************************************************************/
103987 +t_Handle LNXWRP_FM_Init(void);
103988 +
103989 +/**************************************************************************//**
103990 + @Function LNXWRP_FM_Free
103991 +
103992 + @Description Free the FM linux wrapper.
103993 +
103994 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
103995 +
103996 + @Return E_OK on success; Error code otherwise.
103997 +*//***************************************************************************/
103998 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
103999 +
104000 +/**************************************************************************//**
104001 + @Function LNXWRP_FM_GetMacHandle
104002 +
104003 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
104004 +
104005 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
104006 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
104007 + @Param[in] macId - Index of the mac handle.
104008 +
104009 + @Return A handle of the LLD compressor.
104010 +*//***************************************************************************/
104011 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
104012 +
104013 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
104014 +t_Handle LNXWRP_FM_TEST_Init(void);
104015 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
104016 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
104017 +
104018 +/** @} */ /* end of FM_LnxKern_init_grp group */
104019 +
104020 +
104021 +/**************************************************************************//**
104022 + @Group FM_LnxKern_ctrl_grp Control Unit
104023 +
104024 + @Description Control Unit
104025 +
104026 + TODO
104027 + @{
104028 +*//***************************************************************************/
104029 +
104030 +#include "lnxwrp_fsl_fman.h"
104031 +
104032 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104033 +/** @} */ /* end of FM_LnxKern_grp group */
104034 +
104035 +
104036 +#endif /* __LNXWRP_FM_EXT_H */
104037 --- /dev/null
104038 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
104039 @@ -0,0 +1,921 @@
104040 +/*
104041 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104042 + *
104043 + * Redistribution and use in source and binary forms, with or without
104044 + * modification, are permitted provided that the following conditions are met:
104045 + * * Redistributions of source code must retain the above copyright
104046 + * notice, this list of conditions and the following disclaimer.
104047 + * * Redistributions in binary form must reproduce the above copyright
104048 + * notice, this list of conditions and the following disclaimer in the
104049 + * documentation and/or other materials provided with the distribution.
104050 + * * Neither the name of Freescale Semiconductor nor the
104051 + * names of its contributors may be used to endorse or promote products
104052 + * derived from this software without specific prior written permission.
104053 + *
104054 + *
104055 + * ALTERNATIVELY, this software may be distributed under the terms of the
104056 + * GNU General Public License ("GPL") as published by the Free Software
104057 + * Foundation, either version 2 of that License or (at your option) any
104058 + * later version.
104059 + *
104060 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104061 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104062 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104063 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104064 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104065 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104066 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104067 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104068 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104069 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104070 + */
104071 +
104072 +/******************************************************************************
104073 + @File lnxwrp_fsl_fman.h
104074 +
104075 + @Description Linux internal kernel API
104076 +*//***************************************************************************/
104077 +
104078 +#ifndef __LNXWRP_FSL_FMAN_H
104079 +#define __LNXWRP_FSL_FMAN_H
104080 +
104081 +#include <linux/types.h>
104082 +#include <linux/device.h> /* struct device */
104083 +#include <linux/fsl_qman.h> /* struct qman_fq */
104084 +#include "dpaa_integration_ext.h"
104085 +#include "fm_port_ext.h"
104086 +#include "fm_mac_ext.h"
104087 +#include "fm_macsec_ext.h"
104088 +#include "fm_rtc_ext.h"
104089 +
104090 +/**************************************************************************//**
104091 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
104092 +
104093 + @Description FM API functions, definitions and enums.
104094 +
104095 + @{
104096 +*//***************************************************************************/
104097 +
104098 +/**************************************************************************//**
104099 + @Group FM_LnxKern_ctrl_grp Control Unit
104100 +
104101 + @Description Control Unit
104102 +
104103 + Internal Kernel Control Unit API
104104 + @{
104105 +*//***************************************************************************/
104106 +
104107 +/*****************************************************************************/
104108 +/* Internal Linux kernel routines */
104109 +/*****************************************************************************/
104110 +
104111 +/**************************************************************************//**
104112 + @Description MACSEC Exceptions wrapper
104113 +*//***************************************************************************/
104114 +typedef enum fm_macsec_exception {
104115 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
104116 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
104117 +} fm_macsec_exception;
104118 +
104119 +/**************************************************************************//**
104120 + @Description Unknown sci frame treatment wrapper
104121 +*//***************************************************************************/
104122 +typedef enum fm_macsec_unknown_sci_frame_treatment {
104123 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
104124 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104125 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
104126 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
104127 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104128 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
104129 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
104130 +} fm_macsec_unknown_sci_frame_treatment;
104131 +
104132 +/**************************************************************************//**
104133 + @Description Untag frame treatment wrapper
104134 +*//***************************************************************************/
104135 +typedef enum fm_macsec_untag_frame_treatment {
104136 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
104137 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
104138 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
104139 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
104140 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
104141 +} fm_macsec_untag_frame_treatment;
104142 +
104143 +/**************************************************************************//**
104144 +@Description MACSEC SECY Cipher Suite wrapper
104145 +*//***************************************************************************/
104146 +typedef enum fm_macsec_secy_cipher_suite {
104147 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
104148 +#if (DPAA_VERSION >= 11)
104149 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
104150 +#endif /* (DPAA_VERSION >= 11) */
104151 +} fm_macsec_secy_cipher_suite;
104152 +
104153 +/**************************************************************************//**
104154 + @Description MACSEC SECY Exceptions wrapper
104155 +*//***************************************************************************/
104156 +typedef enum fm_macsec_secy_exception {
104157 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
104158 +} fm_macsec_secy_exception;
104159 +
104160 +/**************************************************************************//**
104161 + @Description MACSEC SECY Events wrapper
104162 +*//***************************************************************************/
104163 +typedef enum fm_macsec_secy_event {
104164 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
104165 +} fm_macsec_secy_event;
104166 +
104167 +/**************************************************************************//**
104168 + @Description Valid frame behaviors wrapper
104169 +*//***************************************************************************/
104170 +typedef enum fm_macsec_valid_frame_behavior {
104171 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
104172 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
104173 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
104174 +} fm_macsec_valid_frame_behavior;
104175 +
104176 +/**************************************************************************//**
104177 + @Description SCI insertion modes wrapper
104178 +*//***************************************************************************/
104179 +typedef enum fm_macsec_sci_insertion_mode {
104180 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
104181 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
104182 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
104183 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
104184 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
104185 +} fm_macsec_sci_insertion_mode;
104186 +
104187 +typedef macsecSAKey_t macsec_sa_key_t;
104188 +typedef macsecSCI_t macsec_sci_t;
104189 +typedef macsecAN_t macsec_an_t;
104190 +typedef t_Handle handle_t;
104191 +
104192 +/**************************************************************************//**
104193 + @Function fm_macsec_secy_exception_callback wrapper
104194 + @Description Exceptions user callback routine, will be called upon an
104195 + exception passing the exception identification.
104196 + @Param[in] app_h A handle to an application layer object; This handle
104197 + will be passed by the driver upon calling this callback.
104198 + @Param[in] exception The exception.
104199 +*//***************************************************************************/
104200 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
104201 + fm_macsec_secy_exception exception);
104202 +
104203 +/**************************************************************************//**
104204 + @Function fm_macsec_secy_event_callback wrapper
104205 + @Description Events user callback routine, will be called upon an
104206 + event passing the event identification.
104207 + @Param[in] app_h A handle to an application layer object; This handle
104208 + will be passed by the driver upon calling this callback.
104209 + @Param[in] event The event.
104210 +*//***************************************************************************/
104211 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
104212 + fm_macsec_secy_event event);
104213 +
104214 +/**************************************************************************//**
104215 + @Function fm_macsec_exception_callback wrapper
104216 + @Description Exceptions user callback routine, will be called upon an
104217 + exception passing the exception identification.
104218 + @Param[in] app_h A handle to an application layer object; This handle
104219 + will be passed by the driver upon calling this callback.
104220 + @Param[in] exception The exception.
104221 +*//***************************************************************************/
104222 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
104223 + fm_macsec_exception exception);
104224 +
104225 +/**************************************************************************//**
104226 + @Description MACSEC SecY SC Params wrapper
104227 +*//***************************************************************************/
104228 +struct fm_macsec_secy_sc_params {
104229 + macsec_sci_t sci;
104230 + fm_macsec_secy_cipher_suite cipher_suite;
104231 +};
104232 +
104233 +/**************************************************************************//**
104234 + @Description FM MACSEC SecY config input wrapper
104235 +*//***************************************************************************/
104236 +struct fm_macsec_secy_params {
104237 + handle_t fm_macsec_h;
104238 + struct fm_macsec_secy_sc_params tx_sc_params;
104239 + uint32_t num_receive_channels;
104240 + fm_macsec_secy_exception_callback *exception_f;
104241 + fm_macsec_secy_event_callback *event_f;
104242 + handle_t app_h;
104243 +};
104244 +
104245 +/**************************************************************************//**
104246 + @Description FM MACSEC config input wrapper
104247 +*//***************************************************************************/
104248 +struct fm_macsec_params {
104249 + handle_t fm_h;
104250 + bool guest_mode;
104251 +
104252 + union {
104253 + struct {
104254 + uint8_t fm_mac_id;
104255 + } guest_params;
104256 +
104257 + struct {
104258 + uintptr_t base_addr;
104259 + handle_t fm_mac_h;
104260 + fm_macsec_exception_callback *exception_f;
104261 + handle_t app_h;
104262 + } non_guest_params;
104263 + };
104264 +
104265 +};
104266 +
104267 +/**************************************************************************//**
104268 + @Description FM device opaque structure used for type checking
104269 +*//***************************************************************************/
104270 +struct fm;
104271 +
104272 +/**************************************************************************//**
104273 + @Description FM MAC device opaque structure used for type checking
104274 +*//***************************************************************************/
104275 +struct fm_mac_dev;
104276 +
104277 +/**************************************************************************//**
104278 + @Description FM MACSEC device opaque structure used for type checking
104279 +*//***************************************************************************/
104280 +struct fm_macsec_dev;
104281 +struct fm_macsec_secy_dev;
104282 +
104283 +/**************************************************************************//**
104284 + @Description A structure ..,
104285 +*//***************************************************************************/
104286 +struct fm_port;
104287 +
104288 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
104289 + uint8_t alignment, uint32_t *base_fqid);
104290 +
104291 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
104292 +
104293 +struct fm_port_pcd_param {
104294 + alloc_pcd_fqids cba;
104295 + free_pcd_fqids cbf;
104296 + struct device *dev;
104297 +};
104298 +
104299 +/**************************************************************************//**
104300 + @Description A structure of information about each of the external
104301 + buffer pools used by the port,
104302 +*//***************************************************************************/
104303 +struct fm_port_pool_param {
104304 + uint8_t id; /**< External buffer pool id */
104305 + uint16_t size; /**< External buffer pool buffer size */
104306 +};
104307 +
104308 +/**************************************************************************//**
104309 + @Description structure for additional port parameters
104310 +*//***************************************************************************/
104311 +struct fm_port_params {
104312 + uint32_t errq; /**< Error Queue Id. */
104313 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
104314 + 0 means no Tx conf for processed frames.
104315 + For Rx and OP - default Rx queue. */
104316 + uint8_t num_pools; /**< Number of pools use by this port */
104317 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
104318 + /**< Parameters for each pool */
104319 + uint16_t priv_data_size; /**< Area that user may save for his own
104320 + need (E.g. save the SKB) */
104321 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
104322 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
104323 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
104324 + bool frag_enable; /**< Fragmentation support, for OP only */
104325 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
104326 + if write optimization is used, must be >= 16. */
104327 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
104328 + Note that this field impacts the size of the buffer-prefix
104329 + (i.e. it pushes the data offset); */
104330 +};
104331 +
104332 +/**************************************************************************//**
104333 + @Function fm_bind
104334 +
104335 + @Description Bind to a specific FM device.
104336 +
104337 + @Param[in] fm_dev - the OF handle of the FM device.
104338 +
104339 + @Return A handle of the FM device.
104340 +
104341 + @Cautions Allowed only after the port was created.
104342 +*//***************************************************************************/
104343 +struct fm *fm_bind(struct device *fm_dev);
104344 +
104345 +/**************************************************************************//**
104346 + @Function fm_unbind
104347 +
104348 + @Description Un-bind from a specific FM device.
104349 +
104350 + @Param[in] fm - A handle of the FM device.
104351 +
104352 + @Cautions Allowed only after the port was created.
104353 +*//***************************************************************************/
104354 +void fm_unbind(struct fm *fm);
104355 +
104356 +void *fm_get_handle(struct fm *fm);
104357 +void *fm_get_rtc_handle(struct fm *fm);
104358 +struct resource *fm_get_mem_region(struct fm *fm);
104359 +
104360 +/**************************************************************************//**
104361 + @Function fm_port_bind
104362 +
104363 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
104364 +
104365 + @Param[in] fm_port_dev - the OF handle of the FM port device.
104366 +
104367 + @Return A handle of the FM port device.
104368 +
104369 + @Cautions Allowed only after the port was created.
104370 +*//***************************************************************************/
104371 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
104372 +
104373 +/**************************************************************************//**
104374 + @Function fm_port_unbind
104375 +
104376 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
104377 +
104378 + @Param[in] port - A handle of the FM port device.
104379 +
104380 + @Cautions Allowed only after the port was created.
104381 +*//***************************************************************************/
104382 +void fm_port_unbind(struct fm_port *port);
104383 +
104384 +/**************************************************************************//**
104385 + @Function fm_set_rx_port_params
104386 +
104387 + @Description Configure parameters for a specific Rx FM-port device.
104388 +
104389 + @Param[in] port - A handle of the FM port device.
104390 + @Param[in] params - Rx port parameters
104391 +
104392 + @Cautions Allowed only after the port is binded.
104393 +*//***************************************************************************/
104394 +void fm_set_rx_port_params(struct fm_port *port,
104395 + struct fm_port_params *params);
104396 +
104397 +/**************************************************************************//**
104398 + @Function fm_port_pcd_bind
104399 +
104400 + @Description Bind as a listener on a port PCD.
104401 +
104402 + @Param[in] port - A handle of the FM port device.
104403 + @Param[in] params - PCD port parameters
104404 +
104405 + @Cautions Allowed only after the port is binded.
104406 +*//***************************************************************************/
104407 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
104408 +
104409 +/**************************************************************************//**
104410 + @Function fm_port_get_buff_layout_ext_params
104411 +
104412 + @Description Get data_align and manip_extra_space from the device tree
104413 + chosen node if applied.
104414 + This function will only update these two parameters.
104415 + When this port has no such parameters in the device tree
104416 + values will be set to 0.
104417 +
104418 + @Param[in] port - A handle of the FM port device.
104419 + @Param[in] params - PCD port parameters
104420 +
104421 + @Cautions Allowed only after the port is binded.
104422 +*//***************************************************************************/
104423 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
104424 +
104425 +/**************************************************************************//**
104426 + @Function fm_get_tx_port_channel
104427 +
104428 + @Description Get qman-channel number for this Tx port.
104429 +
104430 + @Param[in] port - A handle of the FM port device.
104431 +
104432 + @Return qman-channel number for this Tx port.
104433 +
104434 + @Cautions Allowed only after the port is binded.
104435 +*//***************************************************************************/
104436 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
104437 +
104438 +/**************************************************************************//**
104439 + @Function fm_set_tx_port_params
104440 +
104441 + @Description Configure parameters for a specific Tx FM-port device
104442 +
104443 + @Param[in] port - A handle of the FM port device.
104444 + @Param[in] params - Tx port parameters
104445 +
104446 + @Cautions Allowed only after the port is binded.
104447 +*//***************************************************************************/
104448 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
104449 +
104450 +
104451 +/**************************************************************************//**
104452 + @Function fm_mac_set_handle
104453 +
104454 + @Description Set mac handle
104455 +
104456 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
104457 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
104458 + @Param[in] mac_id - MAC id.
104459 +*//***************************************************************************/
104460 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
104461 + int mac_id);
104462 +
104463 +/**************************************************************************//**
104464 + @Function fm_port_enable
104465 +
104466 + @Description Enable specific FM-port device (may be Rx or Tx port).
104467 +
104468 + @Param[in] port - A handle of the FM port device.
104469 +
104470 + @Cautions Allowed only after the port is initialized.
104471 +*//***************************************************************************/
104472 +int fm_port_enable(struct fm_port *port);
104473 +
104474 +/**************************************************************************//**
104475 + @Function fm_port_disable
104476 +
104477 + @Description Disable specific FM-port device (may be Rx or Tx port).
104478 +
104479 + @Param[in] port - A handle of the FM port device.
104480 +
104481 + @Cautions Allowed only after the port is initialized.
104482 +*//***************************************************************************/
104483 +int fm_port_disable(struct fm_port *port);
104484 +
104485 +void *fm_port_get_handle(const struct fm_port *port);
104486 +
104487 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
104488 + const void *data);
104489 +
104490 +/**************************************************************************//**
104491 + @Function fm_port_get_base_address
104492 +
104493 + @Description Get base address of this port. Useful for accessing
104494 + port-specific registers (i.e., not common ones).
104495 +
104496 + @Param[in] port - A handle of the FM port device.
104497 +
104498 + @Param[out] base_addr - The port's base addr (virtual address).
104499 +*//***************************************************************************/
104500 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
104501 +
104502 +/**************************************************************************//**
104503 + @Function fm_mutex_lock
104504 +
104505 + @Description Lock function required before any FMD/LLD call.
104506 +*//***************************************************************************/
104507 +void fm_mutex_lock(void);
104508 +
104509 +/**************************************************************************//**
104510 + @Function fm_mutex_unlock
104511 +
104512 + @Description Unlock function required after any FMD/LLD call.
104513 +*//***************************************************************************/
104514 +void fm_mutex_unlock(void);
104515 +
104516 +/**************************************************************************//**
104517 + @Function fm_get_max_frm
104518 +
104519 + @Description Get the maximum frame size
104520 +*//***************************************************************************/
104521 +int fm_get_max_frm(void);
104522 +
104523 +/**************************************************************************//**
104524 + @Function fm_get_rx_extra_headroom
104525 +
104526 + @Description Get the extra headroom size
104527 +*//***************************************************************************/
104528 +int fm_get_rx_extra_headroom(void);
104529 +
104530 +/**************************************************************************//**
104531 +@Function fm_port_set_rate_limit
104532 +
104533 +@Description Configure Shaper parameter on FM-port device (Tx port).
104534 +
104535 +@Param[in] port - A handle of the FM port device.
104536 +@Param[in] max_burst_size - Value of maximum burst size allowed.
104537 +@Param[in] rate_limit - The required rate value.
104538 +
104539 +@Cautions Allowed only after the port is initialized.
104540 +*//***************************************************************************/
104541 +int fm_port_set_rate_limit(struct fm_port *port,
104542 + uint16_t max_burst_size,
104543 + uint32_t rate_limit);
104544 +/**************************************************************************//**
104545 +@Function fm_port_set_rate_limit
104546 +
104547 +@Description Delete Shaper configuration on FM-port device (Tx port).
104548 +
104549 +@Param[in] port - A handle of the FM port device.
104550 +
104551 +@Cautions Allowed only after the port is initialized.
104552 +*//***************************************************************************/
104553 +int fm_port_del_rate_limit(struct fm_port *port);
104554 +
104555 +struct auto_res_tables_sizes
104556 +{
104557 + uint16_t max_num_of_arp_entries;
104558 + uint16_t max_num_of_echo_ipv4_entries;
104559 + uint16_t max_num_of_ndp_entries;
104560 + uint16_t max_num_of_echo_ipv6_entries;
104561 + uint16_t max_num_of_snmp_ipv4_entries;
104562 + uint16_t max_num_of_snmp_ipv6_entries;
104563 + uint16_t max_num_of_snmp_oid_entries;
104564 + uint16_t max_num_of_snmp_char; /* total amount of character needed
104565 + for the snmp table */
104566 + uint16_t max_num_of_ip_prot_filtering;
104567 + uint16_t max_num_of_tcp_port_filtering;
104568 + uint16_t max_num_of_udp_port_filtering;
104569 +};
104570 +/* ARP */
104571 +struct auto_res_arp_entry
104572 +{
104573 + uint32_t ip_address;
104574 + uint8_t mac[6];
104575 + bool is_vlan;
104576 + uint16_t vid;
104577 +};
104578 +struct auto_res_arp_info
104579 +{
104580 + uint8_t table_size;
104581 + struct auto_res_arp_entry *auto_res_table;
104582 + bool enable_conflict_detection; /* when TRUE
104583 + Conflict Detection will be checked and wake the host if
104584 + needed */
104585 +};
104586 +
104587 +/* NDP */
104588 +struct auto_res_ndp_entry
104589 +{
104590 + uint32_t ip_address[4];
104591 + uint8_t mac[6];
104592 + bool is_vlan;
104593 + uint16_t vid;
104594 +};
104595 +struct auto_res_ndp_info
104596 +{
104597 + uint32_t multicast_group;
104598 + uint8_t table_size_assigned;
104599 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
104600 + refer to solicitation IP addresses. Note that all IP adresses
104601 + must be from the same multicast group. This will be checked and
104602 + if not operation will fail. */
104603 + uint8_t table_size_tmp;
104604 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
104605 + refer to temp IP addresses. Note that all temp IP adresses must
104606 + be from the same multicast group. This will be checked and if
104607 + not operation will fail. */
104608 +
104609 + bool enable_conflict_detection; /* when TRUE
104610 + Conflict Detection will be checked and wake the host if
104611 + needed */
104612 +};
104613 +
104614 +/* ICMP ECHO */
104615 +struct auto_res_echo_ipv4_info
104616 +{
104617 + uint8_t table_size;
104618 + struct auto_res_arp_entry *auto_res_table;
104619 +};
104620 +
104621 +struct auto_res_echo_ipv6_info
104622 +{
104623 + uint8_t table_size;
104624 + struct auto_res_ndp_entry *auto_res_table;
104625 +};
104626 +
104627 +/* SNMP */
104628 +struct auto_res_snmp_entry
104629 +{
104630 + uint16_t oidSize;
104631 + uint8_t *oidVal; /* only the oid string */
104632 + uint16_t resSize;
104633 + uint8_t *resVal; /* resVal will be the entire reply,
104634 + i.e. "Type|Length|Value" */
104635 +};
104636 +
104637 +/**************************************************************************//**
104638 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
104639 + Refer to the FMan Controller spec for more details.
104640 +*//***************************************************************************/
104641 +struct auto_res_snmp_ipv4addr_tbl_entry
104642 +{
104643 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
104644 + bool is_vlan;
104645 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104646 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104647 +};
104648 +
104649 +/**************************************************************************//**
104650 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
104651 + Refer to the FMan Controller spec for more details.
104652 +*//***************************************************************************/
104653 +struct auto_res_snmp_ipv6addr_tbl_entry
104654 +{
104655 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
104656 + bool isVlan;
104657 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
104658 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
104659 +};
104660 +
104661 +struct auto_res_snmp_info
104662 +{
104663 + uint16_t control; /**< Control bits [0-15]. */
104664 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
104665 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
104666 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
104667 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
104668 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
104669 + char *community_read_write_string;
104670 + char *community_read_only_string;
104671 + struct auto_res_snmp_entry *oid_table;
104672 + uint32_t oid_table_size;
104673 + uint32_t *statistics;
104674 +};
104675 +
104676 +/* Filtering */
104677 +struct auto_res_port_filtering_entry
104678 +{
104679 + uint16_t src_port;
104680 + uint16_t dst_port;
104681 + uint16_t src_port_mask;
104682 + uint16_t dst_port_mask;
104683 +};
104684 +struct auto_res_filtering_info
104685 +{
104686 + /* IP protocol filtering parameters */
104687 + uint8_t ip_prot_table_size;
104688 + uint8_t *ip_prot_table_ptr;
104689 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
104690 + cause the packet to be droped, hit will pass the packet to
104691 + UDP/TCP filters if needed and if not to the classification
104692 + tree. If the classification tree will pass the packet to a
104693 + queue it will cause a wake interupt. When FALSE it the other
104694 + way around. */
104695 + /* UDP port filtering parameters */
104696 + uint8_t udp_ports_table_size;
104697 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
104698 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
104699 + cause the packet to be droped, hit will pass the packet to
104700 + classification tree. If the classification tree will pass the
104701 + packet to a queue it will cause a wake interupt. When FALSE it
104702 + the other way around. */
104703 + /* TCP port filtering parameters */
104704 + uint16_t tcp_flags_mask;
104705 + uint8_t tcp_ports_table_size;
104706 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
104707 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
104708 + cause the packet to be droped, hit will pass the packet to
104709 + classification tree. If the classification tree will pass the
104710 + packet to a queue it will cause a wake interupt. When FALSE it
104711 + the other way around. */
104712 +};
104713 +
104714 +struct auto_res_port_params
104715 +{
104716 + t_Handle h_FmPortTx;
104717 + struct auto_res_arp_info *p_auto_res_arp_info;
104718 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
104719 + struct auto_res_ndp_info *p_auto_res_ndp_info;
104720 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
104721 + struct auto_res_snmp_info *p_auto_res_snmp_info;
104722 + struct auto_res_filtering_info *p_auto_res_filtering_info;
104723 +};
104724 +
104725 +struct auto_res_port_stats
104726 +{
104727 + uint32_t arp_ar_cnt;
104728 + uint32_t echo_icmpv4_ar_cnt;
104729 + uint32_t ndp_ar_cnt;
104730 + uint32_t echo_icmpv6_ar_cnt;
104731 +};
104732 +
104733 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
104734 + struct auto_res_tables_sizes *params);
104735 +
104736 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
104737 + struct auto_res_port_params *params);
104738 +
104739 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
104740 + struct fm_port *port_tx);
104741 +
104742 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
104743 +
104744 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
104745 + struct fm_port *port);
104746 +
104747 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
104748 + *stats);
104749 +
104750 +int fm_port_resume(struct fm_port *port);
104751 +
104752 +int fm_port_suspend(struct fm_port *port);
104753 +
104754 +#ifdef CONFIG_FMAN_PFC
104755 +/**************************************************************************//**
104756 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
104757 +
104758 +@Description Associate a QMan Work Queue with a PFC priority on this
104759 + FM-port device (Tx port).
104760 +
104761 +@Param[in] port - A handle of the FM port device.
104762 +
104763 +@Param[in] prio - The PFC priority.
104764 +
104765 +@Param[in] wq - The Work Queue associated with the PFC priority.
104766 +
104767 +@Cautions Allowed only after the port is initialized.
104768 +*//***************************************************************************/
104769 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
104770 + uint8_t prio, uint8_t wq);
104771 +#endif
104772 +
104773 +/**************************************************************************//**
104774 +@Function fm_mac_set_exception
104775 +
104776 +@Description Set MAC exception state.
104777 +
104778 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
104779 +@Param[in] exception - FM MAC exception type.
104780 +@Param[in] enable - new state.
104781 +
104782 +*//***************************************************************************/
104783 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
104784 + e_FmMacExceptions exception, bool enable);
104785 +
104786 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
104787 +
104788 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
104789 +
104790 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
104791 + int len);
104792 +
104793 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
104794 +
104795 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
104796 +
104797 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
104798 +
104799 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
104800 +
104801 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
104802 +
104803 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
104804 +
104805 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
104806 +
104807 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
104808 +
104809 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
104810 + bool enable);
104811 +
104812 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104813 + t_EnetAddr *mac_addr);
104814 +
104815 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
104816 + t_EnetAddr *mac_addr);
104817 +
104818 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
104819 + uint8_t *addr);
104820 +
104821 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
104822 + bool link, int speed, bool duplex);
104823 +
104824 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104825 +
104826 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
104827 +
104828 +int fm_mac_set_rx_pause_frames(
104829 + struct fm_mac_dev *fm_mac_dev, bool en);
104830 +
104831 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
104832 + bool en);
104833 +
104834 +int fm_rtc_enable(struct fm *fm_dev);
104835 +
104836 +int fm_rtc_disable(struct fm *fm_dev);
104837 +
104838 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
104839 +
104840 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
104841 +
104842 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
104843 +
104844 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
104845 +
104846 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
104847 + uint64_t time);
104848 +
104849 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
104850 + uint64_t fiper);
104851 +
104852 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
104853 + bool en);
104854 +
104855 +/**************************************************************************//**
104856 +@Function fm_macsec_set_exception
104857 +
104858 +@Description Set MACSEC exception state.
104859 +
104860 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
104861 +@Param[in] exception - FM MACSEC exception type.
104862 +@Param[in] enable - new state.
104863 +
104864 +*//***************************************************************************/
104865 +
104866 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
104867 + fm_macsec_exception exception, bool enable);
104868 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
104869 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
104870 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
104871 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
104872 + *fm_macsec_dev,
104873 + fm_macsec_unknown_sci_frame_treatment treat_mode);
104874 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104875 + bool deliver_uncontrolled);
104876 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104877 + bool discard_uncontrolled);
104878 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
104879 + fm_macsec_untag_frame_treatment treat_mode);
104880 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
104881 + uint32_t pnExhThr);
104882 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
104883 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
104884 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
104885 + fm_macsec_exception exception, bool enable);
104886 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
104887 + int *macsec_revision);
104888 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
104889 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
104890 +
104891 +
104892 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104893 + fm_macsec_secy_exception exception,
104894 + bool enable);
104895 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104896 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
104897 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104898 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104899 + fm_macsec_sci_insertion_mode sci_insertion_mode);
104900 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104901 + bool protect_frames);
104902 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104903 + bool replay_protect, uint32_t replay_window);
104904 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104905 + fm_macsec_valid_frame_behavior validate_frames);
104906 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104907 + bool confidentiality_enable,
104908 + uint32_t confidentiality_offset);
104909 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
104910 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104911 + fm_macsec_secy_event event,
104912 + bool enable);
104913 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104914 + struct fm_macsec_secy_sc_params *params);
104915 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104916 + struct rx_sc_dev *sc);
104917 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104918 + struct rx_sc_dev *sc, macsec_an_t an,
104919 + uint32_t lowest_pn, macsec_sa_key_t key);
104920 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104921 + struct rx_sc_dev *sc, macsec_an_t an);
104922 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104923 + struct rx_sc_dev *sc,
104924 + macsec_an_t an);
104925 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104926 + struct rx_sc_dev *sc,
104927 + macsec_an_t an);
104928 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104929 + struct rx_sc_dev *sc,
104930 + macsec_an_t an, uint32_t updt_next_pn);
104931 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104932 + struct rx_sc_dev *sc,
104933 + macsec_an_t an, uint32_t updt_lowest_pn);
104934 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104935 + struct rx_sc_dev *sc,
104936 + macsec_an_t an, macsec_sa_key_t key);
104937 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104938 + macsec_an_t an, macsec_sa_key_t key);
104939 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104940 + macsec_an_t an);
104941 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104942 + macsec_an_t next_active_an,
104943 + macsec_sa_key_t key);
104944 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104945 + macsec_an_t an);
104946 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104947 + macsec_an_t *p_an);
104948 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104949 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
104950 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
104951 + uint32_t *sc_phys_id);
104952 +
104953 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
104954 +/** @} */ /* end of FM_LnxKern_grp group */
104955 +
104956 +/* default values for initializing PTP 1588 timer clock */
104957 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
104958 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
104959 +
104960 +#endif /* __LNXWRP_FSL_FMAN_H */
104961 --- /dev/null
104962 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
104963 @@ -0,0 +1,50 @@
104964 +/*
104965 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104966 + *
104967 + * Redistribution and use in source and binary forms, with or without
104968 + * modification, are permitted provided that the following conditions are met:
104969 + * * Redistributions of source code must retain the above copyright
104970 + * notice, this list of conditions and the following disclaimer.
104971 + * * Redistributions in binary form must reproduce the above copyright
104972 + * notice, this list of conditions and the following disclaimer in the
104973 + * documentation and/or other materials provided with the distribution.
104974 + * * Neither the name of Freescale Semiconductor nor the
104975 + * names of its contributors may be used to endorse or promote products
104976 + * derived from this software without specific prior written permission.
104977 + *
104978 + *
104979 + * ALTERNATIVELY, this software may be distributed under the terms of the
104980 + * GNU General Public License ("GPL") as published by the Free Software
104981 + * Foundation, either version 2 of that License or (at your option) any
104982 + * later version.
104983 + *
104984 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104985 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104986 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104987 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104988 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104989 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104990 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104991 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104992 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104993 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104994 + */
104995 +
104996 +#ifndef __XX_H
104997 +#define __XX_H
104998 +
104999 +#include "xx_ext.h"
105000 +
105001 +void * xx_Malloc(uint32_t n);
105002 +void xx_Free(void *p);
105003 +
105004 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
105005 +void xx_FreeSmart(void *p);
105006 +
105007 +/* never used: */
105008 +#define GetDeviceName(irq) ((char *)NULL)
105009 +
105010 +int GetDeviceIrqNum(int irq);
105011 +
105012 +
105013 +#endif /* __XX_H */
105014 --- /dev/null
105015 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
105016 @@ -0,0 +1,10 @@
105017 +#
105018 +# Makefile for the Freescale Ethernet controllers
105019 +#
105020 +ccflags-y += -DVERSION=\"\"
105021 +#
105022 +#Include netcomm SW specific definitions
105023 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105024 +#
105025 +
105026 +obj-y += sys_io.o
105027 --- /dev/null
105028 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
105029 @@ -0,0 +1,171 @@
105030 +/*
105031 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105032 + *
105033 + * Redistribution and use in source and binary forms, with or without
105034 + * modification, are permitted provided that the following conditions are met:
105035 + * * Redistributions of source code must retain the above copyright
105036 + * notice, this list of conditions and the following disclaimer.
105037 + * * Redistributions in binary form must reproduce the above copyright
105038 + * notice, this list of conditions and the following disclaimer in the
105039 + * documentation and/or other materials provided with the distribution.
105040 + * * Neither the name of Freescale Semiconductor nor the
105041 + * names of its contributors may be used to endorse or promote products
105042 + * derived from this software without specific prior written permission.
105043 + *
105044 + *
105045 + * ALTERNATIVELY, this software may be distributed under the terms of the
105046 + * GNU General Public License ("GPL") as published by the Free Software
105047 + * Foundation, either version 2 of that License or (at your option) any
105048 + * later version.
105049 + *
105050 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105051 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105052 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105053 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105054 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105055 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105056 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105057 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105058 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105059 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105060 + */
105061 +
105062 +#include <linux/version.h>
105063 +
105064 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
105065 +#define MODVERSIONS
105066 +#endif
105067 +#ifdef MODVERSIONS
105068 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
105069 +#include <linux/modversions.h>
105070 +#else
105071 +#include <config/modversions.h>
105072 +#endif /* LINUX_VERSION_CODE */
105073 +#endif /* MODVERSIONS */
105074 +
105075 +#include <linux/module.h>
105076 +#include <linux/kernel.h>
105077 +
105078 +#include <asm/io.h>
105079 +
105080 +#include "std_ext.h"
105081 +#include "error_ext.h"
105082 +#include "string_ext.h"
105083 +#include "list_ext.h"
105084 +#include "sys_io_ext.h"
105085 +
105086 +
105087 +#define __ERR_MODULE__ MODULE_UNKNOWN
105088 +
105089 +
105090 +typedef struct {
105091 + uint64_t virtAddr;
105092 + uint64_t physAddr;
105093 + uint32_t size;
105094 + t_List node;
105095 +} t_IoMap;
105096 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
105097 +
105098 +LIST(mapsList);
105099 +
105100 +
105101 +static void EnqueueIoMap(t_IoMap *p_IoMap)
105102 +{
105103 + uint32_t intFlags;
105104 +
105105 + intFlags = XX_DisableAllIntr();
105106 + LIST_AddToTail(&p_IoMap->node, &mapsList);
105107 + XX_RestoreAllIntr(intFlags);
105108 +}
105109 +
105110 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
105111 +{
105112 + t_IoMap *p_IoMap;
105113 + t_List *p_Pos;
105114 +
105115 + LIST_FOR_EACH(p_Pos, &mapsList)
105116 + {
105117 + p_IoMap = IOMAP_OBJECT(p_Pos);
105118 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
105119 + return p_IoMap;
105120 + }
105121 +
105122 + return NULL;
105123 +}
105124 +
105125 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
105126 +{
105127 + t_IoMap *p_IoMap;
105128 + t_List *p_Pos;
105129 +
105130 + LIST_FOR_EACH(p_Pos, &mapsList)
105131 + {
105132 + p_IoMap = IOMAP_OBJECT(p_Pos);
105133 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
105134 + return p_IoMap;
105135 + }
105136 +
105137 + return NULL;
105138 +}
105139 +
105140 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
105141 +{
105142 + t_IoMap *p_IoMap;
105143 +
105144 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
105145 + if (!p_IoMap)
105146 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
105147 + memset(p_IoMap, 0, sizeof(t_IoMap));
105148 +
105149 + p_IoMap->virtAddr = virtAddr;
105150 + p_IoMap->physAddr = physAddr;
105151 + p_IoMap->size = size;
105152 +
105153 + INIT_LIST(&p_IoMap->node);
105154 + EnqueueIoMap(p_IoMap);
105155 +
105156 + return E_OK;
105157 +}
105158 +
105159 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
105160 +{
105161 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
105162 + if (!p_IoMap)
105163 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
105164 +
105165 + LIST_Del(&p_IoMap->node);
105166 + XX_Free(p_IoMap);
105167 +
105168 + return E_OK;
105169 +}
105170 +
105171 +uint64_t SYS_PhysToVirt(uint64_t addr)
105172 +{
105173 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
105174 + if (p_IoMap)
105175 + {
105176 + /* This is optimization - put the latest in the list-head - like a cache */
105177 + if (mapsList.p_Next != &p_IoMap->node)
105178 + {
105179 + uint32_t intFlags = XX_DisableAllIntr();
105180 + LIST_DelAndInit(&p_IoMap->node);
105181 + LIST_Add(&p_IoMap->node, &mapsList);
105182 + XX_RestoreAllIntr(intFlags);
105183 + }
105184 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
105185 + }
105186 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
105187 +}
105188 +
105189 +uint64_t SYS_VirtToPhys(uint64_t addr)
105190 +{
105191 + t_IoMap *p_IoMap;
105192 +
105193 + if (addr == 0)
105194 + return 0;
105195 +
105196 + p_IoMap = FindIoMapByVirtAddr(addr);
105197 + if (p_IoMap)
105198 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
105199 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
105200 +}
105201 --- /dev/null
105202 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
105203 @@ -0,0 +1,19 @@
105204 +#
105205 +# Makefile for the Freescale Ethernet controllers
105206 +#
105207 +ccflags-y += -DVERSION=\"\"
105208 +#
105209 +#Include netcomm SW specific definitions
105210 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
105211 +
105212 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
105213 +
105214 +ccflags-y += -I$(NCSW_FM_INC)
105215 +ccflags-y += -I$(NET_DPA)
105216 +
105217 +obj-y += fsl-ncsw-PFM.o
105218 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
105219 +
105220 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
105221 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
105222 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
105223 --- /dev/null
105224 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
105225 @@ -0,0 +1,1665 @@
105226 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
105227 + * All rights reserved.
105228 + *
105229 + * Redistribution and use in source and binary forms, with or without
105230 + * modification, are permitted provided that the following conditions are met:
105231 + * * Redistributions of source code must retain the above copyright
105232 + * notice, this list of conditions and the following disclaimer.
105233 + * * Redistributions in binary form must reproduce the above copyright
105234 + * notice, this list of conditions and the following disclaimer in the
105235 + * documentation and/or other materials provided with the distribution.
105236 + * * Neither the name of Freescale Semiconductor nor the
105237 + * names of its contributors may be used to endorse or promote products
105238 + * derived from this software without specific prior written permission.
105239 + *
105240 + *
105241 + * ALTERNATIVELY, this software may be distributed under the terms of the
105242 + * GNU General Public License ("GPL") as published by the Free Software
105243 + * Foundation, either version 2 of that License or (at your option) any
105244 + * later version.
105245 + *
105246 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105247 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105248 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105249 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105250 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105251 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105252 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105253 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105254 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105255 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105256 + */
105257 +
105258 +/*
105259 + @File fman_test.c
105260 + @Authors Pistirica Sorin Andrei
105261 + @Description FM Linux test environment
105262 +*/
105263 +
105264 +#include <linux/kernel.h>
105265 +#include <linux/module.h>
105266 +#include <linux/fs.h>
105267 +#include <linux/cdev.h>
105268 +#include <linux/device.h>
105269 +#include <linux/io.h>
105270 +#include <linux/ioport.h>
105271 +#include <linux/of_platform.h>
105272 +#include <linux/ip.h>
105273 +#include <linux/compat.h>
105274 +#include <linux/uaccess.h>
105275 +#include <linux/errno.h>
105276 +#include <linux/netdevice.h>
105277 +#include <linux/spinlock.h>
105278 +#include <linux/types.h>
105279 +#include <linux/fsl_qman.h>
105280 +#include <linux/fsl_bman.h>
105281 +
105282 +/* private headers */
105283 +#include "fm_ext.h"
105284 +#include "lnxwrp_fsl_fman.h"
105285 +#include "fm_port_ext.h"
105286 +#if (DPAA_VERSION == 11)
105287 +#include "../../Peripherals/FM/MAC/memac.h"
105288 +#endif
105289 +#include "fm_test_ioctls.h"
105290 +#include "fsl_fman_test.h"
105291 +
105292 +#include "dpaa_eth.h"
105293 +#include "dpaa_eth_common.h"
105294 +
105295 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
105296 +
105297 +struct fmt_frame_s {
105298 + ioc_fmt_buff_desc_t buff;
105299 + struct list_head list;
105300 +};
105301 +
105302 +struct fmt_fqs_s {
105303 + struct qman_fq fq_base;
105304 + bool init;
105305 + struct fmt_port_s *fmt_port_priv;
105306 +};
105307 +
105308 +struct fmt_port_pcd_s {
105309 + int num_queues;
105310 + struct fmt_fqs_s *fmt_pcd_fqs;
105311 + uint32_t fqid_base;
105312 +};
105313 +
105314 +/* char dev structure: fm test port */
105315 +struct fmt_port_s {
105316 + bool valid;
105317 + uint8_t id;
105318 + ioc_fmt_port_type port_type;
105319 + ioc_diag_mode diag;
105320 + bool compat_test_type;
105321 +
105322 + /* fm ports */
105323 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
105324 + * p_tx_port == p_rx_port */
105325 + /* t_LnxWrpFmPortDev */
105326 + struct fm_port *p_tx_port;
105327 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105328 + void *p_tx_fm_port_dev;
105329 + /* t_LnxWrpFmPortDev */
105330 + struct fm_port *p_rx_port;
105331 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
105332 + void *p_rx_fm_port_dev;
105333 +
105334 + void *p_mac_dev;
105335 + uint64_t fm_phys_base_addr;
105336 +
105337 + /* read/write queue manipulation */
105338 + spinlock_t rx_q_lock;
105339 + struct list_head rx_q;
105340 +
105341 + /* tx queuee for injecting traffic */
105342 + int num_of_tx_fqs;
105343 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
105344 +
105345 + /* pcd private queues manipulation */
105346 + struct fmt_port_pcd_s fmt_port_pcd;
105347 +
105348 + /* debugging stuff */
105349 +
105350 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105351 + atomic_t enqueue_to_qman_frm;
105352 + atomic_t enqueue_to_rxq;
105353 + atomic_t dequeue_from_rxq;
105354 + atomic_t not_enqueue_to_rxq_wrong_frm;
105355 +#endif
105356 +
105357 +};
105358 +
105359 +/* The devices. */
105360 +struct fmt_s {
105361 + int major;
105362 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
105363 + struct class *fmt_class;
105364 +};
105365 +
105366 +/* fm test structure */
105367 +static struct fmt_s fm_test;
105368 +
105369 +#if (DPAA_VERSION == 11)
105370 +struct mac_priv_s {
105371 + t_Handle mac;
105372 +};
105373 +#endif
105374 +
105375 +#define DTSEC_BASE_ADDR 0x000e0000
105376 +#define DTSEC_MEM_RANGE 0x00002000
105377 +#define MAC_1G_MACCFG1 0x00000100
105378 +#define MAC_1G_LOOP_MASK 0x00000100
105379 +static int set_1gmac_loopback(
105380 + struct fmt_port_s *fmt_port,
105381 + bool en)
105382 +{
105383 +#if (DPAA_VERSION <= 10)
105384 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
105385 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
105386 + phys_addr_t maccfg1_hw;
105387 + void *maccfg1_map;
105388 + uint32_t maccfg1_val;
105389 +
105390 + /* compute the maccfg1 register address */
105391 + maccfg1_hw = fmt_port->fm_phys_base_addr +
105392 + (phys_addr_t)(DTSEC_BASE_ADDR +
105393 + dtsec_idx_off +
105394 + MAC_1G_MACCFG1);
105395 +
105396 + /* map register */
105397 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
105398 +
105399 + /* set register */
105400 + maccfg1_val = in_be32(maccfg1_map);
105401 + if (en)
105402 + maccfg1_val |= MAC_1G_LOOP_MASK;
105403 + else
105404 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
105405 + out_be32(maccfg1_map, maccfg1_val);
105406 +
105407 + /* unmap register */
105408 + iounmap(maccfg1_map);
105409 +#else
105410 + struct mac_device *mac_dev;
105411 + struct mac_priv_s *priv;
105412 + t_Memac *p_memac;
105413 +
105414 + if (!fmt_port)
105415 + return -EINVAL;
105416 +
105417 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
105418 +
105419 + if (!mac_dev)
105420 + return -EINVAL;
105421 +
105422 + priv = macdev_priv(mac_dev);
105423 +
105424 + if (!priv)
105425 + return -EINVAL;
105426 +
105427 + p_memac = priv->mac;
105428 +
105429 + if (!p_memac)
105430 + return -EINVAL;
105431 +
105432 + memac_set_loopback(p_memac->p_MemMap, en);
105433 +#endif
105434 + return 0;
105435 +}
105436 +
105437 +/* TODO: re-write this function */
105438 +static int set_10gmac_int_loopback(
105439 + struct fmt_port_s *fmt_port,
105440 + bool en)
105441 +{
105442 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
105443 +#define FM_10GMAC0_OFFSET 0x000f0000
105444 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
105445 +#define CMD_CFG_LOOPBACK_EN 0x00000400
105446 +
105447 + uint64_t base_addr, reg_addr;
105448 + uint32_t tmp_val;
105449 +
105450 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
105451 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
105452 +
105453 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
105454 +
105455 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
105456 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
105457 + if (en)
105458 + tmp_val |= CMD_CFG_LOOPBACK_EN;
105459 + else
105460 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
105461 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
105462 +
105463 + iounmap(UINT_TO_PTR(base_addr));
105464 +
105465 + return 0;
105466 +#else
105467 + _fmt_err("TGEC don't have internal-loopback.\n");
105468 + return -EPERM;
105469 +#endif
105470 +}
105471 +
105472 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
105473 +{
105474 + int _err = 0;
105475 +
105476 + switch (fmt_port->port_type) {
105477 +
105478 + case e_IOC_FMT_PORT_T_RXTX:
105479 + /* 1G port */
105480 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
105481 + _err = set_1gmac_loopback(fmt_port, en);
105482 + /* 10g port */
105483 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
105484 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
105485 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
105486 +
105487 + _err = set_10gmac_int_loopback(fmt_port, en);
105488 + } else
105489 + _err = -EINVAL;
105490 + break;
105491 + /* op port does not have MAC (loopback mode) */
105492 + case e_IOC_FMT_PORT_T_OP:
105493 +
105494 + _err = 0;
105495 + break;
105496 + default:
105497 +
105498 + _err = -EPERM;
105499 + break;
105500 + }
105501 +
105502 + return _err;
105503 +}
105504 +
105505 +static void enqueue_fmt_frame(
105506 + struct fmt_port_s *fmt_port,
105507 + struct fmt_frame_s *p_fmt_frame)
105508 +{
105509 + spinlock_t *rx_q_lock = NULL;
105510 +
105511 + rx_q_lock = &fmt_port->rx_q_lock;
105512 +
105513 + spin_lock(rx_q_lock);
105514 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
105515 + spin_unlock(rx_q_lock);
105516 +
105517 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105518 + atomic_inc(&fmt_port->enqueue_to_rxq);
105519 +#endif
105520 +}
105521 +
105522 +static struct fmt_frame_s *dequeue_fmt_frame(
105523 + struct fmt_port_s *fmt_port)
105524 +{
105525 + struct fmt_frame_s *p_fmt_frame = NULL;
105526 + spinlock_t *rx_q_lock = NULL;
105527 +
105528 + rx_q_lock = &fmt_port->rx_q_lock;
105529 +
105530 + spin_lock(rx_q_lock);
105531 +
105532 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
105533 +
105534 + if (!list_empty(&fmt_port->rx_q)) {
105535 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
105536 + struct fmt_frame_s,
105537 + list);
105538 + list_del(&p_fmt_frame->list);
105539 +
105540 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105541 + atomic_inc(&fmt_port->dequeue_from_rxq);
105542 +#endif
105543 + }
105544 +
105545 + spin_unlock(rx_q_lock);
105546 +
105547 + return p_fmt_frame;
105548 +}
105549 +
105550 +/* eth-dev -to- fmt port association */
105551 +struct fmt_port_s *match_dpa_to_fmt_port(
105552 + struct dpa_priv_s *dpa_priv) {
105553 + struct mac_device *mac_dev = dpa_priv->mac_dev;
105554 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
105555 + struct fmt_port_s *fmt_port = NULL;
105556 + int i;
105557 +
105558 + _fmt_dbgr("calling...\n");
105559 +
105560 + /* find the FM-test-port object */
105561 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
105562 + if ((fm_test.ports[i].p_mac_dev &&
105563 + mac_dev == fm_test.ports[i].p_mac_dev) ||
105564 + fm_port == fm_test.ports[i].p_tx_port) {
105565 +
105566 + fmt_port = &fm_test.ports[i];
105567 + break;
105568 + }
105569 +
105570 + _fmt_dbgr("called\n");
105571 + return fmt_port;
105572 +}
105573 +
105574 +void dump_frame(
105575 + uint8_t *buffer,
105576 + uint32_t size)
105577 +{
105578 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105579 + unsigned int i;
105580 +
105581 + for (i = 0; i < size; i++) {
105582 + if (i%16 == 0)
105583 + printk(KERN_DEBUG "\n");
105584 + printk(KERN_DEBUG "%2x ", *(buffer+i));
105585 + }
105586 +#endif
105587 + return;
105588 +}
105589 +
105590 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
105591 + uint32_t fqid,
105592 + uint8_t *buffer,
105593 + uint32_t size)
105594 +{
105595 + struct fmt_frame_s *p_fmt_frame = NULL;
105596 + bool test_and_steal_frame_frame;
105597 + uint32_t data_offset;
105598 + uint32_t i;
105599 +
105600 + _fmt_dbgr("calling...\n");
105601 +
105602 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
105603 + return false;
105604 +
105605 + /* check watermark */
105606 + test_and_steal_frame_frame = false;
105607 + for (i = 0; i < size; i++) {
105608 + uint64_t temp = *((uint64_t *)(buffer + i));
105609 +
105610 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
105611 + _fmt_dbgr("watermark found!\n");
105612 + test_and_steal_frame_frame = true;
105613 + break;
105614 + }
105615 + }
105616 +
105617 + if (!test_and_steal_frame_frame) {
105618 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
105619 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
105620 +#endif
105621 + _fmt_dbgr("NOT watermark found!\n");
105622 + return false;
105623 + }
105624 +
105625 + /* do not enqueue the tx conf/err frames */
105626 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
105627 + goto _test_and_steal_frame_return_true;
105628 +
105629 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
105630 + data_offset = FM_PORT_GetBufferDataOffset(
105631 + fmt_port->p_rx_fm_port_dev);
105632 +
105633 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
105634 +
105635 + /* dump frame... no more space left on device */
105636 + if (p_fmt_frame == NULL) {
105637 + _fmt_err("no space left on device!\n");
105638 + goto _test_and_steal_frame_return_true;
105639 + }
105640 +
105641 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
105642 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
105643 +
105644 + /* No more space left on device*/
105645 + if (p_fmt_frame->buff.p_data == NULL) {
105646 + _fmt_err("no space left on device!\n");
105647 + kfree(p_fmt_frame);
105648 + goto _test_and_steal_frame_return_true;
105649 + }
105650 +
105651 + p_fmt_frame->buff.size = size-data_offset;
105652 + p_fmt_frame->buff.qid = fqid;
105653 +
105654 + memcpy(p_fmt_frame->buff.p_data,
105655 + (uint8_t *)PTR_MOVE(buffer, data_offset),
105656 + p_fmt_frame->buff.size);
105657 +
105658 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
105659 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
105660 + (char *)buffer),
105661 + 32);
105662 +
105663 + /* enqueue frame - this frame will go to us */
105664 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
105665 +
105666 +_test_and_steal_frame_return_true:
105667 + return true;
105668 +}
105669 +
105670 +static int fmt_fq_release(const struct qm_fd *fd)
105671 +{
105672 + struct dpa_bp *_dpa_bp;
105673 + struct bm_buffer _bmb;
105674 +
105675 + if (fd->format == qm_fd_contig) {
105676 + _dpa_bp = dpa_bpid2pool(fd->bpid);
105677 + BUG_ON(IS_ERR(_dpa_bp));
105678 +
105679 + _bmb.hi = fd->addr_hi;
105680 + _bmb.lo = fd->addr_lo;
105681 +
105682 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
105683 + cpu_relax();
105684 +
105685 + } else {
105686 + _fmt_err("frame not supported !\n");
105687 + return -1;
105688 + }
105689 +
105690 + return 0;
105691 +}
105692 +
105693 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
105694 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
105695 + fm_get_rx_extra_headroom() + \
105696 + DPA_PARSE_RESULTS_SIZE + \
105697 + DPA_HASH_RESULTS_SIZE)
105698 +#define MAC_HEADER_LENGTH 14
105699 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
105700 +
105701 +/* dpa ingress hooks definition */
105702 +enum dpaa_eth_hook_result fmt_rx_default_hook(
105703 + struct sk_buff *skb,
105704 + struct net_device *net_dev,
105705 + u32 fqid)
105706 +{
105707 + struct dpa_priv_s *dpa_priv = NULL;
105708 + struct fmt_port_s *fmt_port = NULL;
105709 + uint8_t *buffer;
105710 + uint32_t buffer_len;
105711 +
105712 + _fmt_dbgr("calling...\n");
105713 +
105714 + dpa_priv = netdev_priv(net_dev);
105715 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105716 +
105717 + /* conversion from skb to fd:
105718 + * skb cames processed for L3, so we need to go back for
105719 + * layer 2 offset */
105720 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
105721 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
105722 +
105723 + /* if is not out frame let dpa to handle it */
105724 + if (test_and_steal_frame(fmt_port,
105725 + FMT_RX_DFLT_Q,
105726 + buffer,
105727 + buffer_len))
105728 + goto _fmt_rx_default_hook_stolen;
105729 +
105730 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105731 + return DPAA_ETH_CONTINUE;
105732 +
105733 +_fmt_rx_default_hook_stolen:
105734 + dev_kfree_skb(skb);
105735 +
105736 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105737 + return DPAA_ETH_STOLEN;
105738 +}
105739 +
105740 +enum dpaa_eth_hook_result fmt_rx_error_hook(
105741 + struct net_device *net_dev,
105742 + const struct qm_fd *fd,
105743 + u32 fqid)
105744 +{
105745 + struct dpa_priv_s *dpa_priv = NULL;
105746 + struct dpa_bp *dpa_bp = NULL;
105747 + struct fmt_port_s *fmt_port = NULL;
105748 + void *fd_virt_addr = NULL;
105749 + dma_addr_t addr = qm_fd_addr(fd);
105750 +
105751 + _fmt_dbgr("calling...\n");
105752 +
105753 + dpa_priv = netdev_priv(net_dev);
105754 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105755 +
105756 + /* dpaa doesn't do this... we have to do it here */
105757 + dpa_bp = dpa_bpid2pool(fd->bpid);
105758 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
105759 +
105760 + fd_virt_addr = phys_to_virt(addr);
105761 + /* if is not out frame let dpa to handle it */
105762 + if (test_and_steal_frame(fmt_port,
105763 + FMT_RX_ERR_Q,
105764 + fd_virt_addr,
105765 + fd->length20 + fd->offset)) {
105766 + goto _fmt_rx_error_hook_stolen;
105767 + }
105768 +
105769 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105770 + return DPAA_ETH_CONTINUE;
105771 +
105772 +_fmt_rx_error_hook_stolen:
105773 + /* the frame data doesn't matter,
105774 + * so, no mapping is needed */
105775 + fmt_fq_release(fd);
105776 +
105777 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105778 + return DPAA_ETH_STOLEN;
105779 +}
105780 +
105781 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
105782 + struct net_device *net_dev,
105783 + const struct qm_fd *fd,
105784 + u32 fqid)
105785 +{
105786 + struct dpa_priv_s *dpa_priv = NULL;
105787 + struct fmt_port_s *fmt_port = NULL;
105788 + dma_addr_t addr = qm_fd_addr(fd);
105789 + void *fd_virt_addr = NULL;
105790 + uint32_t fd_len = 0;
105791 +
105792 + _fmt_dbgr("calling...\n");
105793 +
105794 + dpa_priv = netdev_priv(net_dev);
105795 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105796 +
105797 + fd_virt_addr = phys_to_virt(addr);
105798 + fd_len = fd->length20 + fd->offset;
105799 +
105800 + if (fd_len > fm_get_max_frm()) {
105801 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
105802 + goto _fmt_tx_confirm_hook_continue;
105803 + }
105804 +
105805 + if (test_and_steal_frame(fmt_port,
105806 + FMT_TX_CONF_Q,
105807 + fd_virt_addr,
105808 + fd_len))
105809 + goto _fmt_tx_confirm_hook_stolen;
105810 +
105811 +_fmt_tx_confirm_hook_continue:
105812 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105813 + return DPAA_ETH_CONTINUE;
105814 +
105815 +_fmt_tx_confirm_hook_stolen:
105816 + kfree(fd_virt_addr);
105817 +
105818 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105819 + return DPAA_ETH_STOLEN;
105820 +}
105821 +
105822 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
105823 + struct net_device *net_dev,
105824 + const struct qm_fd *fd,
105825 + u32 fqid)
105826 +{
105827 + struct dpa_priv_s *dpa_priv = NULL;
105828 + struct fmt_port_s *fmt_port = NULL;
105829 + dma_addr_t addr = qm_fd_addr(fd);
105830 + void *fd_virt_addr = NULL;
105831 + uint32_t fd_len = 0;
105832 +
105833 + _fmt_dbgr("calling...\n");
105834 +
105835 + dpa_priv = netdev_priv(net_dev);
105836 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
105837 +
105838 + fd_virt_addr = phys_to_virt(addr);
105839 + fd_len = fd->length20 + fd->offset;
105840 +
105841 + if (fd_len > fm_get_max_frm()) {
105842 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
105843 + goto _priv_ingress_tx_err_continue;
105844 + }
105845 +
105846 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
105847 + goto _priv_ingress_tx_err_stolen;
105848 +
105849 +_priv_ingress_tx_err_continue:
105850 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
105851 + return DPAA_ETH_CONTINUE;
105852 +
105853 +_priv_ingress_tx_err_stolen:
105854 + kfree(fd_virt_addr);
105855 +
105856 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
105857 + return DPAA_ETH_STOLEN;
105858 +}
105859 +
105860 +/* egress callbacks definition */
105861 +enum qman_cb_dqrr_result fmt_egress_dqrr(
105862 + struct qman_portal *portal,
105863 + struct qman_fq *fq,
105864 + const struct qm_dqrr_entry *dqrr)
105865 +{
105866 + /* this callback should never be called */
105867 + BUG();
105868 + return qman_cb_dqrr_consume;
105869 +}
105870 +
105871 +static void fmt_egress_error_dqrr(
105872 + struct qman_portal *p,
105873 + struct qman_fq *fq,
105874 + const struct qm_mr_entry *msg)
105875 +{
105876 + uint8_t *fd_virt_addr = NULL;
105877 +
105878 + /* tx failure, on the ern callback - release buffer */
105879 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
105880 + kfree(fd_virt_addr);
105881 +
105882 + return;
105883 +}
105884 +
105885 +static const struct qman_fq fmt_egress_fq = {
105886 + .cb = { .dqrr = fmt_egress_dqrr,
105887 + .ern = fmt_egress_error_dqrr,
105888 + .fqs = NULL}
105889 +};
105890 +
105891 +int fmt_fq_alloc(
105892 + struct fmt_fqs_s *fmt_fqs,
105893 + const struct qman_fq *qman_fq,
105894 + uint32_t fqid, uint32_t flags,
105895 + uint16_t channel, uint8_t wq)
105896 +{
105897 + int _errno = 0;
105898 +
105899 + _fmt_dbg("calling...\n");
105900 +
105901 + fmt_fqs->fq_base = *qman_fq;
105902 +
105903 + if (fqid == 0) {
105904 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
105905 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
105906 + } else
105907 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
105908 +
105909 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
105910 +
105911 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
105912 + if (_errno < 0) {
105913 + _fmt_err("frame queues create failed.\n");
105914 + return -EINVAL;
105915 + }
105916 +
105917 + if (fmt_fqs->init) {
105918 + struct qm_mcc_initfq initfq;
105919 +
105920 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
105921 + initfq.fqd.dest.channel = channel;
105922 + initfq.fqd.dest.wq = wq;
105923 +
105924 + _errno = qman_init_fq(&fmt_fqs->fq_base,
105925 + QMAN_INITFQ_FLAG_SCHED,
105926 + &initfq);
105927 + if (_errno < 0) {
105928 + _fmt_err("frame queues init erorr.\n");
105929 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
105930 + return -EINVAL;
105931 + }
105932 + }
105933 +
105934 + _fmt_dbg("called.\n");
105935 + return 0;
105936 +}
105937 +
105938 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
105939 +{
105940 + int _err = 0;
105941 +
105942 + _fmt_dbg("calling...\n");
105943 +
105944 + if (fmt_fq->init) {
105945 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
105946 + if (unlikely(_err < 0))
105947 + _fmt_err("qman_retire_fq(%u) = %d\n",
105948 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105949 +
105950 + _err = qman_oos_fq(&fmt_fq->fq_base);
105951 + if (unlikely(_err < 0))
105952 + _fmt_err("qman_oos_fq(%u) = %d\n",
105953 + qman_fq_fqid(&fmt_fq->fq_base), _err);
105954 + }
105955 +
105956 + qman_destroy_fq(&fmt_fq->fq_base, 0);
105957 +
105958 + _fmt_dbg("called.\n");
105959 + return _err;
105960 +}
105961 +
105962 +/* private pcd dqrr calbacks */
105963 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
105964 + struct qman_portal *portal,
105965 + struct qman_fq *fq,
105966 + const struct qm_dqrr_entry *dq)
105967 +{
105968 + struct dpa_bp *dpa_bp = NULL;
105969 + dma_addr_t addr = qm_fd_addr(&dq->fd);
105970 + uint8_t *fd_virt_addr = NULL;
105971 + struct fmt_port_s *fmt_port;
105972 + struct fmt_port_pcd_s *fmt_port_pcd;
105973 + uint32_t relative_fqid = 0;
105974 + uint32_t fd_len = 0;
105975 +
105976 + _fmt_dbgr("calling...\n");
105977 +
105978 + /* upcast - from pcd_alloc_fq */
105979 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
105980 + if (!fmt_port) {
105981 + _fmt_err(" wrong fmt port -to- fq match.\n");
105982 + goto _fmt_pcd_dqrr_return;
105983 + }
105984 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
105985 +
105986 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
105987 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
105988 + relative_fqid, fmt_port_pcd->fqid_base);
105989 +
105990 + fd_len = dq->fd.length20 + dq->fd.offset;
105991 +
105992 + if (fd_len > fm_get_max_frm()) {
105993 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
105994 + fd_len, dq->fd.length20, dq->fd.offset);
105995 + goto _fmt_pcd_dqrr_return;
105996 + }
105997 +
105998 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
105999 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
106000 +
106001 + fd_virt_addr = phys_to_virt(addr);
106002 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
106003 + fd_len)) {
106004 +
106005 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106006 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
106007 +#endif
106008 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
106009 + " frame len: %u (dropped).\n",
106010 + dq->fqid, dq->fd.length20);
106011 + dump_frame(fd_virt_addr, fd_len);
106012 + }
106013 +
106014 +_fmt_pcd_dqrr_return:
106015 + /* no need to map again here */
106016 + fmt_fq_release(&dq->fd);
106017 +
106018 + _fmt_dbgr("calle.\n");
106019 + return qman_cb_dqrr_consume;
106020 +}
106021 +
106022 +static void fmt_pcd_err_dqrr(
106023 + struct qman_portal *qm,
106024 + struct qman_fq *fq,
106025 + const struct qm_mr_entry *msg)
106026 +{
106027 + _fmt_err("this callback should never be called.\n");
106028 + BUG();
106029 + return;
106030 +}
106031 +
106032 +static void fmt_pcd_fqs_dqrr(
106033 + struct qman_portal *qm,
106034 + struct qman_fq *fq,
106035 + const struct qm_mr_entry *msg)
106036 +{
106037 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
106038 + return;
106039 +}
106040 +
106041 +/* private pcd queue template */
106042 +static const struct qman_fq pcd_fq = {
106043 + .cb = { .dqrr = fmt_pcd_dqrr,
106044 + .ern = fmt_pcd_err_dqrr,
106045 + .fqs = fmt_pcd_fqs_dqrr}
106046 +};
106047 +
106048 +/* defined as weak in dpaa driver. */
106049 +/* ! parameters come from IOCTL call - US */
106050 +int dpa_alloc_pcd_fqids(
106051 + struct device *dev,
106052 + uint32_t num, uint8_t alignment,
106053 + uint32_t *base_fqid)
106054 +{
106055 + int _err = 0, i;
106056 + struct net_device *net_dev = NULL;
106057 + struct dpa_priv_s *dpa_priv = NULL;
106058 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106059 + struct fmt_fqs_s *fmt_fqs = NULL;
106060 + struct fmt_port_s *fmt_port = NULL;
106061 + int num_allocated = 0;
106062 +
106063 + _fmt_dbg("calling...\n");
106064 +
106065 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106066 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106067 +
106068 + if (!netif_msg_probe(dpa_priv)) {
106069 + _fmt_err("dpa not probe.\n");
106070 + _err = -ENODEV;
106071 + goto _pcd_alloc_fqs_err;
106072 + }
106073 +
106074 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106075 + if (!fmt_port) {
106076 + _fmt_err("fmt port not found.");
106077 + _err = -EINVAL;
106078 + goto _pcd_alloc_fqs_err;
106079 + }
106080 +
106081 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106082 +
106083 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
106084 +
106085 + if ((num_allocated <= 0) ||
106086 + (num_allocated < num) ||
106087 + (alignment && (*base_fqid) % alignment)) {
106088 + *base_fqid = 0;
106089 + _fmt_err("Failed to alloc pcd fqs rang.\n");
106090 + _err = -EINVAL;
106091 + goto _pcd_alloc_fqs_err;
106092 + }
106093 +
106094 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
106095 + num, alignment, num_allocated, *base_fqid);
106096 +
106097 + /* alloc pcd queues */
106098 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
106099 + sizeof(struct fmt_fqs_s),
106100 + GFP_KERNEL);
106101 + fmt_port_pcd->num_queues = num_allocated;
106102 + fmt_port_pcd->fqid_base = *base_fqid;
106103 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106104 +
106105 + /* alloc the pcd queues */
106106 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
106107 + _err = fmt_fq_alloc(
106108 + fmt_fqs,
106109 + &pcd_fq,
106110 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
106111 + dpa_priv->channel, 7);
106112 +
106113 + if (_err < 0)
106114 + goto _pcd_alloc_fqs_err;
106115 +
106116 + /* upcast to identify from where the frames came from */
106117 + fmt_fqs->fmt_port_priv = fmt_port;
106118 + }
106119 +
106120 + _fmt_dbg("called.\n");
106121 + return _err;
106122 +_pcd_alloc_fqs_err:
106123 + if (num_allocated > 0)
106124 + qman_release_fqid_range(*base_fqid, num_allocated);
106125 + /*TODO: free fmt_pcd_fqs if are any */
106126 +
106127 + _fmt_dbg("called(_err:%d).\n", _err);
106128 + return _err;
106129 +}
106130 +
106131 +/* defined as weak in dpaa driver. */
106132 +int dpa_free_pcd_fqids(
106133 + struct device *dev,
106134 + uint32_t base_fqid)
106135 +{
106136 +
106137 + int _err = 0, i;
106138 + struct net_device *net_dev = NULL;
106139 + struct dpa_priv_s *dpa_priv = NULL;
106140 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
106141 + struct fmt_fqs_s *fmt_fqs = NULL;
106142 + struct fmt_port_s *fmt_port = NULL;
106143 + int num_allocated = 0;
106144 +
106145 + _fmt_dbg("calling...\n");
106146 +
106147 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
106148 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
106149 +
106150 + if (!netif_msg_probe(dpa_priv)) {
106151 + _fmt_err("dpa not probe.\n");
106152 + _err = -ENODEV;
106153 + goto _pcd_free_fqs_err;
106154 + }
106155 +
106156 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
106157 + if (!fmt_port) {
106158 + _fmt_err("fmt port not found.");
106159 + _err = -EINVAL;
106160 + goto _pcd_free_fqs_err;
106161 + }
106162 +
106163 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
106164 + num_allocated = fmt_port_pcd->num_queues;
106165 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
106166 +
106167 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
106168 + fmt_fq_free(fmt_fqs);
106169 +
106170 + qman_release_fqid_range(base_fqid,num_allocated);
106171 +
106172 + kfree(fmt_port_pcd->fmt_pcd_fqs);
106173 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
106174 +
106175 + /* debugging stuff */
106176 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106177 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
106178 + _fmt_dbg(" frames enqueue to qman: %u.\n",
106179 + atomic_read(&fmt_port->enqueue_to_qman_frm));
106180 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
106181 + atomic_read(&fmt_port->enqueue_to_rxq));
106182 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
106183 + atomic_read(&fmt_port->dequeue_from_rxq));
106184 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
106185 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
106186 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106187 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106188 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106189 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106190 +#endif
106191 + return 0;
106192 +
106193 +_pcd_free_fqs_err:
106194 + return _err;
106195 +}
106196 +
106197 +static int fmt_port_init(
106198 + struct fmt_port_s *fmt_port,
106199 + ioc_fmt_port_param_t *p_Params)
106200 +{
106201 + struct device_node *fm_node, *fm_port_node;
106202 + const uint32_t *uint32_prop;
106203 + int _errno = 0, lenp = 0, i;
106204 + static struct of_device_id fm_node_of_match[] = {
106205 + { .compatible = "fsl,fman", },
106206 + { /* end of list */ },
106207 + };
106208 +
106209 + _fmt_dbg("calling...\n");
106210 +
106211 + /* init send/receive tu US list */
106212 + INIT_LIST_HEAD(&fmt_port->rx_q);
106213 +
106214 + /* check parameters */
106215 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
106216 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
106217 + _fmt_dbg("wrong test parameters.\n");
106218 + return -EINVAL;
106219 + }
106220 +
106221 + /* set port parameters */
106222 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
106223 + fmt_port->id = p_Params->fm_port_id;
106224 + fmt_port->port_type = p_Params->fm_port_type;
106225 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
106226 +
106227 + /* init debugging stuff */
106228 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106229 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
106230 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
106231 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
106232 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
106233 +#endif
106234 +
106235 + /* TODO: This should be done at probe time not at runtime
106236 + * very ugly function */
106237 + /* fill fmt port properties from dts */
106238 + for_each_matching_node(fm_node, fm_node_of_match) {
106239 +
106240 + uint32_prop = (uint32_t *)of_get_property(fm_node,
106241 + "cell-index", &lenp);
106242 + if (unlikely(uint32_prop == NULL)) {
106243 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106244 + fm_node->full_name);
106245 + return -EINVAL;
106246 + }
106247 + if (WARN_ON(lenp != sizeof(uint32_t))) {
106248 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
106249 + fm_node->full_name);
106250 + return -EINVAL;
106251 + }
106252 +
106253 + if (*uint32_prop == p_Params->fm_id) {
106254 + struct resource res;
106255 +
106256 + /* Get the FM address */
106257 + _errno = of_address_to_resource(fm_node, 0, &res);
106258 + if (unlikely(_errno < 0)) {
106259 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
106260 + return -EINVAL;
106261 + }
106262 +
106263 + fmt_port->fm_phys_base_addr = res.start;
106264 +
106265 + for_each_child_of_node(fm_node, fm_port_node) {
106266 + struct platform_device *of_dev;
106267 +
106268 + if (!of_device_is_available(fm_port_node))
106269 + continue;
106270 +
106271 + uint32_prop = (uint32_t *)of_get_property(
106272 + fm_port_node,
106273 + "cell-index",
106274 + &lenp);
106275 + if (uint32_prop == NULL)
106276 + continue;
106277 +
106278 + if (of_device_is_compatible(fm_port_node,
106279 + "fsl,fman-port-oh") &&
106280 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
106281 +
106282 + if (*uint32_prop == fmt_port->id) {
106283 + of_dev = of_find_device_by_node(fm_port_node);
106284 + if (unlikely(of_dev == NULL)) {
106285 + _fmt_wrn("fm id invalid\n");
106286 + return -EINVAL;
106287 + }
106288 +
106289 + fmt_port->p_tx_port =
106290 + fm_port_bind(&of_dev->dev);
106291 + fmt_port->p_tx_fm_port_dev =
106292 + (void *)fm_port_get_handle(
106293 + fmt_port->p_tx_port);
106294 + fmt_port->p_rx_port =
106295 + fmt_port->p_tx_port;
106296 + fmt_port->p_rx_fm_port_dev =
106297 + fmt_port->p_tx_fm_port_dev;
106298 + fmt_port->p_mac_dev = NULL;
106299 + break;
106300 + }
106301 + } else if ((*uint32_prop == fmt_port->id) &&
106302 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106303 +
106304 + of_dev = of_find_device_by_node(fm_port_node);
106305 + if (unlikely(of_dev == NULL)) {
106306 + _fmt_wrn("dtb fm id invalid value");
106307 + return -EINVAL;
106308 + }
106309 +
106310 + if (of_device_is_compatible(fm_port_node,
106311 + "fsl,fman-port-1g-tx")) {
106312 + fmt_port->p_tx_port =
106313 + fm_port_bind(&of_dev->dev);
106314 + fmt_port->p_tx_fm_port_dev = (void *)
106315 + fm_port_get_handle(
106316 + fmt_port->p_tx_port);
106317 + } else if (of_device_is_compatible(fm_port_node,
106318 + "fsl,fman-port-1g-rx")) {
106319 + fmt_port->p_rx_port =
106320 + fm_port_bind(&of_dev->dev);
106321 + fmt_port->p_rx_fm_port_dev = (void *)
106322 + fm_port_get_handle(
106323 + fmt_port->p_rx_port);
106324 + } else if (of_device_is_compatible(fm_port_node,
106325 + "fsl,fman-1g-mac") ||
106326 + of_device_is_compatible(fm_port_node,
106327 + "fsl,fman-memac"))
106328 + fmt_port->p_mac_dev =
106329 + (typeof(fmt_port->p_mac_dev))
106330 + dev_get_drvdata(&of_dev->dev);
106331 + else
106332 + continue;
106333 +
106334 + if (fmt_port->p_tx_fm_port_dev &&
106335 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106336 + break;
106337 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
106338 + fmt_port->id) &&
106339 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
106340 +
106341 + of_dev = of_find_device_by_node(fm_port_node);
106342 + if (unlikely(of_dev == NULL)) {
106343 + _fmt_wrn("dtb fm id invalid value\n");
106344 + return -EINVAL;
106345 + }
106346 +
106347 + if (of_device_is_compatible(fm_port_node,
106348 + "fsl,fman-port-10g-tx")) {
106349 + fmt_port->p_tx_port =
106350 + fm_port_bind(&of_dev->dev);
106351 + fmt_port->p_tx_fm_port_dev = (void *)
106352 + fm_port_get_handle(
106353 + fmt_port->p_tx_port);
106354 + } else if (of_device_is_compatible(fm_port_node,
106355 + "fsl,fman-port-10g-rx")) {
106356 + fmt_port->p_rx_port =
106357 + fm_port_bind(&of_dev->dev);
106358 + fmt_port->p_rx_fm_port_dev = (void *)
106359 + fm_port_get_handle(
106360 + fmt_port->p_rx_port);
106361 + } else if (of_device_is_compatible(fm_port_node,
106362 + "fsl,fman-10g-mac") ||
106363 + of_device_is_compatible(fm_port_node,
106364 + "fsl,fman-memac"))
106365 + fmt_port->p_mac_dev =
106366 + (typeof(fmt_port->p_mac_dev))
106367 + dev_get_drvdata(&of_dev->dev);
106368 + else
106369 + continue;
106370 +
106371 + if (fmt_port->p_tx_fm_port_dev &&
106372 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
106373 + break;
106374 + }
106375 + } /* for_each_child */
106376 + }
106377 + } /* for each matching node */
106378 +
106379 + if (fmt_port->p_tx_fm_port_dev == 0 ||
106380 + fmt_port->p_rx_fm_port_dev == 0) {
106381 +
106382 + _fmt_err("bad fm port pointers.\n");
106383 + return -EINVAL;
106384 + }
106385 +
106386 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
106387 +
106388 + /* init fman test egress dynamic frame queues */
106389 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
106390 + int _errno;
106391 + _errno = fmt_fq_alloc(
106392 + &fmt_port->p_tx_fqs[i],
106393 + &fmt_egress_fq,
106394 + 0,
106395 + QMAN_FQ_FLAG_TO_DCPORTAL,
106396 + fm_get_tx_port_channel(fmt_port->p_tx_port),
106397 + i);
106398 +
106399 + if (_errno < 0) {
106400 + _fmt_err("tx queues allocation failed.\n");
106401 + /* TODO: memory leak here if 1 queue is allocated and
106402 + * next queues are failing ... */
106403 + return -EINVAL;
106404 + }
106405 + }
106406 +
106407 + /* port is valid and ready to use. */
106408 + fmt_port->valid = TRUE;
106409 +
106410 + _fmt_dbg("called.\n");
106411 + return 0;
106412 +}
106413 +
106414 +/* fm test chardev functions */
106415 +static int fmt_open(struct inode *inode, struct file *file)
106416 +{
106417 + unsigned int minor = iminor(inode);
106418 +
106419 + _fmt_dbg("calling...\n");
106420 +
106421 + if (file->private_data != NULL)
106422 + return 0;
106423 +
106424 + /* The minor represent the port number.
106425 + * Set the port structure accordingly, thus all the operations
106426 + * will be done on this port. */
106427 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
106428 + (minor < DEV_FM_TEST_MAX_MINORS))
106429 + file->private_data = &fm_test.ports[minor];
106430 + else
106431 + return -ENXIO;
106432 +
106433 + _fmt_dbg("called.\n");
106434 + return 0;
106435 +}
106436 +
106437 +static int fmt_close(struct inode *inode, struct file *file)
106438 +{
106439 + struct fmt_port_s *fmt_port = NULL;
106440 + struct fmt_frame_s *fmt_frame = NULL;
106441 +
106442 + int err = 0;
106443 +
106444 + _fmt_dbg("calling...\n");
106445 +
106446 + fmt_port = file->private_data;
106447 + if (!fmt_port)
106448 + return -ENODEV;
106449 +
106450 + /* Close the current test port by invalidating it. */
106451 + fmt_port->valid = FALSE;
106452 +
106453 + /* clean the fmt port queue */
106454 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
106455 + if (fmt_frame && fmt_frame->buff.p_data){
106456 + kfree(fmt_frame->buff.p_data);
106457 + kfree(fmt_frame);
106458 + }
106459 + }
106460 +
106461 + /* !!! the qman queues are cleaning from fm_ioctl...
106462 + * - very ugly */
106463 +
106464 + _fmt_dbg("called.\n");
106465 + return err;
106466 +}
106467 +
106468 +static int fmt_ioctls(unsigned int minor,
106469 + struct file *file,
106470 + unsigned int cmd,
106471 + unsigned long arg,
106472 + bool compat)
106473 +{
106474 + struct fmt_port_s *fmt_port = NULL;
106475 +
106476 + _fmt_dbg("IOCTL minor:%u "
106477 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
106478 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106479 +
106480 + fmt_port = file->private_data;
106481 + if (!fmt_port) {
106482 + _fmt_err("invalid fmt port.\n");
106483 + return -ENODEV;
106484 + }
106485 +
106486 + /* set test type properly */
106487 + if (compat)
106488 + fmt_port->compat_test_type = true;
106489 + else
106490 + fmt_port->compat_test_type = false;
106491 +
106492 + switch (cmd) {
106493 + case FMT_PORT_IOC_INIT:
106494 + {
106495 + ioc_fmt_port_param_t param;
106496 +
106497 + if (fmt_port->valid) {
106498 + _fmt_wrn("port is already initialized.\n");
106499 + return -EFAULT;
106500 + }
106501 +#if defined(CONFIG_COMPAT)
106502 + if (compat) {
106503 + if (copy_from_user(&param,
106504 + (ioc_fmt_port_param_t *)compat_ptr(arg),
106505 + sizeof(ioc_fmt_port_param_t)))
106506 +
106507 + return -EFAULT;
106508 + } else
106509 +#endif
106510 + {
106511 + if (copy_from_user(&param,
106512 + (ioc_fmt_port_param_t *) arg,
106513 + sizeof(ioc_fmt_port_param_t)))
106514 +
106515 + return -EFAULT;
106516 + }
106517 +
106518 + return fmt_port_init(fmt_port, &param);
106519 + }
106520 +
106521 + case FMT_PORT_IOC_SET_DIAG_MODE:
106522 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
106523 + return -EFAULT;
106524 +
106525 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
106526 + return set_mac_int_loopback(fmt_port, TRUE);
106527 + else
106528 + return set_mac_int_loopback(fmt_port, FALSE);
106529 + break;
106530 +
106531 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
106532 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
106533 + default:
106534 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
106535 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
106536 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
106537 + return -EFAULT;
106538 + }
106539 +
106540 + return 0;
106541 +}
106542 +
106543 +#ifdef CONFIG_COMPAT
106544 +static long fmt_compat_ioctl(
106545 + struct file *file,
106546 + unsigned int cmd,
106547 + unsigned long arg)
106548 +{
106549 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106550 +
106551 + _fmt_dbg("calling...\n");
106552 + return fmt_ioctls(minor, file, cmd, arg, true);
106553 +}
106554 +#endif
106555 +
106556 +static long fmt_ioctl(
106557 + struct file *file,
106558 + unsigned int cmd,
106559 + unsigned long arg)
106560 +{
106561 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
106562 + unsigned int res;
106563 +
106564 + _fmt_dbg("calling...\n");
106565 +
106566 + fm_mutex_lock();
106567 + res = fmt_ioctls(minor, file, cmd, arg, false);
106568 + fm_mutex_unlock();
106569 +
106570 + _fmt_dbg("called.\n");
106571 +
106572 + return res;
106573 +}
106574 +
106575 +#ifdef CONFIG_COMPAT
106576 +void copy_compat_test_frame_buffer(
106577 + ioc_fmt_buff_desc_t *buff,
106578 + ioc_fmt_compat_buff_desc_t *compat_buff)
106579 +{
106580 + compat_buff->qid = buff->qid;
106581 + compat_buff->p_data = ptr_to_compat(buff->p_data);
106582 + compat_buff->size = buff->size;
106583 + compat_buff->status = buff->status;
106584 +
106585 + compat_buff->buff_context.p_user_priv =
106586 + ptr_to_compat(buff->buff_context.p_user_priv);
106587 + memcpy(compat_buff->buff_context.fm_prs_res,
106588 + buff->buff_context.fm_prs_res,
106589 + FM_PRS_MAX * sizeof(uint8_t));
106590 + memcpy(compat_buff->buff_context.fm_time_stamp,
106591 + buff->buff_context.fm_time_stamp,
106592 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106593 +}
106594 +#endif
106595 +
106596 +ssize_t fmt_read(
106597 + struct file *file,
106598 + char __user *buf,
106599 + size_t size,
106600 + loff_t *ppos)
106601 +{
106602 + struct fmt_port_s *fmt_port = NULL;
106603 + struct fmt_frame_s *p_fmt_frame = NULL;
106604 + ssize_t cnt = 0;
106605 +
106606 + fmt_port = file->private_data;
106607 + if (!fmt_port || !fmt_port->valid) {
106608 + _fmt_err("fmt port not valid!\n");
106609 + return -ENODEV;
106610 + }
106611 +
106612 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
106613 + if (p_fmt_frame == NULL)
106614 + return 0;
106615 +
106616 + _fmt_dbgr("calling...\n");
106617 +
106618 +#ifdef CONFIG_COMPAT
106619 + if (fmt_port->compat_test_type){
106620 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
106621 + }
106622 + else
106623 +#endif
106624 + {
106625 + cnt = sizeof(ioc_fmt_buff_desc_t);
106626 + }
106627 +
106628 + if (size < cnt) {
106629 + _fmt_err("illegal buffer-size!\n");
106630 + cnt = 0;
106631 + goto _fmt_read_return;
106632 + }
106633 +
106634 + /* Copy structure */
106635 +#ifdef CONFIG_COMPAT
106636 + if (fmt_port->compat_test_type) {
106637 + {
106638 + ioc_fmt_compat_buff_desc_t compat_buff;
106639 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
106640 + &compat_buff);
106641 +
106642 + if (copy_to_user(buf, &compat_buff, cnt)) {
106643 + _fmt_err("copy_to_user failed!\n");
106644 + goto _fmt_read_return;
106645 + }
106646 + }
106647 +
106648 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
106649 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
106650 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106651 + } else
106652 +#endif
106653 + {
106654 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
106655 + _fmt_err("copy_to_user failed!\n");
106656 + goto _fmt_read_return;
106657 + }
106658 +
106659 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
106660 + buf + sizeof(ioc_fmt_buff_desc_t);
106661 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
106662 + }
106663 +
106664 + if (size < cnt) {
106665 + _fmt_err("illegal buffer-size!\n");
106666 + goto _fmt_read_return;
106667 + }
106668 +
106669 + /* copy frame */
106670 +#ifdef CONFIG_COMPAT
106671 + if (fmt_port->compat_test_type) {
106672 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
106673 + p_fmt_frame->buff.p_data, cnt)) {
106674 + _fmt_err("copy_to_user failed!\n");
106675 + goto _fmt_read_return;
106676 + }
106677 + } else
106678 +#endif
106679 + {
106680 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
106681 + p_fmt_frame->buff.p_data, cnt)) {
106682 + _fmt_err("copy_to_user failed!\n");
106683 + goto _fmt_read_return;
106684 + }
106685 + }
106686 +
106687 +_fmt_read_return:
106688 + kfree(p_fmt_frame->buff.p_data);
106689 + kfree(p_fmt_frame);
106690 +
106691 + _fmt_dbgr("called.\n");
106692 + return cnt;
106693 +}
106694 +
106695 +ssize_t fmt_write(
106696 + struct file *file,
106697 + const char __user *buf,
106698 + size_t size,
106699 + loff_t *ppos)
106700 +{
106701 + struct fmt_port_s *fmt_port = NULL;
106702 + ioc_fmt_buff_desc_t buff_desc;
106703 +#ifdef CONFIG_COMPAT
106704 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
106705 +#endif
106706 + uint8_t *p_data = NULL;
106707 + uint32_t data_offset;
106708 + int _errno;
106709 + t_DpaaFD fd;
106710 +
106711 + _fmt_dbgr("calling...\n");
106712 +
106713 + fmt_port = file->private_data;
106714 + if (!fmt_port || !fmt_port->valid) {
106715 + _fmt_err("fmt port not valid.\n");
106716 + return -EINVAL;
106717 + }
106718 +
106719 + /* If Compat (32B UserSpace - 64B KernelSpace) */
106720 +#ifdef CONFIG_COMPAT
106721 + if (fmt_port->compat_test_type) {
106722 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
106723 + _fmt_err("invalid buff_desc size.\n");
106724 + return -EFAULT;
106725 + }
106726 +
106727 + if (copy_from_user(&buff_desc_compat, buf,
106728 + sizeof(ioc_fmt_compat_buff_desc_t)))
106729 + return -EFAULT;
106730 +
106731 + buff_desc.qid = buff_desc_compat.qid;
106732 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
106733 + buff_desc.size = buff_desc_compat.size;
106734 + buff_desc.status = buff_desc_compat.status;
106735 +
106736 + buff_desc.buff_context.p_user_priv =
106737 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
106738 + memcpy(buff_desc.buff_context.fm_prs_res,
106739 + buff_desc_compat.buff_context.fm_prs_res,
106740 + FM_PRS_MAX * sizeof(uint8_t));
106741 + memcpy(buff_desc.buff_context.fm_time_stamp,
106742 + buff_desc_compat.buff_context.fm_time_stamp,
106743 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
106744 + } else
106745 +#endif
106746 + {
106747 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
106748 + _fmt_err("invalid buff_desc size.\n");
106749 + return -EFAULT;
106750 + }
106751 +
106752 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
106753 + sizeof(ioc_fmt_buff_desc_t)))
106754 + return -EFAULT;
106755 + }
106756 +
106757 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
106758 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
106759 + if (!p_data)
106760 + return -ENOMEM;
106761 +
106762 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
106763 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
106764 + buff_desc.p_data,
106765 + buff_desc.size)) {
106766 + kfree(p_data);
106767 + return -EFAULT;
106768 + }
106769 +
106770 + /* TODO: dma_map_single here (cannot access the bpool struct) */
106771 +
106772 + /* prepare fd */
106773 + memset(&fd, 0, sizeof(fd));
106774 + DPAA_FD_SET_ADDR(&fd, p_data);
106775 + DPAA_FD_SET_OFFSET(&fd, data_offset);
106776 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
106777 +
106778 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
106779 + (struct qm_fd *)&fd, 0);
106780 + if (_errno) {
106781 + buff_desc.status = (uint32_t)_errno;
106782 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
106783 + sizeof(ioc_fmt_buff_desc_t))) {
106784 + kfree(p_data);
106785 + return -EFAULT;
106786 + }
106787 + }
106788 +
106789 + /* for debugging */
106790 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
106791 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
106792 +#endif
106793 + _fmt_dbgr("called.\n");
106794 + return buff_desc.size;
106795 +}
106796 +
106797 +/* fm test character device definition */
106798 +static const struct file_operations fmt_fops =
106799 +{
106800 + .owner = THIS_MODULE,
106801 +#ifdef CONFIG_COMPAT
106802 + .compat_ioctl = fmt_compat_ioctl,
106803 +#endif
106804 + .unlocked_ioctl = fmt_ioctl,
106805 + .open = fmt_open,
106806 + .release = fmt_close,
106807 + .read = fmt_read,
106808 + .write = fmt_write,
106809 +};
106810 +
106811 +static int fmt_init(void)
106812 +{
106813 + int id;
106814 +
106815 + _fmt_dbg("calling...\n");
106816 +
106817 + /* Register to the /dev for IOCTL API */
106818 + /* Register dynamically a new major number for the character device: */
106819 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
106820 + if (fm_test.major <= 0) {
106821 + _fmt_wrn("Failed to allocate major number for device %s.\n",
106822 + DEV_FM_TEST_NAME);
106823 + return -ENODEV;
106824 + }
106825 +
106826 + /* Creating class for FMan_test */
106827 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
106828 + if (IS_ERR(fm_test.fmt_class)) {
106829 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
106830 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
106831 + return -ENODEV;
106832 + }
106833 +
106834 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106835 + if (NULL == device_create(fm_test.fmt_class, NULL,
106836 + MKDEV(fm_test.major,
106837 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
106838 + DEV_FM_TEST_NAME "%d", id)) {
106839 +
106840 + _fmt_err("Error creating %s device.\n",
106841 + DEV_FM_TEST_NAME);
106842 + return -ENODEV;
106843 + }
106844 +
106845 + return 0;
106846 +}
106847 +
106848 +static void fmt_free(void)
106849 +{
106850 + int id;
106851 +
106852 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
106853 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
106854 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
106855 + class_destroy(fm_test.fmt_class);
106856 +}
106857 +
106858 +static int __init __cold fmt_load(void)
106859 +{
106860 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
106861 +
106862 + /* set dpaa hooks for default queues */
106863 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
106864 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
106865 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
106866 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
106867 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
106868 +
106869 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
106870 +
106871 + /* initialize the fman test environment */
106872 + if (fmt_init() < 0) {
106873 + _fmt_err("Failed to init FM-test modul.\n");
106874 + fmt_free();
106875 + return -ENODEV;
106876 + }
106877 +
106878 + _fmt_inf("FSL FM test module loaded.\n");
106879 +
106880 + return 0;
106881 +}
106882 +
106883 +static void __exit __cold fmt_unload(void)
106884 +{
106885 + fmt_free();
106886 + _fmt_inf("FSL FM test module unloaded.\n");
106887 +}
106888 +
106889 +module_init(fmt_load);
106890 +module_exit(fmt_unload);
106891 --- /dev/null
106892 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
106893 @@ -0,0 +1,2908 @@
106894 +/*
106895 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106896 + *
106897 + * Redistribution and use in source and binary forms, with or without
106898 + * modification, are permitted provided that the following conditions are met:
106899 + * * Redistributions of source code must retain the above copyright
106900 + * notice, this list of conditions and the following disclaimer.
106901 + * * Redistributions in binary form must reproduce the above copyright
106902 + * notice, this list of conditions and the following disclaimer in the
106903 + * documentation and/or other materials provided with the distribution.
106904 + * * Neither the name of Freescale Semiconductor nor the
106905 + * names of its contributors may be used to endorse or promote products
106906 + * derived from this software without specific prior written permission.
106907 + *
106908 + *
106909 + * ALTERNATIVELY, this software may be distributed under the terms of the
106910 + * GNU General Public License ("GPL") as published by the Free Software
106911 + * Foundation, either version 2 of that License or (at your option) any
106912 + * later version.
106913 + *
106914 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106915 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106916 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106917 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106918 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106919 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106920 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106921 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106922 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106923 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106924 + */
106925 +
106926 +/*
106927 + @File lnxwrp_fm.c
106928 + @Author Shlomi Gridish
106929 + @Description FM Linux wrapper functions.
106930 +*/
106931 +
106932 +#include <linux/version.h>
106933 +#include <linux/slab.h>
106934 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106935 +#define MODVERSIONS
106936 +#endif
106937 +#ifdef MODVERSIONS
106938 +#include <config/modversions.h>
106939 +#endif /* MODVERSIONS */
106940 +#include <linux/kernel.h>
106941 +#include <linux/module.h>
106942 +#include <linux/fs.h>
106943 +#include <linux/cdev.h>
106944 +#include <linux/device.h>
106945 +#include <linux/irq.h>
106946 +#include <linux/interrupt.h>
106947 +#include <linux/io.h>
106948 +#include <linux/ioport.h>
106949 +#include <linux/of_platform.h>
106950 +#include <linux/of_address.h>
106951 +#include <linux/of_irq.h>
106952 +#include <linux/clk.h>
106953 +#include <asm/uaccess.h>
106954 +#include <asm/errno.h>
106955 +#ifndef CONFIG_FMAN_ARM
106956 +#include <sysdev/fsl_soc.h>
106957 +#include <linux/fsl/guts.h>
106958 +#include <linux/fsl/svr.h>
106959 +#endif
106960 +#include <linux/stat.h> /* For file access mask */
106961 +#include <linux/skbuff.h>
106962 +#include <linux/proc_fs.h>
106963 +
106964 +/* NetCommSw Headers --------------- */
106965 +#include "std_ext.h"
106966 +#include "error_ext.h"
106967 +#include "sprint_ext.h"
106968 +#include "debug_ext.h"
106969 +#include "sys_io_ext.h"
106970 +
106971 +#include "fm_ioctls.h"
106972 +
106973 +#include "lnxwrp_fm.h"
106974 +#include "lnxwrp_resources.h"
106975 +#include "lnxwrp_sysfs_fm.h"
106976 +#include "lnxwrp_sysfs_fm_port.h"
106977 +#include "lnxwrp_exp_sym.h"
106978 +#include "fm_common.h"
106979 +#include "../../sdk_fman/Peripherals/FM/fm.h"
106980 +#define __ERR_MODULE__ MODULE_FM
106981 +
106982 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
106983 + e_FmPortType portType,
106984 + uint8_t portId);
106985 +
106986 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
106987 +
106988 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
106989 + do { \
106990 + if (i<max){ \
106991 + p_Entry = &p_Entrys[i]; \
106992 + p_Entry->p_Function = _func; \
106993 + _param \
106994 + i++; \
106995 + } \
106996 + else \
106997 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
106998 + ("Number of advanced-configuration entries exceeded"));\
106999 + } while (0)
107000 +
107001 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
107002 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
107003 +
107004 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
107005 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
107006 +
107007 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
107008 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
107009 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
107010 +
107011 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
107012 +#define FSL_FM_PAUSE_TIME_DISABLE 0
107013 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
107014 +
107015 +/*
107016 + * Max frame size, across all interfaces.
107017 + * Configurable from Kconfig or bootargs, to avoid allocating
107018 + * oversized (socket) buffers when not using jumbo frames.
107019 + * Must be large enough to accommodate the network MTU, but small enough
107020 + * to avoid wasting skb memory.
107021 + *
107022 + * Could be overridden once, at boot-time, via the
107023 + * fm_set_max_frm() callback.
107024 + */
107025 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107026 +
107027 +/*
107028 + * Extra headroom for Rx buffers.
107029 + * FMan is instructed to allocate, on the Rx path, this amount of
107030 + * space at the beginning of a data buffer, beside the DPA private
107031 + * data area and the IC fields.
107032 + * Does not impact Tx buffer layout.
107033 + *
107034 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
107035 + * on particular forwarding scenarios that add extra headers to the
107036 + * forwarded frame.
107037 + */
107038 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107039 +
107040 +#ifdef CONFIG_FMAN_PFC
107041 +static int fsl_fm_pfc_quanta[] = {
107042 + CONFIG_FMAN_PFC_QUANTA_0,
107043 + CONFIG_FMAN_PFC_QUANTA_1,
107044 + CONFIG_FMAN_PFC_QUANTA_2,
107045 + CONFIG_FMAN_PFC_QUANTA_3
107046 +};
107047 +#endif
107048 +
107049 +static t_LnxWrpFm lnxWrpFm;
107050 +
107051 +int fm_get_max_frm()
107052 +{
107053 + return fsl_fm_max_frm;
107054 +}
107055 +EXPORT_SYMBOL(fm_get_max_frm);
107056 +
107057 +int fm_get_rx_extra_headroom()
107058 +{
107059 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
107060 +}
107061 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
107062 +
107063 +static int __init fm_set_max_frm(char *str)
107064 +{
107065 + int ret = 0;
107066 +
107067 + ret = get_option(&str, &fsl_fm_max_frm);
107068 + if (ret != 1) {
107069 + /*
107070 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
107071 + * and something like "earlyprintk=serial,uart0,115200" is
107072 + * specified in the bootargs
107073 + */
107074 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107075 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
107076 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
107077 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107078 +
107079 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107080 + return 1;
107081 + }
107082 +
107083 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
107084 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
107085 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
107086 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
107087 + "from Kconfig.\n",
107088 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
107089 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
107090 +
107091 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
107092 + return 1;
107093 + }
107094 +
107095 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
107096 + fsl_fm_max_frm);
107097 + return 0;
107098 +}
107099 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
107100 +
107101 +static int __init fm_set_rx_extra_headroom(char *str)
107102 +{
107103 + int ret;
107104 +
107105 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
107106 +
107107 + if (ret != 1) {
107108 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
107109 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
107110 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107111 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107112 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107113 +
107114 + return 1;
107115 + }
107116 +
107117 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
107118 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
107119 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
107120 + "bootargs; will use the default "
107121 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
107122 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
107123 + fsl_fm_rx_extra_headroom,
107124 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
107125 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
107126 + }
107127 +
107128 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
107129 + fsl_fm_rx_extra_headroom);
107130 +
107131 + return 0;
107132 +}
107133 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
107134 +
107135 +static irqreturn_t fm_irq(int irq, void *_dev)
107136 +{
107137 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107138 +#ifdef CONFIG_PM_SLEEP
107139 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
107140 +#endif
107141 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107142 + return IRQ_NONE;
107143 +
107144 +#ifdef CONFIG_PM_SLEEP
107145 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
107146 + {
107147 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
107148 + }
107149 +#endif
107150 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
107151 + return IRQ_HANDLED;
107152 +}
107153 +
107154 +static irqreturn_t fm_err_irq(int irq, void *_dev)
107155 +{
107156 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
107157 +
107158 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
107159 + return IRQ_NONE;
107160 +
107161 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
107162 + return IRQ_HANDLED;
107163 +
107164 + return IRQ_NONE;
107165 +}
107166 +
107167 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
107168 +static struct mutex lnxwrp_mutex;
107169 +
107170 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
107171 +{
107172 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107173 + int j;
107174 +
107175 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
107176 + if (!p_LnxWrpFmDev)
107177 + {
107178 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
107179 + return NULL;
107180 + }
107181 +
107182 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
107183 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107184 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107185 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107186 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107187 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107188 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107189 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107190 + {
107191 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107192 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107193 + }
107194 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107195 + {
107196 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107197 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107198 + }
107199 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107200 + {
107201 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
107202 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
107203 + }
107204 +
107205 + return p_LnxWrpFmDev;
107206 +}
107207 +
107208 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107209 +{
107210 + int j;
107211 +
107212 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
107213 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
107214 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
107215 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
107216 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
107217 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
107218 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
107219 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
107220 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
107221 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
107222 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
107223 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
107224 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
107225 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
107226 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
107227 +
107228 + XX_Free(p_LnxWrpFmDev);
107229 +}
107230 +
107231 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
107232 +{
107233 +#define FM_BMI_PPIDS_OFFSET 0x00080304
107234 +#define FM_DMA_PLR_OFFSET 0x000c2060
107235 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
107236 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
107237 +#define DMA_LOW_LIODN_MASK 0x00000FFF
107238 +#define DMA_LIODN_SHIFT 16
107239 +
107240 +typedef _Packed struct {
107241 + uint32_t plr[32];
107242 +} _PackedType t_Plr;
107243 +
107244 +typedef _Packed struct {
107245 + volatile uint32_t fmbm_ppid[63];
107246 +} _PackedType t_Ppids;
107247 +
107248 + t_Plr *p_Plr;
107249 + t_Ppids *p_Ppids;
107250 + int i,j;
107251 + uint32_t fmRev;
107252 +
107253 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
107254 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
107255 +#if (DPAA_VERSION >= 11)
107256 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
107257 +#else
107258 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
107259 +#endif
107260 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
107261 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
107262 +
107263 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
107264 + fmRev &= 0xffff;
107265 +
107266 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
107267 +#ifdef MODULE
107268 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
107269 + p_Plr->plr[i] = 0;
107270 +#endif /* MODULE */
107271 +
107272 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
107273 + {
107274 + uint16_t liodnBase = (uint16_t)((i%2) ?
107275 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
107276 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
107277 +#ifdef FM_PARTITION_ARRAY
107278 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
107279 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
107280 +#endif /* FM_PARTITION_ARRAY */
107281 +
107282 + if ((i >= phys1GRxPortId[0]) &&
107283 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
107284 + {
107285 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
107286 + if (phys1GRxPortId[j] == i)
107287 + break;
107288 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
107289 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
107290 + }
107291 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
107292 + (i >= phys10GRxPortId[0]) &&
107293 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
107294 + {
107295 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
107296 + if (phys10GRxPortId[j] == i)
107297 + break;
107298 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
107299 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
107300 + }
107301 + else if ((i >= physOhPortId[0]) &&
107302 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
107303 + {
107304 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
107305 + if (physOhPortId[j] == i)
107306 + break;
107307 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
107308 + if (j == 0)
107309 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
107310 + else
107311 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
107312 + }
107313 + else if ((i >= phys1GTxPortId[0]) &&
107314 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
107315 + {
107316 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
107317 + if (phys1GTxPortId[j] == i)
107318 + break;
107319 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
107320 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
107321 + }
107322 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
107323 + (i >= phys10GTxPortId[0]) &&
107324 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
107325 + {
107326 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
107327 + if (phys10GTxPortId[j] == i)
107328 + break;
107329 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
107330 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
107331 + }
107332 + }
107333 +
107334 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
107335 +
107336 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
107337 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
107338 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
107339 +
107340 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
107341 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
107342 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
107343 +
107344 + return E_OK;
107345 +}
107346 +
107347 +/* Structure that defines QE firmware binary files.
107348 + *
107349 + * See Documentation/powerpc/qe_firmware.txt for a description of these
107350 + * fields.
107351 + */
107352 +struct qe_firmware {
107353 + struct qe_header {
107354 + __be32 length; /* Length of the entire structure, in bytes */
107355 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
107356 + u8 version; /* Version of this layout. First ver is '1' */
107357 + } header;
107358 + u8 id[62]; /* Null-terminated identifier string */
107359 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
107360 + u8 count; /* Number of microcode[] structures */
107361 + struct {
107362 + __be16 model; /* The SOC model */
107363 + u8 major; /* The SOC revision major */
107364 + u8 minor; /* The SOC revision minor */
107365 + } __attribute__ ((packed)) soc;
107366 + u8 padding[4]; /* Reserved, for alignment */
107367 + __be64 extended_modes; /* Extended modes */
107368 + __be32 vtraps[8]; /* Virtual trap addresses */
107369 + u8 reserved[4]; /* Reserved, for future expansion */
107370 + struct qe_microcode {
107371 + u8 id[32]; /* Null-terminated identifier */
107372 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
107373 + __be32 eccr; /* The value for the ECCR register */
107374 + __be32 iram_offset; /* Offset into I-RAM for the code */
107375 + __be32 count; /* Number of 32-bit words of the code */
107376 + __be32 code_offset; /* Offset of the actual microcode */
107377 + u8 major; /* The microcode version major */
107378 + u8 minor; /* The microcode version minor */
107379 + u8 revision; /* The microcode version revision */
107380 + u8 padding; /* Reserved, for alignment */
107381 + u8 reserved[4]; /* Reserved, for future expansion */
107382 + } __attribute__ ((packed)) microcode[1];
107383 + /* All microcode binaries should be located here */
107384 + /* CRC32 should be located here, after the microcode binaries */
107385 +} __attribute__ ((packed));
107386 +
107387 +
107388 +/**
107389 + * FindFmanMicrocode - find the Fman microcode
107390 + *
107391 + * This function returns a pointer to the QE Firmware blob that holds
107392 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
107393 + * is similar to QE microcode, so there's no point in defining a new layout.
107394 + *
107395 + * Current versions of U-Boot embed the Fman firmware into the device tree,
107396 + * so we check for that first. Each Fman node in the device tree contains a
107397 + * node or a pointer to node that holds the firmware. Technically, we should
107398 + * be fetching the firmware node for the current Fman, but we don't have that
107399 + * information any more, so we assume that there is only one firmware node in
107400 + * the device tree, and that all Fmen use the same firmware.
107401 + */
107402 +static const struct qe_firmware *FindFmanMicrocode(void)
107403 +{
107404 + static const struct qe_firmware *P4080_UCPatch;
107405 + struct device_node *np;
107406 +
107407 + if (P4080_UCPatch)
107408 + return P4080_UCPatch;
107409 +
107410 + /* The firmware should be inside the device tree. */
107411 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
107412 + if (np) {
107413 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
107414 + of_node_put(np);
107415 + if (P4080_UCPatch)
107416 + return P4080_UCPatch;
107417 + else
107418 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
107419 + }
107420 +
107421 + /* Returning NULL here forces the reuse of the IRAM content */
107422 + return NULL;
107423 +}
107424 +#define SVR_SECURITY_MASK 0x00080000
107425 +#define SVR_PERSONALITY_MASK 0x0000FF00
107426 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
107427 +#define SVR_B4860_REV1_VALUE 0x86800010
107428 +#define SVR_B4860_REV2_VALUE 0x86800020
107429 +#define SVR_T4240_VALUE 0x82400000
107430 +#define SVR_T4120_VALUE 0x82400100
107431 +#define SVR_T4160_VALUE 0x82410000
107432 +#define SVR_T4080_VALUE 0x82410200
107433 +#define SVR_T4_DEVICE_ID 0x82400000
107434 +#define SVR_DEVICE_ID_MASK 0xFFF00000
107435 +
107436 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
107437 +
107438 +/* searches for a subnode with the given name/compatible */
107439 +static bool HasFmPcdOfNode(struct device_node *fm_node,
107440 + struct of_device_id *ids,
107441 + const char *name,
107442 + const char *compatible)
107443 +{
107444 + struct device_node *dev_node;
107445 + bool ret = false;
107446 +
107447 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
107448 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
107449 + return false;
107450 + strcpy(ids[0].name, name);
107451 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
107452 + return false;
107453 + strcpy(ids[0].compatible, compatible);
107454 + for_each_child_of_node(fm_node, dev_node)
107455 + if (of_match_node(ids, dev_node) != NULL)
107456 + ret = true;
107457 + return ret;
107458 +}
107459 +
107460 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
107461 +{
107462 + t_LnxWrpFmDev *p_LnxWrpFmDev;
107463 + struct device_node *fm_node, *dev_node;
107464 + struct of_device_id ids[OF_DEV_ID_NUM];
107465 + struct resource res;
107466 + struct clk *clk;
107467 + u32 clk_rate;
107468 + const uint32_t *uint32_prop;
107469 + int _errno=0, lenp;
107470 + uint32_t tmp_prop;
107471 +
107472 + fm_node = of_node_get(of_dev->dev.of_node);
107473 +
107474 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
107475 + if (unlikely(uint32_prop == NULL)) {
107476 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
107477 + return NULL;
107478 + }
107479 + tmp_prop = be32_to_cpu(*uint32_prop);
107480 +
107481 + if (WARN_ON(lenp != sizeof(uint32_t)))
107482 + return NULL;
107483 +
107484 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107485 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107486 + return NULL;
107487 + }
107488 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
107489 + if (!p_LnxWrpFmDev) {
107490 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
107491 + return NULL;
107492 + }
107493 + p_LnxWrpFmDev->dev = &of_dev->dev;
107494 + p_LnxWrpFmDev->id = tmp_prop;
107495 +
107496 + /* Get the FM interrupt */
107497 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
107498 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
107499 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107500 + DestroyFmDev(p_LnxWrpFmDev);
107501 + return NULL;
107502 + }
107503 +
107504 + /* Get the FM error interrupt */
107505 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
107506 +
107507 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
107508 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
107509 + DestroyFmDev(p_LnxWrpFmDev);
107510 + return NULL;
107511 + }
107512 +
107513 + /* Get the FM address */
107514 + _errno = of_address_to_resource(fm_node, 0, &res);
107515 + if (unlikely(_errno < 0)) {
107516 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107517 + DestroyFmDev(p_LnxWrpFmDev);
107518 + return NULL;
107519 + }
107520 +
107521 +
107522 + p_LnxWrpFmDev->fmBaseAddr = 0;
107523 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
107524 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
107525 +
107526 + clk = of_clk_get(fm_node, 0);
107527 + if (IS_ERR(clk)) {
107528 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
107529 + __func__);
107530 + of_node_put(fm_node);
107531 + DestroyFmDev(p_LnxWrpFmDev);
107532 + return NULL;
107533 + }
107534 +
107535 + clk_rate = clk_get_rate(clk);
107536 + if (!clk_rate) {
107537 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
107538 + __func__);
107539 + of_node_put(fm_node);
107540 + DestroyFmDev(p_LnxWrpFmDev);
107541 + return NULL;
107542 + }
107543 +
107544 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
107545 + /* Get the MURAM base address and size */
107546 + memset(ids, 0, sizeof(ids));
107547 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
107548 + return NULL;
107549 + strcpy(ids[0].name, "muram");
107550 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
107551 + return NULL;
107552 + strcpy(ids[0].compatible, "fsl,fman-muram");
107553 + for_each_child_of_node(fm_node, dev_node) {
107554 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107555 + _errno = of_address_to_resource(dev_node, 0, &res);
107556 + if (unlikely(_errno < 0)) {
107557 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107558 + DestroyFmDev(p_LnxWrpFmDev);
107559 + return NULL;
107560 + }
107561 +
107562 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
107563 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
107564 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
107565 +
107566 +#ifndef CONFIG_FMAN_ARM
107567 + {
107568 + uint32_t svr;
107569 + svr = mfspr(SPRN_SVR);
107570 +
107571 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
107572 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
107573 + }
107574 +#endif
107575 + }
107576 + }
107577 +
107578 + /* Get the RTC base address and size */
107579 + memset(ids, 0, sizeof(ids));
107580 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
107581 + return NULL;
107582 + strcpy(ids[0].name, "ptp-timer");
107583 + if (WARN_ON(strlen("fsl,fman-rtc") >= sizeof(ids[0].compatible)))
107584 + return NULL;
107585 + strcpy(ids[0].compatible, "fsl,fman-rtc");
107586 + for_each_child_of_node(fm_node, dev_node) {
107587 + if (likely(of_match_node(ids, dev_node) != NULL)) {
107588 + _errno = of_address_to_resource(dev_node, 0, &res);
107589 + if (unlikely(_errno < 0)) {
107590 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107591 + DestroyFmDev(p_LnxWrpFmDev);
107592 + return NULL;
107593 + }
107594 +
107595 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
107596 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
107597 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
107598 + }
107599 + }
107600 +
107601 +#if (DPAA_VERSION >= 11)
107602 + /* Get the VSP base address */
107603 + for_each_child_of_node(fm_node, dev_node) {
107604 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
107605 + _errno = of_address_to_resource(dev_node, 0, &res);
107606 + if (unlikely(_errno < 0)) {
107607 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
107608 + DestroyFmDev(p_LnxWrpFmDev);
107609 + return NULL;
107610 + }
107611 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
107612 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
107613 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
107614 + }
107615 + }
107616 +#endif
107617 +
107618 + /* Get all PCD nodes */
107619 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
107620 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
107621 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
107622 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
107623 +
107624 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
107625 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
107626 + p_LnxWrpFmDev->pcdActive = TRUE;
107627 +
107628 + if (p_LnxWrpFmDev->pcdActive)
107629 + {
107630 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
107631 + if (str_prop) {
107632 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
107633 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
107634 + }
107635 + else
107636 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
107637 + }
107638 +
107639 + of_node_put(fm_node);
107640 +
107641 + p_LnxWrpFmDev->hcCh =
107642 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
107643 +
107644 + p_LnxWrpFmDev->active = TRUE;
107645 +
107646 + return p_LnxWrpFmDev;
107647 +}
107648 +
107649 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
107650 +{
107651 + struct device_node *dev_node;
107652 + const uint32_t *uint32_prop;
107653 + int lenp;
107654 + uint32_t tmp_prop;
107655 +
107656 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
107657 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
107658 + if (unlikely(uint32_prop == NULL)) {
107659 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
107660 + ("of_get_property(%s, cell-index) failed",
107661 + dev_node->full_name));
107662 + return NULL;
107663 + }
107664 + tmp_prop = be32_to_cpu(*uint32_prop);
107665 + if (WARN_ON(lenp != sizeof(uint32_t)))
107666 + return NULL;
107667 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
107668 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
107669 + return NULL;
107670 + }
107671 + if (fmIndx == tmp_prop)
107672 + return dev_node;
107673 + }
107674 +
107675 + return NULL;
107676 +}
107677 +
107678 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
107679 +{
107680 + struct device_node *dev_node;
107681 + t_Error err = E_INVALID_VALUE;
107682 + const uint32_t *uint32_prop;
107683 + const char *str_prop;
107684 + int lenp;
107685 + uint32_t tmp_prop;
107686 +
107687 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
107688 + if (!dev_node) /* no advance parameters for FMan */
107689 + return E_OK;
107690 +
107691 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
107692 + if (str_prop) {
107693 + if (strcmp(str_prop, "port") == 0)
107694 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
107695 + else if (strcmp(str_prop, "tnum") == 0)
107696 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
107697 +
107698 + if (err != E_OK)
107699 + RETURN_ERROR(MINOR, err, NO_MSG);
107700 + }
107701 +
107702 + uint32_prop = (uint32_t *)of_get_property(dev_node,
107703 + "total-fifo-size", &lenp);
107704 + if (uint32_prop) {
107705 + tmp_prop = be32_to_cpu(*uint32_prop);
107706 + if (WARN_ON(lenp != sizeof(uint32_t)))
107707 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107708 +
107709 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
107710 + tmp_prop) != E_OK)
107711 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107712 + }
107713 +
107714 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
107715 + &lenp);
107716 + if (uint32_prop) {
107717 + tmp_prop = be32_to_cpu(*uint32_prop);
107718 + if (WARN_ON(lenp != sizeof(uint32_t)))
107719 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
107720 +
107721 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
107722 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
107723 +
107724 + if (err != E_OK)
107725 + RETURN_ERROR(MINOR, err, NO_MSG);
107726 + }
107727 +
107728 + of_node_put(dev_node);
107729 +
107730 + return E_OK;
107731 +}
107732 +
107733 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
107734 +{
107735 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107736 +
107737 + ASSERT_COND(p_LnxWrpFmDev);
107738 +
107739 + DBG(INFO, ("got fm exception %d", exception));
107740 +
107741 + /* do nothing */
107742 + UNUSED(exception);
107743 +}
107744 +
107745 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
107746 + e_FmPortType portType,
107747 + uint8_t portId,
107748 + uint64_t addr,
107749 + uint8_t tnum,
107750 + uint16_t liodn)
107751 +{
107752 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
107753 +
107754 + ASSERT_COND(p_LnxWrpFmDev);
107755 +
107756 + /* do nothing */
107757 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
107758 +}
107759 +
107760 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107761 +{
107762 + struct resource *dev_res;
107763 + int _errno;
107764 +
107765 + if (!p_LnxWrpFmDev->active)
107766 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107767 +
107768 +#ifndef MODULE
107769 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
107770 + if (unlikely(_errno < 0))
107771 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107772 +#endif
107773 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, 0, "fman", p_LnxWrpFmDev);
107774 + if (unlikely(_errno < 0))
107775 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
107776 +
107777 + enable_irq_wake(p_LnxWrpFmDev->irq);
107778 +
107779 + if (p_LnxWrpFmDev->err_irq != 0) {
107780 +#ifndef MODULE
107781 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
107782 + if (unlikely(_errno < 0))
107783 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
107784 +#endif
107785 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
107786 + if (unlikely(_errno < 0))
107787 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
107788 +
107789 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
107790 + }
107791 +
107792 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
107793 + if (unlikely(p_LnxWrpFmDev->res == NULL))
107794 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
107795 +
107796 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
107797 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
107798 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107799 +
107800 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
107801 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
107802 +
107803 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
107804 + if (unlikely(dev_res == NULL))
107805 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107806 +
107807 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
107808 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
107809 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107810 +
107811 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
107812 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
107813 +
107814 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
107815 + {
107816 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-rtc");
107817 + if (unlikely(dev_res == NULL))
107818 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107819 +
107820 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
107821 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
107822 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107823 +
107824 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
107825 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
107826 + }
107827 +
107828 +#if (DPAA_VERSION >= 11)
107829 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
107830 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
107831 + if (unlikely(dev_res == NULL))
107832 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
107833 +
107834 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
107835 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
107836 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
107837 + }
107838 +#endif
107839 +
107840 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
107841 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
107842 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
107843 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
107844 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
107845 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
107846 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
107847 +
107848 + return FillRestFmInfo(p_LnxWrpFmDev);
107849 +}
107850 +
107851 +#ifndef CONFIG_FMAN_ARM
107852 +/*
107853 + * Table for matching compatible strings, for device tree
107854 + * guts node, for QorIQ SOCs.
107855 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
107856 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
107857 + * string would be used.
107858 +*/
107859 +static const struct of_device_id guts_device_ids[] = {
107860 + { .compatible = "fsl,qoriq-device-config-1.0", },
107861 + { .compatible = "fsl,qoriq-device-config-2.0", },
107862 + {}
107863 +};
107864 +
107865 +static unsigned int get_rcwsr(int regnum)
107866 +{
107867 + struct ccsr_guts __iomem *guts_regs = NULL;
107868 + struct device_node *guts_node;
107869 +
107870 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107871 + if (!guts_node) {
107872 + pr_err("could not find GUTS node\n");
107873 + return 0;
107874 + }
107875 + guts_regs = of_iomap(guts_node, 0);
107876 + of_node_put(guts_node);
107877 + if (!guts_regs) {
107878 + pr_err("ioremap of GUTS node failed\n");
107879 + return 0;
107880 + }
107881 +
107882 + return ioread32be(&guts_regs->rcwsr[regnum]);
107883 +}
107884 +
107885 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
107886 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
107887 +
107888 +/**
107889 + * @Function ResetOnInitErrata_A007273
107890 + *
107891 + * @Description Workaround for Errata A-007273
107892 + * This workaround is required to avoid a FMan hang during reset on initialization.
107893 + * Enable all MACs in guts.devdisr2 register,
107894 + * then perform a regular FMan reset and then restore MACs to their original state.
107895 + *
107896 + * @Param[in] h_Fm - FM module descriptor
107897 + *
107898 + * @Return None.
107899 + */
107900 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
107901 +{
107902 + struct ccsr_guts __iomem *guts_regs = NULL;
107903 + struct device_node *guts_node;
107904 + u32 devdisr2, enableMacs;
107905 +
107906 + /* Get guts registers */
107907 + guts_node = of_find_matching_node(NULL, guts_device_ids);
107908 + if (!guts_node) {
107909 + pr_err("could not find GUTS node\n");
107910 + return;
107911 + }
107912 + guts_regs = of_iomap(guts_node, 0);
107913 + of_node_put(guts_node);
107914 + if (!guts_regs) {
107915 + pr_err("ioremap of GUTS node failed\n");
107916 + return;
107917 + }
107918 +
107919 + /* Read current state */
107920 + devdisr2 = ioread32be(&guts_regs->devdisr2);
107921 +
107922 + if (FmGetId(h_Fm) == 0)
107923 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
107924 + else
107925 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
107926 +
107927 + /* Enable all MACs */
107928 + iowrite32be(enableMacs, &guts_regs->devdisr2);
107929 +
107930 + /* Perform standard FMan reset */
107931 + FmReset(h_Fm);
107932 +
107933 + /* Restore devdisr2 value */
107934 + iowrite32be(devdisr2, &guts_regs->devdisr2);
107935 +
107936 + iounmap(guts_regs);
107937 +}
107938 +#endif
107939 +
107940 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
107941 +{
107942 + const struct qe_firmware *fw;
107943 +
107944 + if (!p_LnxWrpFmDev->active)
107945 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
107946 +
107947 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
107948 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
107949 +
107950 + /* Loading the fman-controller code */
107951 + fw = FindFmanMicrocode();
107952 +
107953 + if (!fw) {
107954 + /* this forces the reuse of the current IRAM content */
107955 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
107956 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
107957 + } else {
107958 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
107959 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
107960 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
107961 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
107962 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
107963 + fw->microcode[0].major,
107964 + fw->microcode[0].minor,
107965 + fw->microcode[0].revision));
107966 + }
107967 +
107968 +#ifdef CONFIG_FMAN_ARM
107969 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
107970 + int i;
107971 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
107972 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
107973 + u32 *dest = kzalloc(usz, GFP_KERNEL);
107974 +
107975 + if (p_Code && dest)
107976 + for(i=0; i < usz / 4; ++i)
107977 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
107978 +
107979 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
107980 + }
107981 +#endif
107982 +
107983 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
107984 +
107985 +#if (DPAA_VERSION >= 11)
107986 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
107987 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
107988 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
107989 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
107990 + }
107991 +#endif
107992 +
107993 +#ifdef CONFIG_FMAN_ARM
107994 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
107995 +#else
107996 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
107997 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
107998 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
107999 + else
108000 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
108001 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
108002 +
108003 + {
108004 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
108005 + uint32_t svr;
108006 + svr = mfspr(SPRN_SVR);
108007 +
108008 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
108009 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
108010 + }
108011 +#endif /* CONFIG_FMAN_ARM */
108012 +
108013 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
108014 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
108015 +
108016 +
108017 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108018 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108019 +
108020 +#ifndef CONFIG_FMAN_ARM
108021 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
108022 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
108023 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108024 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
108025 +#endif /* CONFIG_FMAN_ARM */
108026 +
108027 +#ifdef CONFIG_FMAN_P1023
108028 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
108029 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108030 +#endif
108031 +
108032 +
108033 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
108034 +
108035 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
108036 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
108037 +
108038 + /* TODO: Why we mask these interrupts? */
108039 + if (p_LnxWrpFmDev->err_irq == 0) {
108040 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
108041 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
108042 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
108043 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
108044 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
108045 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
108046 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
108047 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
108048 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
108049 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
108050 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
108051 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
108052 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
108053 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
108054 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
108055 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
108056 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
108057 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
108058 + }
108059 +
108060 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108061 + {
108062 + t_FmRtcParams fmRtcParam;
108063 +
108064 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
108065 + fmRtcParam.h_App = p_LnxWrpFmDev;
108066 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
108067 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
108068 +
108069 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
108070 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
108071 +
108072 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
108073 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108074 +
108075 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
108076 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
108077 + }
108078 +
108079 + return E_OK;
108080 +}
108081 +
108082 +/* TODO: to be moved back here */
108083 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
108084 +
108085 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108086 +{
108087 + if (!p_LnxWrpFmDev->active)
108088 + return;
108089 +
108090 + FreeFmPcdDev(p_LnxWrpFmDev);
108091 +
108092 + if (p_LnxWrpFmDev->h_RtcDev)
108093 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
108094 +
108095 + if (p_LnxWrpFmDev->h_Dev)
108096 + FM_Free(p_LnxWrpFmDev->h_Dev);
108097 +
108098 + if (p_LnxWrpFmDev->h_MuramDev)
108099 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
108100 +
108101 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
108102 + {
108103 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
108104 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
108105 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
108106 + }
108107 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
108108 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
108109 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
108110 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
108111 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
108112 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
108113 + if (p_LnxWrpFmDev->err_irq != 0) {
108114 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
108115 + }
108116 +
108117 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
108118 +}
108119 +
108120 +/* FMan character device file operations */
108121 +extern struct file_operations fm_fops;
108122 +
108123 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
108124 +{
108125 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108126 +
108127 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
108128 + return -EIO;
108129 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
108130 + return -EIO;
108131 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
108132 + return -EIO;
108133 +
108134 + /* IOCTL ABI checking */
108135 + LnxWrpPCDIOCTLEnumChecking();
108136 + LnxWrpPCDIOCTLTypeChecking();
108137 +
108138 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
108139 +
108140 + /* Register to the /dev for IOCTL API */
108141 + /* Register dynamically a new major number for the character device: */
108142 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
108143 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
108144 + return -EIO;
108145 + }
108146 +
108147 + /* Creating classes for FM */
108148 + DBG(TRACE ,("class_create fm_class"));
108149 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
108150 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
108151 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108152 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
108153 + return -EIO;
108154 + }
108155 +
108156 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
108157 + "fm%d", p_LnxWrpFmDev->id);
108158 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
108159 + "fm%d-pcd", p_LnxWrpFmDev->id);
108160 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
108161 +
108162 + /* create sysfs entries for stats and regs */
108163 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
108164 + {
108165 + FreeFmDev(p_LnxWrpFmDev);
108166 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
108167 + return -EIO;
108168 + }
108169 +
108170 +#ifdef CONFIG_PM
108171 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
108172 +#endif
108173 +
108174 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
108175 +
108176 + return 0;
108177 +}
108178 +
108179 +static int fm_remove(struct platform_device *of_dev)
108180 +{
108181 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108182 + struct device *dev;
108183 +
108184 + dev = &of_dev->dev;
108185 + p_LnxWrpFmDev = dev_get_drvdata(dev);
108186 +
108187 + fm_sysfs_destroy(dev);
108188 +
108189 + DBG(TRACE, ("destroy fm_class"));
108190 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
108191 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
108192 + class_destroy(p_LnxWrpFmDev->fm_class);
108193 +
108194 + /* Destroy chardev */
108195 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
108196 +
108197 + FreeFmDev(p_LnxWrpFmDev);
108198 +
108199 + DestroyFmDev(p_LnxWrpFmDev);
108200 +
108201 + dev_set_drvdata(dev, NULL);
108202 +
108203 + return 0;
108204 +}
108205 +
108206 +static const struct of_device_id fm_match[] = {
108207 + {
108208 + .compatible = "fsl,fman"
108209 + },
108210 + {}
108211 +};
108212 +#ifndef MODULE
108213 +MODULE_DEVICE_TABLE(of, fm_match);
108214 +#endif /* !MODULE */
108215 +
108216 +#ifdef CONFIG_PM
108217 +
108218 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
108219 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
108220 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
108221 +
108222 +struct device *g_fm_dev;
108223 +
108224 +static int fm_soc_suspend(struct device *dev)
108225 +{
108226 + int err = 0;
108227 + uint32_t *fmclk;
108228 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108229 + g_fm_dev = dev;
108230 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108231 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
108232 + if (p_LnxWrpFmDev->h_DsarRxPort)
108233 + {
108234 +#ifdef CONFIG_FSL_QORIQ_PM
108235 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
108236 +#endif
108237 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
108238 + p_LnxWrpFmDev->h_DsarTxPort);
108239 + }
108240 + return err;
108241 +}
108242 +
108243 +static int fm_soc_resume(struct device *dev)
108244 +{
108245 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
108246 + uint32_t *fmclk;
108247 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
108248 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
108249 + if (p_LnxWrpFmDev->h_DsarRxPort)
108250 + {
108251 +#ifdef CONFIG_FSL_QORIQ_PM
108252 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
108253 +#endif
108254 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
108255 + p_LnxWrpFmDev->h_DsarTxPort);
108256 + p_LnxWrpFmDev->h_DsarRxPort = 0;
108257 + p_LnxWrpFmDev->h_DsarTxPort = 0;
108258 + }
108259 + return 0;
108260 +}
108261 +
108262 +static const struct dev_pm_ops fm_pm_ops = {
108263 + .suspend = fm_soc_suspend,
108264 + .resume = fm_soc_resume,
108265 +};
108266 +
108267 +#define FM_PM_OPS (&fm_pm_ops)
108268 +
108269 +#else /* CONFIG_PM */
108270 +
108271 +#define FM_PM_OPS NULL
108272 +
108273 +#endif /* CONFIG_PM */
108274 +
108275 +static struct platform_driver fm_driver = {
108276 + .driver = {
108277 + .name = "fsl-fman",
108278 + .of_match_table = fm_match,
108279 + .owner = THIS_MODULE,
108280 + .pm = FM_PM_OPS,
108281 + },
108282 + .probe = fm_probe,
108283 + .remove = fm_remove
108284 +};
108285 +
108286 +t_Handle LNXWRP_FM_Init(void)
108287 +{
108288 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
108289 + mutex_init(&lnxwrp_mutex);
108290 +
108291 + /* Register to the DTB for basic FM API */
108292 + platform_driver_register(&fm_driver);
108293 +
108294 + return &lnxWrpFm;
108295 +}
108296 +
108297 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
108298 +{
108299 + platform_driver_unregister(&fm_driver);
108300 + mutex_destroy(&lnxwrp_mutex);
108301 +
108302 + return E_OK;
108303 +}
108304 +
108305 +
108306 +struct fm * fm_bind(struct device *fm_dev)
108307 +{
108308 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
108309 +}
108310 +EXPORT_SYMBOL(fm_bind);
108311 +
108312 +void fm_unbind(struct fm *fm)
108313 +{
108314 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108315 +
108316 + put_device(p_LnxWrpFmDev->dev);
108317 +}
108318 +EXPORT_SYMBOL(fm_unbind);
108319 +
108320 +struct resource * fm_get_mem_region(struct fm *fm)
108321 +{
108322 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108323 +
108324 + return p_LnxWrpFmDev->res;
108325 +}
108326 +EXPORT_SYMBOL(fm_get_mem_region);
108327 +
108328 +void * fm_get_handle(struct fm *fm)
108329 +{
108330 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108331 +
108332 + return (void *)p_LnxWrpFmDev->h_Dev;
108333 +}
108334 +EXPORT_SYMBOL(fm_get_handle);
108335 +
108336 +void * fm_get_rtc_handle(struct fm *fm)
108337 +{
108338 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
108339 +
108340 + return (void *)p_LnxWrpFmDev->h_RtcDev;
108341 +}
108342 +EXPORT_SYMBOL(fm_get_rtc_handle);
108343 +
108344 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
108345 +{
108346 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
108347 +}
108348 +EXPORT_SYMBOL(fm_port_bind);
108349 +
108350 +void fm_port_unbind(struct fm_port *port)
108351 +{
108352 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108353 +
108354 + put_device(p_LnxWrpFmPortDev->dev);
108355 +}
108356 +EXPORT_SYMBOL(fm_port_unbind);
108357 +
108358 +void *fm_port_get_handle(const struct fm_port *port)
108359 +{
108360 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108361 +
108362 + return (void *)p_LnxWrpFmPortDev->h_Dev;
108363 +}
108364 +EXPORT_SYMBOL(fm_port_get_handle);
108365 +
108366 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
108367 + const void *data)
108368 +{
108369 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
108370 + (void *)data);
108371 +}
108372 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
108373 +
108374 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
108375 +{
108376 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108377 +
108378 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
108379 +}
108380 +EXPORT_SYMBOL(fm_port_get_base_addr);
108381 +
108382 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
108383 +{
108384 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108385 +
108386 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
108387 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
108388 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
108389 +}
108390 +EXPORT_SYMBOL(fm_port_pcd_bind);
108391 +
108392 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
108393 +{
108394 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108395 + struct device_node *fm_node, *port_node;
108396 + const uint32_t *uint32_prop;
108397 + int lenp;
108398 +
108399 + params->data_align = 0;
108400 + params->manip_extra_space = 0;
108401 +
108402 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
108403 + if (!fm_node) /* no advance parameters for FMan */
108404 + return;
108405 +
108406 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
108407 + p_LnxWrpFmPortDev->settings.param.portType,
108408 + p_LnxWrpFmPortDev->settings.param.portId);
108409 + if (!port_node) /* no advance parameters for FMan-Port */
108410 + return;
108411 +
108412 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
108413 + if (uint32_prop) {
108414 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
108415 + return;
108416 +
108417 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
108418 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
108419 + }
108420 +
108421 + of_node_put(port_node);
108422 + of_node_put(fm_node);
108423 +}
108424 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
108425 +
108426 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
108427 +{
108428 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108429 +
108430 + return p_LnxWrpFmPortDev->txCh;
108431 +}
108432 +EXPORT_SYMBOL(fm_get_tx_port_channel);
108433 +
108434 +int fm_port_enable (struct fm_port *port)
108435 +{
108436 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108437 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108438 +
108439 + return GET_ERROR_TYPE(err);
108440 +}
108441 +EXPORT_SYMBOL(fm_port_enable);
108442 +
108443 +int fm_port_disable(struct fm_port *port)
108444 +{
108445 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
108446 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108447 +
108448 + return GET_ERROR_TYPE(err);
108449 +}
108450 +EXPORT_SYMBOL(fm_port_disable);
108451 +
108452 +int fm_port_set_rate_limit(struct fm_port *port,
108453 + uint16_t max_burst_size,
108454 + uint32_t rate_limit)
108455 +{
108456 + t_FmPortRateLimit param;
108457 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108458 + int err = 0;
108459 +
108460 + param.maxBurstSize = max_burst_size;
108461 + param.rateLimit = rate_limit;
108462 + param.rateLimitDivider = 0;
108463 +
108464 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
108465 + return err;
108466 +}
108467 +EXPORT_SYMBOL(fm_port_set_rate_limit);
108468 +
108469 +int fm_port_del_rate_limit(struct fm_port *port)
108470 +{
108471 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108472 +
108473 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
108474 + return 0;
108475 +}
108476 +EXPORT_SYMBOL(fm_port_del_rate_limit);
108477 +
108478 +void FM_PORT_Dsar_DumpRegs(void);
108479 +int ar_showmem(struct file *file, const char __user *buffer,
108480 + unsigned long count, void *data)
108481 +{
108482 + FM_PORT_Dsar_DumpRegs();
108483 + return 2;
108484 +}
108485 +
108486 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
108487 + struct fm_port *port)
108488 +{
108489 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108490 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
108491 +}
108492 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
108493 +
108494 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
108495 + struct auto_res_port_params *params)
108496 +{
108497 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108498 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
108499 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
108500 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
108501 +
108502 + /*Register other under /proc/autoresponse */
108503 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
108504 + return -EFAULT;
108505 +
108506 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
108507 + return 0;
108508 +}
108509 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
108510 +
108511 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
108512 + struct fm_port *port_tx)
108513 +{
108514 +}
108515 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
108516 +
108517 +int fm_port_get_autores_stats(struct fm_port *port,
108518 + struct auto_res_port_stats *stats)
108519 +{
108520 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108521 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
108522 + return -EFAULT;
108523 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
108524 +}
108525 +EXPORT_SYMBOL(fm_port_get_autores_stats);
108526 +
108527 +int fm_port_suspend(struct fm_port *port)
108528 +{
108529 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108530 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108531 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
108532 + else
108533 + return 0;
108534 +}
108535 +EXPORT_SYMBOL(fm_port_suspend);
108536 +
108537 +int fm_port_resume(struct fm_port *port)
108538 +{
108539 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108540 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
108541 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
108542 + else
108543 + return 0;
108544 +}
108545 +EXPORT_SYMBOL(fm_port_resume);
108546 +
108547 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
108548 +{
108549 + return FM_PORT_IsInDsar(port);
108550 +}
108551 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
108552 +
108553 +#ifdef CONFIG_FMAN_PFC
108554 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
108555 + uint8_t prio, uint8_t wq)
108556 +{
108557 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
108558 + int err;
108559 + int _errno;
108560 +
108561 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
108562 + prio, wq);
108563 + _errno = -GET_ERROR_TYPE(err);
108564 + if (unlikely(_errno < 0))
108565 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
108566 +
108567 + return _errno;
108568 +}
108569 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
108570 +#endif
108571 +
108572 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
108573 + e_FmMacExceptions exception, bool enable)
108574 +{
108575 + int err;
108576 + int _errno;
108577 +
108578 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
108579 +
108580 + _errno = -GET_ERROR_TYPE(err);
108581 + if (unlikely(_errno < 0))
108582 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
108583 +
108584 + return _errno;
108585 +}
108586 +EXPORT_SYMBOL(fm_mac_set_exception);
108587 +
108588 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
108589 +{
108590 + int err;
108591 + int _error;
108592 +
108593 + err = FM_MAC_Free(fm_mac_dev);
108594 + _error = -GET_ERROR_TYPE(err);
108595 +
108596 + if (unlikely(_error < 0))
108597 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
108598 +
108599 + return _error;
108600 +}
108601 +EXPORT_SYMBOL(fm_mac_free);
108602 +
108603 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
108604 +{
108605 + struct fm_mac_dev *fm_mac_dev;
108606 +
108607 + fm_mac_dev = FM_MAC_Config(params);
108608 + if (unlikely(fm_mac_dev == NULL))
108609 + pr_err("FM_MAC_Config() failed\n");
108610 +
108611 + return fm_mac_dev;
108612 +}
108613 +EXPORT_SYMBOL(fm_mac_config);
108614 +
108615 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
108616 + int len)
108617 +{
108618 + int err;
108619 + int _errno;
108620 +
108621 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
108622 + _errno = -GET_ERROR_TYPE(err);
108623 + if (unlikely(_errno < 0))
108624 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
108625 +
108626 + return _errno;
108627 +}
108628 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
108629 +
108630 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
108631 +{
108632 + int err;
108633 + int _errno;
108634 +
108635 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
108636 + _errno = -GET_ERROR_TYPE(err);
108637 + if (unlikely(_errno < 0))
108638 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
108639 +
108640 + return _errno;
108641 +}
108642 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
108643 +
108644 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
108645 +{
108646 + int err;
108647 + int _errno;
108648 +
108649 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
108650 + _errno = -GET_ERROR_TYPE(err);
108651 + if (unlikely(_errno < 0))
108652 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
108653 +
108654 + return _errno;
108655 +}
108656 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
108657 +
108658 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
108659 +{
108660 + int err;
108661 + int _errno;
108662 +
108663 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
108664 + _errno = -GET_ERROR_TYPE(err);
108665 + if (unlikely(_errno < 0))
108666 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
108667 +
108668 + return _errno;
108669 +}
108670 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
108671 +
108672 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
108673 +{
108674 + int err;
108675 + int _errno;
108676 +
108677 + err = FM_MAC_Init(fm_mac_dev);
108678 + _errno = -GET_ERROR_TYPE(err);
108679 + if (unlikely(_errno < 0))
108680 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
108681 +
108682 + return _errno;
108683 +}
108684 +EXPORT_SYMBOL(fm_mac_init);
108685 +
108686 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
108687 +{
108688 + int err;
108689 + int _errno;
108690 +
108691 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
108692 + _errno = -GET_ERROR_TYPE(err);
108693 + if (unlikely(_errno < 0))
108694 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
108695 +
108696 + return _errno;
108697 +}
108698 +EXPORT_SYMBOL(fm_mac_get_version);
108699 +
108700 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
108701 +{
108702 + int _errno;
108703 + t_Error err;
108704 +
108705 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108706 + _errno = -GET_ERROR_TYPE(err);
108707 + if (unlikely(_errno < 0))
108708 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
108709 +
108710 + return _errno;
108711 +}
108712 +EXPORT_SYMBOL(fm_mac_enable);
108713 +
108714 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
108715 +{
108716 + int _errno;
108717 + t_Error err;
108718 +
108719 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
108720 + _errno = -GET_ERROR_TYPE(err);
108721 + if (unlikely(_errno < 0))
108722 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
108723 +
108724 + return _errno;
108725 +}
108726 +EXPORT_SYMBOL(fm_mac_disable);
108727 +
108728 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
108729 +{
108730 + int _errno;
108731 + t_Error err;
108732 +
108733 + err = FM_MAC_Resume(fm_mac_dev);
108734 + _errno = -GET_ERROR_TYPE(err);
108735 + if (unlikely(_errno < 0))
108736 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
108737 +
108738 + return _errno;
108739 +}
108740 +EXPORT_SYMBOL(fm_mac_resume);
108741 +
108742 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
108743 + bool enable)
108744 +{
108745 + int _errno;
108746 + t_Error err;
108747 +
108748 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
108749 + _errno = -GET_ERROR_TYPE(err);
108750 + if (unlikely(_errno < 0))
108751 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
108752 +
108753 + return _errno;
108754 +}
108755 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
108756 +
108757 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108758 + t_EnetAddr *mac_addr)
108759 +{
108760 + int _errno;
108761 + t_Error err;
108762 +
108763 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
108764 + _errno = -GET_ERROR_TYPE(err);
108765 + if (_errno < 0) {
108766 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
108767 + return _errno;
108768 + }
108769 +
108770 + return 0;
108771 +}
108772 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
108773 +
108774 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
108775 + t_EnetAddr *mac_addr)
108776 +{
108777 + int _errno;
108778 + t_Error err;
108779 +
108780 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
108781 + _errno = -GET_ERROR_TYPE(err);
108782 + if (_errno < 0) {
108783 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
108784 + return _errno;
108785 + }
108786 +
108787 + return 0;
108788 +}
108789 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
108790 +
108791 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
108792 + uint8_t *addr)
108793 +{
108794 + int _errno;
108795 + t_Error err;
108796 +
108797 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
108798 + _errno = -GET_ERROR_TYPE(err);
108799 + if (_errno < 0)
108800 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
108801 +
108802 + return _errno;
108803 +}
108804 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
108805 +
108806 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
108807 + bool link, int speed, bool duplex)
108808 +{
108809 + int _errno;
108810 + t_Error err;
108811 +
108812 + if (!link) {
108813 +#if (DPAA_VERSION < 11)
108814 + FM_MAC_RestartAutoneg(fm_mac_dev);
108815 +#endif
108816 + return 0;
108817 + }
108818 +
108819 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
108820 + _errno = -GET_ERROR_TYPE(err);
108821 + if (unlikely(_errno < 0))
108822 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
108823 +
108824 + return _errno;
108825 +}
108826 +EXPORT_SYMBOL(fm_mac_adjust_link);
108827 +
108828 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108829 +{
108830 + int _errno;
108831 + t_Error err;
108832 +
108833 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
108834 + _errno = -GET_ERROR_TYPE(err);
108835 + if (unlikely(_errno < 0))
108836 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
108837 + return _errno;
108838 +}
108839 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
108840 +
108841 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
108842 +{
108843 + int _errno;
108844 + t_Error err;
108845 +
108846 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
108847 + _errno = -GET_ERROR_TYPE(err);
108848 + if (unlikely(_errno < 0))
108849 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
108850 + return _errno;
108851 +}
108852 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
108853 +
108854 +int fm_mac_set_rx_pause_frames(
108855 + struct fm_mac_dev *fm_mac_dev, bool en)
108856 +{
108857 + int _errno;
108858 + t_Error err;
108859 +
108860 + /* if rx pause is enabled, do NOT ignore pause frames */
108861 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
108862 +
108863 + _errno = -GET_ERROR_TYPE(err);
108864 + if (_errno < 0)
108865 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
108866 +
108867 + return _errno;
108868 +}
108869 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
108870 +
108871 +#ifdef CONFIG_FMAN_PFC
108872 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108873 + bool en)
108874 +{
108875 + int _errno, i;
108876 + t_Error err;
108877 +
108878 + if (en)
108879 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108880 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108881 + i, fsl_fm_pfc_quanta[i],
108882 + FSL_FM_PAUSE_THRESH_DEFAULT);
108883 + _errno = -GET_ERROR_TYPE(err);
108884 + if (_errno < 0) {
108885 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108886 + return _errno;
108887 + }
108888 + }
108889 + else
108890 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
108891 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
108892 + i, FSL_FM_PAUSE_TIME_DISABLE,
108893 + FSL_FM_PAUSE_THRESH_DEFAULT);
108894 + _errno = -GET_ERROR_TYPE(err);
108895 + if (_errno < 0) {
108896 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
108897 + return _errno;
108898 + }
108899 + }
108900 +
108901 + return _errno;
108902 +}
108903 +#else
108904 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
108905 + bool en)
108906 +{
108907 + int _errno;
108908 + t_Error err;
108909 +
108910 + if (en)
108911 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108912 + FSL_FM_PAUSE_TIME_ENABLE);
108913 + else
108914 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
108915 + FSL_FM_PAUSE_TIME_DISABLE);
108916 +
108917 + _errno = -GET_ERROR_TYPE(err);
108918 + if (_errno < 0)
108919 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
108920 +
108921 + return _errno;
108922 +}
108923 +#endif
108924 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
108925 +
108926 +int fm_rtc_enable(struct fm *fm_dev)
108927 +{
108928 + int _errno;
108929 + t_Error err;
108930 +
108931 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
108932 + _errno = -GET_ERROR_TYPE(err);
108933 + if (unlikely(_errno < 0))
108934 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
108935 +
108936 + return _errno;
108937 +}
108938 +EXPORT_SYMBOL(fm_rtc_enable);
108939 +
108940 +int fm_rtc_disable(struct fm *fm_dev)
108941 +{
108942 + int _errno;
108943 + t_Error err;
108944 +
108945 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
108946 + _errno = -GET_ERROR_TYPE(err);
108947 + if (unlikely(_errno < 0))
108948 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
108949 +
108950 + return _errno;
108951 +}
108952 +EXPORT_SYMBOL(fm_rtc_disable);
108953 +
108954 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
108955 +{
108956 + int _errno;
108957 + t_Error err;
108958 +
108959 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108960 + _errno = -GET_ERROR_TYPE(err);
108961 + if (unlikely(_errno < 0))
108962 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
108963 +
108964 + return _errno;
108965 +}
108966 +EXPORT_SYMBOL(fm_rtc_get_cnt);
108967 +
108968 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
108969 +{
108970 + int _errno;
108971 + t_Error err;
108972 +
108973 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
108974 + _errno = -GET_ERROR_TYPE(err);
108975 + if (unlikely(_errno < 0))
108976 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
108977 +
108978 + return _errno;
108979 +}
108980 +EXPORT_SYMBOL(fm_rtc_set_cnt);
108981 +
108982 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
108983 +{
108984 + int _errno;
108985 + t_Error err;
108986 +
108987 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
108988 + drift);
108989 + _errno = -GET_ERROR_TYPE(err);
108990 + if (unlikely(_errno < 0))
108991 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
108992 +
108993 + return _errno;
108994 +}
108995 +EXPORT_SYMBOL(fm_rtc_get_drift);
108996 +
108997 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
108998 +{
108999 + int _errno;
109000 + t_Error err;
109001 +
109002 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
109003 + drift);
109004 + _errno = -GET_ERROR_TYPE(err);
109005 + if (unlikely(_errno < 0))
109006 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
109007 +
109008 + return _errno;
109009 +}
109010 +EXPORT_SYMBOL(fm_rtc_set_drift);
109011 +
109012 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
109013 + uint64_t time)
109014 +{
109015 + t_FmRtcAlarmParams alarm;
109016 + int _errno;
109017 + t_Error err;
109018 +
109019 + alarm.alarmId = id;
109020 + alarm.alarmTime = time;
109021 + alarm.f_AlarmCallback = NULL;
109022 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
109023 + &alarm);
109024 + _errno = -GET_ERROR_TYPE(err);
109025 + if (unlikely(_errno < 0))
109026 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
109027 +
109028 + return _errno;
109029 +}
109030 +EXPORT_SYMBOL(fm_rtc_set_alarm);
109031 +
109032 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
109033 + uint64_t fiper)
109034 +{
109035 + t_FmRtcPeriodicPulseParams pp;
109036 + int _errno;
109037 + t_Error err;
109038 +
109039 + pp.periodicPulseId = id;
109040 + pp.periodicPulsePeriod = fiper;
109041 + pp.f_PeriodicPulseCallback = NULL;
109042 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
109043 + _errno = -GET_ERROR_TYPE(err);
109044 + if (unlikely(_errno < 0))
109045 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
109046 +
109047 + return _errno;
109048 +}
109049 +EXPORT_SYMBOL(fm_rtc_set_fiper);
109050 +
109051 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
109052 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
109053 +{
109054 + int _errno;
109055 + t_Error err;
109056 +
109057 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
109058 + events);
109059 + _errno = -GET_ERROR_TYPE(err);
109060 + if (unlikely(_errno < 0))
109061 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
109062 +
109063 + return _errno;
109064 +}
109065 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
109066 +
109067 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
109068 +{
109069 + int _errno;
109070 + t_Error err;
109071 +
109072 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
109073 + events);
109074 + _errno = -GET_ERROR_TYPE(err);
109075 + if (unlikely(_errno < 0))
109076 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
109077 +
109078 + return _errno;
109079 +}
109080 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
109081 +#endif
109082 +
109083 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
109084 +{
109085 + int _errno;
109086 + t_Error err;
109087 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
109088 +
109089 + /* Do not set WoL on AR ports */
109090 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
109091 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
109092 + return 0;
109093 + }
109094 +
109095 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
109096 +
109097 + _errno = -GET_ERROR_TYPE(err);
109098 + if (_errno < 0)
109099 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
109100 +
109101 + return _errno;
109102 +}
109103 +EXPORT_SYMBOL(fm_mac_set_wol);
109104 +
109105 +void fm_mutex_lock(void)
109106 +{
109107 + mutex_lock(&lnxwrp_mutex);
109108 +}
109109 +EXPORT_SYMBOL(fm_mutex_lock);
109110 +
109111 +void fm_mutex_unlock(void)
109112 +{
109113 + mutex_unlock(&lnxwrp_mutex);
109114 +}
109115 +EXPORT_SYMBOL(fm_mutex_unlock);
109116 +
109117 +/*Macsec wrapper functions*/
109118 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
109119 +{
109120 + struct fm_macsec_dev *fm_macsec_dev;
109121 +
109122 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
109123 + if (unlikely(fm_macsec_dev == NULL))
109124 + pr_err("FM_MACSEC_Config() failed\n");
109125 +
109126 + return fm_macsec_dev;
109127 +}
109128 +EXPORT_SYMBOL(fm_macsec_config);
109129 +
109130 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
109131 +{
109132 + int err;
109133 + int _errno;
109134 +
109135 + err = FM_MACSEC_Init(fm_macsec_dev);
109136 + _errno = -GET_ERROR_TYPE(err);
109137 + if (unlikely(_errno < 0))
109138 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
109139 +
109140 + return _errno;
109141 +}
109142 +EXPORT_SYMBOL(fm_macsec_init);
109143 +
109144 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
109145 +{
109146 + int err;
109147 + int _error;
109148 +
109149 + err = FM_MACSEC_Free(fm_macsec_dev);
109150 + _error = -GET_ERROR_TYPE(err);
109151 +
109152 + if (unlikely(_error < 0))
109153 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
109154 +
109155 + return _error;
109156 +}
109157 +EXPORT_SYMBOL(fm_macsec_free);
109158 +
109159 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
109160 + *fm_macsec_dev,
109161 + fm_macsec_unknown_sci_frame_treatment treat_mode)
109162 +{
109163 + int err;
109164 + int _errno;
109165 +
109166 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
109167 + treat_mode);
109168 + _errno = -GET_ERROR_TYPE(err);
109169 + if (unlikely(_errno < 0))
109170 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
109171 +
109172 + return _errno;
109173 +}
109174 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
109175 +
109176 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109177 + bool deliver_uncontrolled)
109178 +{
109179 + int err;
109180 + int _errno;
109181 +
109182 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
109183 + deliver_uncontrolled);
109184 + _errno = -GET_ERROR_TYPE(err);
109185 + if (unlikely(_errno < 0))
109186 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
109187 +
109188 + return _errno;
109189 +}
109190 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
109191 +
109192 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109193 + bool discard_uncontrolled)
109194 +{
109195 + int err;
109196 + int _errno;
109197 +
109198 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
109199 + discard_uncontrolled);
109200 + _errno = -GET_ERROR_TYPE(err);
109201 + if (unlikely(_errno < 0))
109202 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
109203 +
109204 + return _errno;
109205 +}
109206 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
109207 +
109208 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
109209 + fm_macsec_untag_frame_treatment treat_mode)
109210 +{
109211 + int err;
109212 + int _errno;
109213 +
109214 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
109215 + _errno = -GET_ERROR_TYPE(err);
109216 + if (unlikely(_errno < 0))
109217 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
109218 +
109219 + return _errno;
109220 +}
109221 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
109222 +
109223 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
109224 + uint32_t pn_exh_thr)
109225 +{
109226 + int err;
109227 + int _errno;
109228 +
109229 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
109230 + _errno = -GET_ERROR_TYPE(err);
109231 + if (unlikely(_errno < 0))
109232 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
109233 +
109234 + return _errno;
109235 +}
109236 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
109237 +
109238 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
109239 +{
109240 + int err;
109241 + int _errno;
109242 +
109243 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
109244 + _errno = -GET_ERROR_TYPE(err);
109245 + if (unlikely(_errno < 0))
109246 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
109247 +
109248 + return _errno;
109249 +}
109250 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
109251 +
109252 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
109253 +{
109254 + int err;
109255 + int _errno;
109256 +
109257 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
109258 + _errno = -GET_ERROR_TYPE(err);
109259 + if (unlikely(_errno < 0))
109260 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
109261 +
109262 + return _errno;
109263 +}
109264 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
109265 +
109266 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
109267 + fm_macsec_exception exception, bool enable)
109268 +{
109269 + int err;
109270 + int _errno;
109271 +
109272 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
109273 + _errno = -GET_ERROR_TYPE(err);
109274 + if (unlikely(_errno < 0))
109275 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
109276 +
109277 + return _errno;
109278 +}
109279 +EXPORT_SYMBOL(fm_macsec_config_exception);
109280 +
109281 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
109282 + int *macsec_revision)
109283 +{
109284 + int err;
109285 + int _errno;
109286 +
109287 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
109288 + _errno = -GET_ERROR_TYPE(err);
109289 + if (unlikely(_errno < 0))
109290 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
109291 +
109292 + return _errno;
109293 +}
109294 +EXPORT_SYMBOL(fm_macsec_get_revision);
109295 +
109296 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
109297 +{
109298 + int err;
109299 + int _errno;
109300 +
109301 + err = FM_MACSEC_Enable(fm_macsec_dev);
109302 + _errno = -GET_ERROR_TYPE(err);
109303 + if (unlikely(_errno < 0))
109304 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
109305 +
109306 + return _errno;
109307 +}
109308 +EXPORT_SYMBOL(fm_macsec_enable);
109309 +
109310 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
109311 +{
109312 + int err;
109313 + int _errno;
109314 +
109315 + err = FM_MACSEC_Disable(fm_macsec_dev);
109316 + _errno = -GET_ERROR_TYPE(err);
109317 + if (unlikely(_errno < 0))
109318 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
109319 +
109320 + return _errno;
109321 +}
109322 +EXPORT_SYMBOL(fm_macsec_disable);
109323 +
109324 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
109325 + fm_macsec_exception exception, bool enable)
109326 +{
109327 + int err;
109328 + int _errno;
109329 +
109330 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
109331 + _errno = -GET_ERROR_TYPE(err);
109332 + if (unlikely(_errno < 0))
109333 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
109334 +
109335 + return _errno;
109336 +}
109337 +EXPORT_SYMBOL(fm_macsec_set_exception);
109338 +
109339 +/* Macsec SECY wrapper API */
109340 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
109341 +{
109342 + struct fm_macsec_secy_dev *fm_macsec_secy;
109343 +
109344 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
109345 + if (unlikely(fm_macsec_secy < 0))
109346 + pr_err("FM_MACSEC_SECY_Config() failed\n");
109347 +
109348 + return fm_macsec_secy;
109349 +}
109350 +EXPORT_SYMBOL(fm_macsec_secy_config);
109351 +
109352 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109353 +{
109354 + int err;
109355 + int _errno;
109356 +
109357 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
109358 + _errno = -GET_ERROR_TYPE(err);
109359 + if (unlikely(_errno < 0))
109360 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
109361 +
109362 + return _errno;
109363 +}
109364 +EXPORT_SYMBOL(fm_macsec_secy_init);
109365 +
109366 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109367 +{
109368 + int err;
109369 + int _errno;
109370 +
109371 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
109372 + _errno = -GET_ERROR_TYPE(err);
109373 + if (unlikely(_errno < 0))
109374 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
109375 +
109376 + return _errno;
109377 +}
109378 +EXPORT_SYMBOL(fm_macsec_secy_free);
109379 +
109380 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109381 + fm_macsec_sci_insertion_mode sci_insertion_mode)
109382 +{
109383 + int err;
109384 + int _errno;
109385 +
109386 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
109387 + sci_insertion_mode);
109388 + _errno = -GET_ERROR_TYPE(err);
109389 + if (unlikely(_errno < 0))
109390 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
109391 +
109392 + return _errno;
109393 +}
109394 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
109395 +
109396 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109397 + bool protect_frames)
109398 +{
109399 + int err;
109400 + int _errno;
109401 +
109402 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
109403 + protect_frames);
109404 + _errno = -GET_ERROR_TYPE(err);
109405 + if (unlikely(_errno < 0))
109406 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
109407 +
109408 + return _errno;
109409 +}
109410 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
109411 +
109412 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109413 + bool replay_protect, uint32_t replay_window)
109414 +{
109415 + int err;
109416 + int _errno;
109417 +
109418 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
109419 + replay_protect, replay_window);
109420 + _errno = -GET_ERROR_TYPE(err);
109421 + if (unlikely(_errno < 0))
109422 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
109423 +
109424 + return _errno;
109425 +}
109426 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
109427 +
109428 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109429 + fm_macsec_valid_frame_behavior validate_frames)
109430 +{
109431 + int err;
109432 + int _errno;
109433 +
109434 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
109435 + validate_frames);
109436 + _errno = -GET_ERROR_TYPE(err);
109437 + if (unlikely(_errno < 0))
109438 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
109439 +
109440 + return _errno;
109441 +}
109442 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
109443 +
109444 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109445 + bool confidentiality_enable,
109446 + uint32_t confidentiality_offset)
109447 +{
109448 + int err;
109449 + int _errno;
109450 +
109451 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
109452 + confidentiality_enable,
109453 + confidentiality_offset);
109454 + _errno = -GET_ERROR_TYPE(err);
109455 + if (unlikely(_errno < 0))
109456 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
109457 + err);
109458 +
109459 + return _errno;
109460 +}
109461 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
109462 +
109463 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
109464 +{
109465 + int err;
109466 + int _errno;
109467 +
109468 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
109469 + _errno = -GET_ERROR_TYPE(err);
109470 + if (unlikely(_errno < 0))
109471 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
109472 + err);
109473 +
109474 + return _errno;
109475 +}
109476 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
109477 +
109478 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109479 + fm_macsec_secy_exception exception,
109480 + bool enable)
109481 +{
109482 + int err;
109483 + int _errno;
109484 +
109485 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
109486 + enable);
109487 + _errno = -GET_ERROR_TYPE(err);
109488 + if (unlikely(_errno < 0))
109489 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
109490 + err);
109491 +
109492 + return _errno;
109493 +}
109494 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
109495 +
109496 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109497 + fm_macsec_secy_event event,
109498 + bool enable)
109499 +{
109500 + int err;
109501 + int _errno;
109502 +
109503 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
109504 + _errno = -GET_ERROR_TYPE(err);
109505 + if (unlikely(_errno < 0))
109506 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
109507 + err);
109508 +
109509 + return _errno;
109510 +}
109511 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
109512 +
109513 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109514 + struct fm_macsec_secy_sc_params *params)
109515 +{
109516 + struct rx_sc_dev *rx_sc_dev;
109517 +
109518 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
109519 + if (unlikely(rx_sc_dev == NULL))
109520 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
109521 +
109522 + return rx_sc_dev;
109523 +}
109524 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
109525 +
109526 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109527 + struct rx_sc_dev *sc)
109528 +{
109529 + int err;
109530 + int _errno;
109531 +
109532 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
109533 + _errno = -GET_ERROR_TYPE(err);
109534 + if (unlikely(_errno < 0))
109535 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
109536 + err);
109537 +
109538 + return _errno;
109539 +}
109540 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
109541 +
109542 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109543 + struct rx_sc_dev *sc, macsec_an_t an,
109544 + uint32_t lowest_pn, macsec_sa_key_t key)
109545 +{
109546 + int err;
109547 + int _errno;
109548 +
109549 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
109550 + lowest_pn, key);
109551 + _errno = -GET_ERROR_TYPE(err);
109552 + if (unlikely(_errno < 0))
109553 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
109554 + err);
109555 +
109556 + return _errno;
109557 +}
109558 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
109559 +
109560 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109561 + struct rx_sc_dev *sc, macsec_an_t an)
109562 +{
109563 + int err;
109564 + int _errno;
109565 +
109566 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
109567 + _errno = -GET_ERROR_TYPE(err);
109568 + if (unlikely(_errno < 0))
109569 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
109570 + err);
109571 +
109572 + return _errno;
109573 +}
109574 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
109575 +
109576 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109577 + struct rx_sc_dev *sc,
109578 + macsec_an_t an)
109579 +{
109580 + int err;
109581 + int _errno;
109582 +
109583 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
109584 + _errno = -GET_ERROR_TYPE(err);
109585 + if (unlikely(_errno < 0))
109586 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
109587 + err);
109588 +
109589 + return _errno;
109590 +}
109591 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
109592 +
109593 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109594 + struct rx_sc_dev *sc,
109595 + macsec_an_t an)
109596 +{
109597 + int err;
109598 + int _errno;
109599 +
109600 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
109601 + _errno = -GET_ERROR_TYPE(err);
109602 + if (unlikely(_errno < 0))
109603 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
109604 + err);
109605 +
109606 + return _errno;
109607 +}
109608 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
109609 +
109610 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109611 + struct rx_sc_dev *sc,
109612 + macsec_an_t an, uint32_t updt_next_pn)
109613 +{
109614 + int err;
109615 + int _errno;
109616 +
109617 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
109618 + updt_next_pn);
109619 + _errno = -GET_ERROR_TYPE(err);
109620 + if (unlikely(_errno < 0))
109621 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
109622 +
109623 + return _errno;
109624 +}
109625 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
109626 +
109627 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109628 + struct rx_sc_dev *sc,
109629 + macsec_an_t an, uint32_t updt_lowest_pn)
109630 +{
109631 + int err;
109632 + int _errno;
109633 +
109634 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
109635 + updt_lowest_pn);
109636 + _errno = -GET_ERROR_TYPE(err);
109637 + if (unlikely(_errno < 0))
109638 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
109639 + err);
109640 +
109641 + return _errno;
109642 +}
109643 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
109644 +
109645 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109646 + struct rx_sc_dev *sc,
109647 + macsec_an_t an, macsec_sa_key_t key)
109648 +{
109649 + int err;
109650 + int _errno;
109651 +
109652 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
109653 + _errno = -GET_ERROR_TYPE(err);
109654 + if (unlikely(_errno < 0))
109655 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
109656 + err);
109657 +
109658 + return _errno;
109659 +}
109660 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
109661 +
109662 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109663 + macsec_an_t an, macsec_sa_key_t key)
109664 +{
109665 + int err;
109666 + int _errno;
109667 +
109668 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
109669 + _errno = -GET_ERROR_TYPE(err);
109670 + if (unlikely(_errno < 0))
109671 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
109672 + err);
109673 +
109674 + return _errno;
109675 +}
109676 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
109677 +
109678 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109679 + macsec_an_t an)
109680 +{
109681 + int err;
109682 + int _errno;
109683 +
109684 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
109685 + _errno = -GET_ERROR_TYPE(err);
109686 + if (unlikely(_errno < 0))
109687 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
109688 + err);
109689 +
109690 + return _errno;
109691 +}
109692 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
109693 +
109694 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109695 + macsec_an_t next_active_an,
109696 + macsec_sa_key_t key)
109697 +{
109698 + int err;
109699 + int _errno;
109700 +
109701 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
109702 + key);
109703 + _errno = -GET_ERROR_TYPE(err);
109704 + if (unlikely(_errno < 0))
109705 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
109706 + err);
109707 +
109708 + return _errno;
109709 +}
109710 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
109711 +
109712 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109713 + macsec_an_t an)
109714 +{
109715 + int err;
109716 + int _errno;
109717 +
109718 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
109719 + _errno = -GET_ERROR_TYPE(err);
109720 + if (unlikely(_errno < 0))
109721 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
109722 + err);
109723 +
109724 + return _errno;
109725 +}
109726 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
109727 +
109728 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109729 + macsec_an_t *p_an)
109730 +{
109731 + int err;
109732 + int _errno;
109733 +
109734 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
109735 + _errno = -GET_ERROR_TYPE(err);
109736 + if (unlikely(_errno < 0))
109737 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
109738 + err);
109739 +
109740 + return _errno;
109741 +}
109742 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
109743 +
109744 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109745 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
109746 +{
109747 + int err;
109748 + int _errno;
109749 +
109750 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
109751 + _errno = -GET_ERROR_TYPE(err);
109752 + if (unlikely(_errno < 0))
109753 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
109754 + err);
109755 +
109756 + return _errno;
109757 +}
109758 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
109759 +
109760 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
109761 + uint32_t *sc_phys_id)
109762 +{
109763 + int err;
109764 + int _errno;
109765 +
109766 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
109767 + _errno = -GET_ERROR_TYPE(err);
109768 + if (unlikely(_errno < 0))
109769 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
109770 + err);
109771 +
109772 + return _errno;
109773 +}
109774 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
109775 +
109776 +static t_Handle h_FmLnxWrp;
109777 +
109778 +static int __init __cold fm_load (void)
109779 +{
109780 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
109781 + {
109782 + printk("Failed to init FM wrapper!\n");
109783 + return -ENODEV;
109784 + }
109785 +
109786 + printk(KERN_CRIT "Freescale FM module," \
109787 + " FMD API version %d.%d.%d\n",
109788 + FMD_API_VERSION_MAJOR,
109789 + FMD_API_VERSION_MINOR,
109790 + FMD_API_VERSION_RESPIN);
109791 + return 0;
109792 +}
109793 +
109794 +static void __exit __cold fm_unload (void)
109795 +{
109796 + if (h_FmLnxWrp)
109797 + LNXWRP_FM_Free(h_FmLnxWrp);
109798 +}
109799 +
109800 +module_init (fm_load);
109801 +module_exit (fm_unload);
109802 --- /dev/null
109803 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
109804 @@ -0,0 +1,294 @@
109805 +/*
109806 + * Copyright 2008-2012 Freescale Semiconductor Inc.
109807 + *
109808 + * Redistribution and use in source and binary forms, with or without
109809 + * modification, are permitted provided that the following conditions are met:
109810 + * * Redistributions of source code must retain the above copyright
109811 + * notice, this list of conditions and the following disclaimer.
109812 + * * Redistributions in binary form must reproduce the above copyright
109813 + * notice, this list of conditions and the following disclaimer in the
109814 + * documentation and/or other materials provided with the distribution.
109815 + * * Neither the name of Freescale Semiconductor nor the
109816 + * names of its contributors may be used to endorse or promote products
109817 + * derived from this software without specific prior written permission.
109818 + *
109819 + *
109820 + * ALTERNATIVELY, this software may be distributed under the terms of the
109821 + * GNU General Public License ("GPL") as published by the Free Software
109822 + * Foundation, either version 2 of that License or (at your option) any
109823 + * later version.
109824 + *
109825 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
109826 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
109827 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
109828 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
109829 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
109830 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
109831 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
109832 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
109833 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
109834 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109835 + */
109836 +
109837 +/*
109838 + @File lnxwrp_fm.h
109839 +
109840 + @Author Shlomi Gridish
109841 +
109842 + @Description FM Linux wrapper functions.
109843 +
109844 +*/
109845 +
109846 +#ifndef __LNXWRP_FM_H__
109847 +#define __LNXWRP_FM_H__
109848 +
109849 +#include <linux/fsl_qman.h> /* struct qman_fq */
109850 +
109851 +#include "std_ext.h"
109852 +#include "error_ext.h"
109853 +#include "list_ext.h"
109854 +
109855 +#include "lnxwrp_fm_ext.h"
109856 +
109857 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
109858 +
109859 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
109860 +
109861 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
109862 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
109863 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
109864 +#else
109865 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
109866 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
109867 +#endif
109868 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
109869 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
109870 +
109871 +#define FRAG_MANIP_SPACE 128
109872 +#define FRAG_DATA_ALIGN 64
109873 +
109874 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
109875 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
109876 +#endif
109877 +
109878 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
109879 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
109880 +#endif
109881 +
109882 +typedef enum {
109883 + e_NO_PCD = 0,
109884 + e_FM_PCD_3_TUPLE
109885 +} e_LnxWrpFmPortPcdDefUseCase;
109886 +
109887 +
109888 +typedef struct t_FmTestFq {
109889 + struct qman_fq fq_base;
109890 + t_Handle h_Arg;
109891 +} t_FmTestFq;
109892 +
109893 +typedef struct {
109894 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
109895 + int minor;
109896 + char name[20];
109897 + bool active;
109898 + uint64_t phys_baseAddr;
109899 + uint64_t baseAddr; /* Port's *virtual* address */
109900 + uint32_t memSize;
109901 + t_WrpFmPortDevSettings settings;
109902 + t_FmExtPools opExtPools;
109903 + uint8_t totalNumOfSchemes;
109904 + uint8_t schemesBase;
109905 + uint8_t numOfSchemesUsed;
109906 + uint32_t pcdBaseQ;
109907 + uint16_t pcdNumOfQs;
109908 + struct fm_port_pcd_param pcd_owner_params;
109909 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109910 + t_Handle h_DefNetEnv;
109911 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
109912 + t_FmBufferPrefixContent buffPrefixContent;
109913 + t_Handle h_Dev;
109914 + t_Handle h_DfltVsp;
109915 + t_Handle h_LnxWrpFmDev;
109916 + uint16_t txCh;
109917 + struct device *dev;
109918 + struct device_attribute *dev_attr_stats;
109919 + struct device_attribute *dev_attr_regs;
109920 + struct device_attribute *dev_attr_bmi_regs;
109921 + struct device_attribute *dev_attr_qmi_regs;
109922 +#if (DPAA_VERSION >= 11)
109923 + struct device_attribute *dev_attr_ipv4_opt;
109924 +#endif
109925 + struct device_attribute *dev_attr_dsar_regs;
109926 + struct device_attribute *dev_attr_dsar_mem;
109927 + struct auto_res_tables_sizes dsar_table_sizes;
109928 +} t_LnxWrpFmPortDev;
109929 +
109930 +typedef struct {
109931 + uint8_t id;
109932 + bool active;
109933 + uint64_t baseAddr;
109934 + uint32_t memSize;
109935 + t_WrpFmMacDevSettings settings;
109936 + t_Handle h_Dev;
109937 + t_Handle h_LnxWrpFmDev;
109938 +} t_LnxWrpFmMacDev;
109939 +
109940 +/* information about all active ports for an FMan.
109941 + * !Some ports may be disabled by u-boot, thus will not be available */
109942 +struct fm_active_ports {
109943 + uint32_t num_oh_ports;
109944 + uint32_t num_tx_ports;
109945 + uint32_t num_rx_ports;
109946 + uint32_t num_tx25_ports;
109947 + uint32_t num_rx25_ports;
109948 + uint32_t num_tx10_ports;
109949 + uint32_t num_rx10_ports;
109950 +};
109951 +
109952 +/* FMan resources precalculated at fm probe based
109953 + * on available FMan port. */
109954 +struct fm_resource_settings {
109955 + /* buffers - fifo sizes */
109956 + uint32_t tx1g_num_buffers;
109957 + uint32_t rx1g_num_buffers;
109958 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
109959 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
109960 + uint32_t tx10g_num_buffers;
109961 + uint32_t rx10g_num_buffers;
109962 + uint32_t oh_num_buffers;
109963 + uint32_t shared_ext_buffers;
109964 +
109965 + /* open DMAs */
109966 + uint32_t tx_1g_dmas;
109967 + uint32_t rx_1g_dmas;
109968 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
109969 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
109970 + uint32_t tx_10g_dmas;
109971 + uint32_t rx_10g_dmas;
109972 + uint32_t oh_dmas;
109973 + uint32_t shared_ext_open_dma;
109974 +
109975 + /* Tnums */
109976 + uint32_t tx_1g_tnums;
109977 + uint32_t rx_1g_tnums;
109978 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
109979 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
109980 + uint32_t tx_10g_tnums;
109981 + uint32_t rx_10g_tnums;
109982 + uint32_t oh_tnums;
109983 + uint32_t shared_ext_tnums;
109984 +};
109985 +
109986 +typedef struct {
109987 + uint8_t id;
109988 + char name[10];
109989 + bool active;
109990 + bool pcdActive;
109991 + bool prsActive;
109992 + bool kgActive;
109993 + bool ccActive;
109994 + bool plcrActive;
109995 + e_LnxWrpFmPortPcdDefUseCase defPcd;
109996 + uint32_t usedSchemes;
109997 + uint8_t totalNumOfSharedSchemes;
109998 + uint8_t sharedSchemesBase;
109999 + uint8_t numOfSchemesUsed;
110000 + uint8_t defNetEnvId;
110001 + uint64_t fmPhysBaseAddr;
110002 + uint64_t fmBaseAddr;
110003 + uint32_t fmMemSize;
110004 + uint64_t fmMuramPhysBaseAddr;
110005 + uint64_t fmMuramBaseAddr;
110006 + uint32_t fmMuramMemSize;
110007 + uint64_t fmRtcPhysBaseAddr;
110008 + uint64_t fmRtcBaseAddr;
110009 + uint32_t fmRtcMemSize;
110010 + uint64_t fmVspPhysBaseAddr;
110011 + uint64_t fmVspBaseAddr;
110012 + uint32_t fmVspMemSize;
110013 + int irq;
110014 + int err_irq;
110015 + t_WrpFmDevSettings fmDevSettings;
110016 + t_WrpFmPcdDevSettings fmPcdDevSettings;
110017 + t_Handle h_Dev;
110018 + uint16_t hcCh;
110019 +
110020 + t_Handle h_MuramDev;
110021 + t_Handle h_PcdDev;
110022 + t_Handle h_RtcDev;
110023 +
110024 + t_Handle h_DsarRxPort;
110025 + t_Handle h_DsarTxPort;
110026 +
110027 + t_LnxWrpFmPortDev hcPort;
110028 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
110029 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
110030 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
110031 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
110032 + struct fm_active_ports fm_active_ports_info;
110033 + struct fm_resource_settings fm_resource_settings_info;
110034 +
110035 + struct device *dev;
110036 + struct resource *res;
110037 + int major;
110038 + struct class *fm_class;
110039 + struct device_attribute *dev_attr_stats;
110040 + struct device_attribute *dev_attr_regs;
110041 + struct device_attribute *dev_attr_risc_load;
110042 +
110043 + struct device_attribute *dev_pcd_attr_stats;
110044 + struct device_attribute *dev_plcr_attr_regs;
110045 + struct device_attribute *dev_prs_attr_regs;
110046 + struct device_attribute *dev_fm_fpm_attr_regs;
110047 + struct device_attribute *dev_fm_kg_attr_regs;
110048 + struct device_attribute *dev_fm_kg_pe_attr_regs;
110049 + struct device_attribute *dev_attr_muram_free_size;
110050 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
110051 +
110052 +
110053 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
110054 +} t_LnxWrpFmDev;
110055 +
110056 +typedef struct {
110057 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
110058 +} t_LnxWrpFm;
110059 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
110060 +
110061 +
110062 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
110063 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
110064 +
110065 +
110066 +#if 0
110067 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
110068 +{
110069 + uint32_t schemeMask;
110070 + uint8_t i;
110071 +
110072 + if (!numSchemes)
110073 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110074 +
110075 + schemeMask = 0x80000000;
110076 + *p_BaseSchemeNum = 0xff;
110077 +
110078 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
110079 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
110080 + {
110081 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
110082 + numSchemes--;
110083 + if (*p_BaseSchemeNum==0xff)
110084 + *p_BaseSchemeNum = i;
110085 + }
110086 + else if (*p_BaseSchemeNum!=0xff)
110087 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
110088 +
110089 + if (numSchemes)
110090 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
110091 + return E_OK;
110092 +}
110093 +#endif
110094 +
110095 +void LnxWrpPCDIOCTLTypeChecking(void);
110096 +void LnxWrpPCDIOCTLEnumChecking(void);
110097 +
110098 +#endif /* __LNXWRP_FM_H__ */
110099 --- /dev/null
110100 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
110101 @@ -0,0 +1,1512 @@
110102 +/*
110103 + * Copyright 2008-2012 Freescale Semiconductor Inc.
110104 + *
110105 + * Redistribution and use in source and binary forms, with or without
110106 + * modification, are permitted provided that the following conditions are met:
110107 + * * Redistributions of source code must retain the above copyright
110108 + * notice, this list of conditions and the following disclaimer.
110109 + * * Redistributions in binary form must reproduce the above copyright
110110 + * notice, this list of conditions and the following disclaimer in the
110111 + * documentation and/or other materials provided with the distribution.
110112 + * * Neither the name of Freescale Semiconductor nor the
110113 + * names of its contributors may be used to endorse or promote products
110114 + * derived from this software without specific prior written permission.
110115 + *
110116 + *
110117 + * ALTERNATIVELY, this software may be distributed under the terms of the
110118 + * GNU General Public License ("GPL") as published by the Free Software
110119 + * Foundation, either version 2 of that License or (at your option) any
110120 + * later version.
110121 + *
110122 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
110123 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
110124 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
110125 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
110126 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
110127 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
110128 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
110129 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
110130 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
110131 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
110132 + */
110133 +
110134 +/*
110135 + @File lnxwrp_fm_port.c
110136 +
110137 + @Description FMD wrapper - FMan port functions.
110138 +
110139 +*/
110140 +
110141 +#include <linux/version.h>
110142 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
110143 +#define MODVERSIONS
110144 +#endif
110145 +#ifdef MODVERSIONS
110146 +#include <config/modversions.h>
110147 +#endif /* MODVERSIONS */
110148 +#include <linux/kernel.h>
110149 +#include <linux/module.h>
110150 +#include <linux/of_platform.h>
110151 +#include <linux/of_address.h>
110152 +#include <linux/cdev.h>
110153 +#include <linux/slab.h>
110154 +#include <linux/spinlock.h>
110155 +#ifndef CONFIG_FMAN_ARM
110156 +#include <linux/fsl/svr.h>
110157 +#endif
110158 +#include <linux/io.h>
110159 +
110160 +#include "sprint_ext.h"
110161 +#include "fm_common.h"
110162 +#include "lnxwrp_fsl_fman.h"
110163 +#include "fm_port_ext.h"
110164 +#if (DPAA_VERSION >= 11)
110165 +#include "fm_vsp_ext.h"
110166 +#endif /* DPAA_VERSION >= 11 */
110167 +#include "fm_ioctls.h"
110168 +#include "lnxwrp_resources.h"
110169 +#include "lnxwrp_sysfs_fm_port.h"
110170 +
110171 +#define __ERR_MODULE__ MODULE_FM
110172 +
110173 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
110174 +
110175 +/* TODO: duplicated, see lnxwrp_fm.c */
110176 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
110177 +do {\
110178 + if (i < max) {\
110179 + p_Entry = &p_Entrys[i];\
110180 + p_Entry->p_Function = _func;\
110181 + _param\
110182 + i++;\
110183 + } else {\
110184 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
110185 + ("Number of advanced-configuration entries exceeded"));\
110186 + } \
110187 +} while (0)
110188 +
110189 +#ifndef CONFIG_FMAN_ARM
110190 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
110191 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
110192 +#endif
110193 +
110194 +static volatile int hcFrmRcv/* = 0 */;
110195 +static spinlock_t lock;
110196 +
110197 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
110198 + struct qman_fq *fq,
110199 + const struct qm_dqrr_entry
110200 + *dq)
110201 +{
110202 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
110203 + unsigned long flags;
110204 +
110205 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110206 +{
110207 + /* extract the HC frame address */
110208 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
110209 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
110210 + int i;
110211 +
110212 + /* 32b byteswap of all data in the HC Frame */
110213 + for(i = 0; i < hcf_l / 4; ++i)
110214 + hcf_va[i] =
110215 + ___constant_swab32(hcf_va[i]);
110216 +}
110217 +#endif
110218 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
110219 + spin_lock_irqsave(&lock, flags);
110220 + hcFrmRcv--;
110221 + spin_unlock_irqrestore(&lock, flags);
110222 +
110223 + return qman_cb_dqrr_consume;
110224 +}
110225 +
110226 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
110227 + struct qman_fq *fq,
110228 + const struct qm_dqrr_entry *dq)
110229 +{
110230 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110231 + __func__);
110232 + return qman_cb_dqrr_consume;
110233 +}
110234 +
110235 +static void qm_err_cb(struct qman_portal *portal,
110236 + struct qman_fq *fq, const struct qm_mr_entry *msg)
110237 +{
110238 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
110239 + __func__);
110240 +}
110241 +
110242 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
110243 + uint32_t fqid,
110244 + uint32_t flags, uint16_t channel, uint8_t wq)
110245 +{
110246 + int _errno;
110247 + struct qman_fq *fq = NULL;
110248 + t_FmTestFq *p_FmtFq;
110249 + struct qm_mcc_initfq initfq;
110250 +
110251 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
110252 + if (!p_FmtFq) {
110253 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
110254 + return NULL;
110255 + }
110256 +
110257 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
110258 + ? qm_tx_conf_dqrr_cb
110259 + : qm_tx_dqrr_cb);
110260 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
110261 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
110262 + /* qm_err_cb wrongly called when the FQ is parked */
110263 + p_FmtFq->fq_base.cb.fqs = NULL;
110264 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
110265 + if (fqid == 0) {
110266 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
110267 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
110268 + } else {
110269 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
110270 + }
110271 +
110272 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
110273 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
110274 + XX_Free(p_FmtFq);
110275 + return NULL;
110276 + }
110277 + fq = &p_FmtFq->fq_base;
110278 +
110279 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
110280 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
110281 + initfq.fqd.dest.channel = channel;
110282 + initfq.fqd.dest.wq = wq;
110283 +
110284 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
110285 + if (unlikely(_errno < 0)) {
110286 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
110287 + ("FQ obj - qman_init_fq!!!"));
110288 + qman_destroy_fq(fq, 0);
110289 + XX_Free(p_FmtFq);
110290 + return NULL;
110291 + }
110292 + }
110293 +
110294 + DBG(TRACE,
110295 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
110296 + flags, channel, wq));
110297 +
110298 + return fq;
110299 +}
110300 +
110301 +static void FqFree(struct qman_fq *fq)
110302 +{
110303 + int _errno;
110304 +
110305 + _errno = qman_retire_fq(fq, NULL);
110306 + if (unlikely(_errno < 0))
110307 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110308 +
110309 + _errno = qman_oos_fq(fq);
110310 + if (unlikely(_errno < 0))
110311 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
110312 +
110313 + qman_destroy_fq(fq, 0);
110314 + XX_Free((t_FmTestFq *) fq);
110315 +}
110316 +
110317 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
110318 +{
110319 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
110320 + int _errno, timeout = 1000000;
110321 + unsigned long flags;
110322 +
110323 + ASSERT_COND(p_LnxWrpFmDev);
110324 +
110325 + spin_lock_irqsave(&lock, flags);
110326 + hcFrmRcv++;
110327 + spin_unlock_irqrestore(&lock, flags);
110328 +
110329 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
110330 +{
110331 + /* extract the HC frame address */
110332 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
110333 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
110334 + int i;
110335 +
110336 + /* 32b byteswap of all data in the HC Frame */
110337 + for(i = 0; i < hcf_l / 4; ++i)
110338 + hcf_va[i] =
110339 + ___constant_swab32(hcf_va[i]);
110340 +}
110341 +#endif
110342 +
110343 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
110344 + 0);
110345 + if (_errno)
110346 + RETURN_ERROR(MINOR, E_INVALID_STATE,
110347 + ("qman_enqueue() failed"));
110348 +
110349 + while (hcFrmRcv && --timeout) {
110350 + udelay(1);
110351 + cpu_relax();
110352 + }
110353 + if (timeout == 0) {
110354 + dump_stack();
110355 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
110356 + ("timeout waiting for Tx confirmation"));
110357 + return E_WRITE_FAILED;
110358 + }
110359 +
110360 + return E_OK;
110361 +}
110362 +
110363 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
110364 + *of_dev)
110365 +{
110366 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110367 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
110368 + struct device_node *fm_node, *port_node;
110369 + struct resource res;
110370 + const uint32_t *uint32_prop;
110371 + int _errno = 0, lenp;
110372 + uint32_t tmp_prop;
110373 +
110374 +#ifdef CONFIG_FMAN_P1023
110375 + static unsigned char have_oh_port/* = 0 */;
110376 +#endif
110377 +
110378 + port_node = of_node_get(of_dev->dev.of_node);
110379 +
110380 + /* Get the FM node */
110381 + fm_node = of_get_parent(port_node);
110382 + if (unlikely(fm_node == NULL)) {
110383 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
110384 + ("of_get_parent() = %d", _errno));
110385 + return NULL;
110386 + }
110387 +
110388 + p_LnxWrpFmDev =
110389 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
110390 + of_node_put(fm_node);
110391 +
110392 + /* if fm_probe() failed, no point in going further with port probing */
110393 + if (p_LnxWrpFmDev == NULL)
110394 + return NULL;
110395 +
110396 + uint32_prop =
110397 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
110398 + if (unlikely(uint32_prop == NULL)) {
110399 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110400 + ("of_get_property(%s, cell-index) failed",
110401 + port_node->full_name));
110402 + return NULL;
110403 + }
110404 + tmp_prop = be32_to_cpu(*uint32_prop);
110405 + if (WARN_ON(lenp != sizeof(uint32_t)))
110406 + return NULL;
110407 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh") ||
110408 + of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") ||
110409 + of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) {
110410 +#ifndef CONFIG_FMAN_ARM
110411 +#ifdef CONFIG_FMAN_P3040_P4080_P5020
110412 + /* On PPC FMan v2, OH ports start from cell-index 0x1 */
110413 + tmp_prop -= 0x1;
110414 +#else
110415 + /* On PPC FMan v3 (Low and High), OH ports start from
110416 + * cell-index 0x2
110417 + */
110418 + tmp_prop -= 0x2;
110419 +#endif // CONFIG_FMAN_P3040_P4080_P5020
110420 +#endif // CONFIG_FMAN_ARM
110421 +
110422 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
110423 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110424 + ("of_get_property(%s, cell-index) failed",
110425 + port_node->full_name));
110426 + return NULL;
110427 + }
110428 +
110429 +#ifdef CONFIG_FMAN_P1023
110430 + /* Beware, this can be done when there is only
110431 + one FMan to be initialized */
110432 + if (!have_oh_port) {
110433 + have_oh_port = 1; /* first OP/HC port
110434 + is used for host command */
110435 +#else
110436 + /* Here it is hardcoded the use of the OH port 1
110437 + (with cell-index 0) */
110438 + if (tmp_prop == 0) {
110439 +#endif
110440 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
110441 + p_LnxWrpFmPortDev->id = 0;
110442 + /*
110443 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
110444 + p_LnxWrpFmPortDev->id = *uint32_prop;
110445 + */
110446 + p_LnxWrpFmPortDev->settings.param.portType =
110447 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
110448 + } else {
110449 + p_LnxWrpFmPortDev =
110450 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
110451 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
110452 + p_LnxWrpFmPortDev->settings.param.portType =
110453 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
110454 + }
110455 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
110456 +
110457 + uint32_prop =
110458 + (uint32_t *) of_get_property(port_node,
110459 + "fsl,qman-channel-id",
110460 + &lenp);
110461 + if (uint32_prop == NULL) {
110462 + /*
110463 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
110464 + */
110465 + XX_Print("FM warning: missing fsl,qman-channel-id"
110466 + " for OH port.\n");
110467 + return NULL;
110468 + }
110469 + tmp_prop = be32_to_cpu(*uint32_prop);
110470 + if (WARN_ON(lenp != sizeof(uint32_t)))
110471 + return NULL;
110472 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110473 +
110474 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110475 + qmChannel = p_LnxWrpFmPortDev->txCh;
110476 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
110477 + tmp_prop -= 0x28;
110478 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
110479 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110480 + ("of_get_property(%s, cell-index) failed",
110481 + port_node->full_name));
110482 + return NULL;
110483 + }
110484 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110485 +
110486 + p_LnxWrpFmPortDev->id = tmp_prop;
110487 + p_LnxWrpFmPortDev->settings.param.portId =
110488 + p_LnxWrpFmPortDev->id;
110489 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
110490 +
110491 + uint32_prop = (uint32_t *) of_get_property(port_node,
110492 + "fsl,qman-channel-id", &lenp);
110493 + if (uint32_prop == NULL) {
110494 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110495 + ("missing fsl,qman-channel-id"));
110496 + return NULL;
110497 + }
110498 + tmp_prop = be32_to_cpu(*uint32_prop);
110499 + if (WARN_ON(lenp != sizeof(uint32_t)))
110500 + return NULL;
110501 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110502 + p_LnxWrpFmPortDev->
110503 + settings.param.specificParams.nonRxParams.qmChannel =
110504 + p_LnxWrpFmPortDev->txCh;
110505 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
110506 +#ifndef CONFIG_FMAN_ARM
110507 + /* On T102x, the 10G TX port IDs start from 0x28 */
110508 + if (IS_T1023_T1024)
110509 + tmp_prop -= 0x28;
110510 + else
110511 +#endif
110512 + tmp_prop -= 0x30;
110513 +
110514 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
110515 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110516 + ("of_get_property(%s, cell-index) failed",
110517 + port_node->full_name));
110518 + return NULL;
110519 + }
110520 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
110521 + FM_MAX_NUM_OF_1G_TX_PORTS];
110522 +#ifndef CONFIG_FMAN_ARM
110523 + if (IS_T1023_T1024)
110524 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
110525 +#endif
110526 +
110527 + p_LnxWrpFmPortDev->id = tmp_prop;
110528 + p_LnxWrpFmPortDev->settings.param.portId =
110529 + p_LnxWrpFmPortDev->id;
110530 + p_LnxWrpFmPortDev->settings.param.portType =
110531 + e_FM_PORT_TYPE_TX_10G;
110532 + uint32_prop = (uint32_t *) of_get_property(port_node,
110533 + "fsl,qman-channel-id", &lenp);
110534 + if (uint32_prop == NULL) {
110535 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110536 + ("missing fsl,qman-channel-id"));
110537 + return NULL;
110538 + }
110539 + tmp_prop = be32_to_cpu(*uint32_prop);
110540 + if (WARN_ON(lenp != sizeof(uint32_t)))
110541 + return NULL;
110542 + p_LnxWrpFmPortDev->txCh = tmp_prop;
110543 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
110544 + qmChannel = p_LnxWrpFmPortDev->txCh;
110545 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
110546 + tmp_prop -= 0x08;
110547 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
110548 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110549 + ("of_get_property(%s, cell-index) failed",
110550 + port_node->full_name));
110551 + return NULL;
110552 + }
110553 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110554 +
110555 + p_LnxWrpFmPortDev->id = tmp_prop;
110556 + p_LnxWrpFmPortDev->settings.param.portId =
110557 + p_LnxWrpFmPortDev->id;
110558 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
110559 + if (p_LnxWrpFmDev->pcdActive)
110560 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110561 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
110562 +#ifndef CONFIG_FMAN_ARM
110563 + /* On T102x, the 10G RX port IDs start from 0x08 */
110564 + if (IS_T1023_T1024)
110565 + tmp_prop -= 0x8;
110566 + else
110567 +#endif
110568 + tmp_prop -= 0x10;
110569 +
110570 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
110571 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110572 + ("of_get_property(%s, cell-index) failed",
110573 + port_node->full_name));
110574 + return NULL;
110575 + }
110576 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
110577 + FM_MAX_NUM_OF_1G_RX_PORTS];
110578 +
110579 +#ifndef CONFIG_FMAN_ARM
110580 + if (IS_T1023_T1024)
110581 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
110582 +#endif
110583 +
110584 + p_LnxWrpFmPortDev->id = tmp_prop;
110585 + p_LnxWrpFmPortDev->settings.param.portId =
110586 + p_LnxWrpFmPortDev->id;
110587 + p_LnxWrpFmPortDev->settings.param.portType =
110588 + e_FM_PORT_TYPE_RX_10G;
110589 + if (p_LnxWrpFmDev->pcdActive)
110590 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
110591 + } else {
110592 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
110593 + return NULL;
110594 + }
110595 +
110596 + _errno = of_address_to_resource(port_node, 0, &res);
110597 + if (unlikely(_errno < 0)) {
110598 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110599 + ("of_address_to_resource() = %d", _errno));
110600 + return NULL;
110601 + }
110602 +
110603 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
110604 + p_LnxWrpFmPortDev->baseAddr = 0;
110605 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
110606 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
110607 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
110608 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
110609 +
110610 + of_node_put(port_node);
110611 +
110612 + p_LnxWrpFmPortDev->active = TRUE;
110613 +
110614 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
110615 + /* for performance mode no OH port available. */
110616 + if (p_LnxWrpFmPortDev->settings.param.portType ==
110617 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110618 + p_LnxWrpFmPortDev->active = FALSE;
110619 +#endif
110620 +
110621 + return p_LnxWrpFmPortDev;
110622 +}
110623 +
110624 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
110625 + e_FmPortType portType,
110626 + uint8_t portId)
110627 +{
110628 + struct device_node *port_node;
110629 + const uint32_t *uint32_prop;
110630 + int lenp;
110631 + char *portTypeString;
110632 + uint32_t tmp_prop;
110633 +
110634 + switch(portType) {
110635 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
110636 + portTypeString = "fsl,fman-port-op-extended-args";
110637 + break;
110638 + case e_FM_PORT_TYPE_TX:
110639 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
110640 + break;
110641 + case e_FM_PORT_TYPE_TX_10G:
110642 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
110643 + break;
110644 + case e_FM_PORT_TYPE_RX:
110645 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
110646 + break;
110647 + case e_FM_PORT_TYPE_RX_10G:
110648 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
110649 + break;
110650 + default:
110651 + return NULL;
110652 + }
110653 +
110654 + for_each_child_of_node(fm_node, port_node) {
110655 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
110656 + if (unlikely(uint32_prop == NULL)) {
110657 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
110658 + ("of_get_property(%s, cell-index) failed",
110659 + port_node->full_name));
110660 + return NULL;
110661 + }
110662 + tmp_prop = be32_to_cpu(*uint32_prop);
110663 + if (WARN_ON(lenp != sizeof(uint32_t)))
110664 + return NULL;
110665 + if ((portId == tmp_prop) &&
110666 + (of_device_is_compatible(port_node, portTypeString))) {
110667 + return port_node;
110668 + }
110669 + }
110670 +
110671 + return NULL;
110672 +}
110673 +
110674 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110675 +{
110676 + struct device_node *fm_node, *port_node;
110677 + t_Error err;
110678 + t_FmPortRsrc portRsrc;
110679 + const uint32_t *uint32_prop;
110680 + /*const char *str_prop;*/
110681 + int lenp;
110682 +#ifdef CONFIG_FMAN_PFC
110683 + uint8_t i, id, num_pools;
110684 + t_FmBufPoolDepletion poolDepletion;
110685 +
110686 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
110687 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
110688 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
110689 + poolDepletion.singlePoolModeEnable = true;
110690 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110691 + extBufPools.numOfPoolsUsed;
110692 + for (i = 0; i < num_pools; i++) {
110693 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
110694 + extBufPools.extBufPool[i].id;
110695 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
110696 + }
110697 +
110698 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
110699 + poolDepletion.pfcPrioritiesEn[i] = true;
110700 +
110701 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
110702 + &poolDepletion);
110703 + if (err != E_OK)
110704 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
110705 + }
110706 +#endif
110707 +
110708 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110709 + if (!fm_node) /* no advance parameters for FMan */
110710 + return E_OK;
110711 +
110712 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110713 + p_LnxWrpFmPortDev->settings.param.portType,
110714 + p_LnxWrpFmPortDev->settings.param.portId);
110715 + if (!port_node) /* no advance parameters for FMan-Port */
110716 + return E_OK;
110717 +
110718 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
110719 + if (uint32_prop) {
110720 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110721 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110722 +
110723 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110724 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110725 +
110726 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
110727 + &portRsrc)) != E_OK)
110728 + RETURN_ERROR(MINOR, err, NO_MSG);
110729 + }
110730 +
110731 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
110732 + if (uint32_prop) {
110733 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110734 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110735 +
110736 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110737 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110738 +
110739 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
110740 + &portRsrc)) != E_OK)
110741 + RETURN_ERROR(MINOR, err, NO_MSG);
110742 + }
110743 +
110744 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
110745 + if (uint32_prop) {
110746 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110747 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110748 +
110749 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
110750 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
110751 +
110752 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
110753 + &portRsrc)) != E_OK)
110754 + RETURN_ERROR(MINOR, err, NO_MSG);
110755 + }
110756 +
110757 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
110758 + if (uint32_prop) {
110759 + if (WARN_ON(lenp != sizeof(uint32_t)))
110760 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110761 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
110762 + be32_to_cpu(uint32_prop[0]))) != E_OK)
110763 + RETURN_ERROR(MINOR, err, NO_MSG);
110764 + }
110765 +
110766 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
110767 + &lenp);
110768 + if (uint32_prop) {
110769 +
110770 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
110771 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110772 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
110773 + e_FM_PORT_TYPE_RX) &&
110774 + (p_LnxWrpFmPortDev->settings.param.portType !=
110775 + e_FM_PORT_TYPE_RX_10G))
110776 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
110777 + ("Auto Response is an Rx port atribute."));
110778 +
110779 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
110780 +
110781 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
110782 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110783 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
110784 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110785 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
110786 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110787 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
110788 + (uint16_t)be32_to_cpu(uint32_prop[3]);
110789 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
110790 + (uint16_t)be32_to_cpu(uint32_prop[4]);
110791 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
110792 + (uint16_t)be32_to_cpu(uint32_prop[5]);
110793 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
110794 + (uint16_t)be32_to_cpu(uint32_prop[6]);
110795 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
110796 + (uint16_t)be32_to_cpu(uint32_prop[7]);
110797 +
110798 + uint32_prop = (uint32_t *)of_get_property(port_node,
110799 + "ar-filters-sizes", &lenp);
110800 + if (uint32_prop) {
110801 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
110802 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110803 +
110804 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
110805 + (uint16_t)be32_to_cpu(uint32_prop[0]);
110806 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
110807 + (uint16_t)be32_to_cpu(uint32_prop[1]);
110808 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
110809 + (uint16_t)be32_to_cpu(uint32_prop[2]);
110810 + }
110811 +
110812 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
110813 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
110814 + RETURN_ERROR(MINOR, err, NO_MSG);
110815 + }
110816 +
110817 + of_node_put(port_node);
110818 + of_node_put(fm_node);
110819 +
110820 + return E_OK;
110821 +}
110822 +
110823 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110824 +{
110825 + struct device_node *fm_node, *port_node;
110826 + t_Error err;
110827 + const uint32_t *uint32_prop;
110828 + /*const char *str_prop;*/
110829 + int lenp;
110830 +
110831 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110832 + if (!fm_node) /* no advance parameters for FMan */
110833 + return E_OK;
110834 +
110835 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110836 + p_LnxWrpFmPortDev->settings.param.portType,
110837 + p_LnxWrpFmPortDev->settings.param.portId);
110838 + if (!port_node) /* no advance parameters for FMan-Port */
110839 + return E_OK;
110840 +
110841 +#if (DPAA_VERSION >= 11)
110842 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
110843 + if (uint32_prop) {
110844 + t_FmPortVSPAllocParams portVSPAllocParams;
110845 + t_FmVspParams fmVspParams;
110846 + t_LnxWrpFmDev *p_LnxWrpFmDev;
110847 + uint8_t portId;
110848 +
110849 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
110850 +
110851 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110852 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
110853 +
110854 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
110855 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
110856 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110857 + p_LnxWrpFmPortDev->settings.frag_enabled))
110858 + return E_OK;
110859 +
110860 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
110861 + memset(&fmVspParams, 0, sizeof(fmVspParams));
110862 +
110863 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
110864 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
110865 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
110866 +
110867 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
110868 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
110869 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
110870 +
110871 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
110872 + {
110873 + portId = fmVspParams.portParams.portId;
110874 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
110875 +#ifndef CONFIG_FMAN_ARM
110876 + if (!(IS_T1023_T1024))
110877 +#endif
110878 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
110879 + }
110880 + portVSPAllocParams.h_FmTxPort =
110881 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
110882 + fmVspParams.liodnOffset =
110883 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
110884 + memcpy(&fmVspParams.extBufPools,
110885 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
110886 + sizeof(t_FmExtPools));
110887 + }
110888 + else
110889 + {
110890 + memcpy(&fmVspParams.extBufPools,
110891 + &p_LnxWrpFmPortDev->opExtPools,
110892 + sizeof(t_FmExtPools));
110893 + }
110894 +
110895 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
110896 + &portVSPAllocParams)) != E_OK)
110897 + RETURN_ERROR(MINOR, err, NO_MSG);
110898 +
110899 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
110900 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
110901 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
110902 + return E_OK;
110903 +
110904 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
110905 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
110906 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
110907 +
110908 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
110909 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
110910 + RETURN_ERROR(MINOR, err, NO_MSG);
110911 +
110912 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
110913 + RETURN_ERROR(MINOR, err, NO_MSG);
110914 + }
110915 +#else
110916 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
110917 +#endif /* (DPAA_VERSION >= 11) */
110918 +
110919 + of_node_put(port_node);
110920 + of_node_put(fm_node);
110921 +
110922 + return E_OK;
110923 +}
110924 +
110925 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110926 +{
110927 + t_LnxWrpFmDev *p_LnxWrpFmDev =
110928 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110929 + struct resource *dev_res;
110930 +
110931 + if (!p_LnxWrpFmPortDev->active)
110932 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110933 + ("FM port not configured!!!"));
110934 +
110935 + dev_res =
110936 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
110937 + p_LnxWrpFmPortDev->phys_baseAddr,
110938 + p_LnxWrpFmPortDev->memSize,
110939 + "fman-port-hc");
110940 + if (unlikely(dev_res == NULL))
110941 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
110942 + ("__devm_request_region() failed"));
110943 + p_LnxWrpFmPortDev->baseAddr =
110944 + PTR_TO_UINT(devm_ioremap
110945 + (p_LnxWrpFmDev->dev,
110946 + p_LnxWrpFmPortDev->phys_baseAddr,
110947 + p_LnxWrpFmPortDev->memSize));
110948 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
110949 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
110950 + ("devm_ioremap() failed"));
110951 +
110952 + p_LnxWrpFmPortDev->settings.param.baseAddr =
110953 + p_LnxWrpFmPortDev->baseAddr;
110954 +
110955 + return E_OK;
110956 +}
110957 +
110958 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
110959 +{
110960 +#define MY_ADV_CONFIG_CHECK_END \
110961 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
110962 + ("Advanced configuration routine"));\
110963 + if (errCode != E_OK)\
110964 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
110965 + }
110966 +
110967 + int i = 0;
110968 +
110969 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
110970 + return E_INVALID_STATE;
110971 +
110972 + p_LnxWrpFmPortDev->h_Dev =
110973 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
110974 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
110975 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
110976 +
110977 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
110978 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
110979 + e_FM_PORT_TYPE_TX_10G)
110980 + || (p_LnxWrpFmPortDev->settings.param.portType ==
110981 + e_FM_PORT_TYPE_TX)) {
110982 + t_Error errCode = E_OK;
110983 + errCode =
110984 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
110985 + TRUE);
110986 + if (errCode != E_OK)
110987 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110988 + errCode =
110989 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
110990 + e_FM_PORT_DEQ_FULL_PREFETCH);
110991 + if (errCode
110992 + != E_OK)
110993 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
110994 + }
110995 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
110996 +
110997 +#ifndef CONFIG_FMAN_ARM
110998 +#ifdef FM_BCB_ERRATA_BMI_SW001
110999 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
111000 +#define SVR_SECURITY_MASK 0x00080000
111001 +#define SVR_PERSONALITY_MASK 0x0000FF00
111002 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
111003 +#define SVR_B4860_REV1_VALUE 0x86800010
111004 +
111005 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111006 + e_FM_PORT_TYPE_RX_10G) ||
111007 + (p_LnxWrpFmPortDev->settings.param.portType ==
111008 + e_FM_PORT_TYPE_RX)) {
111009 + unsigned int svr;
111010 +
111011 + svr = mfspr(SPRN_SVR);
111012 +
111013 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
111014 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
111015 + }
111016 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
111017 +#endif /* CONFIG_FMAN_ARM */
111018 +/* Call the driver's advanced configuration routines, if requested:
111019 + Compare the function pointer of each entry to the available routines,
111020 + and invoke the matching routine with proper casting of arguments. */
111021 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
111022 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
111023 +
111024 +/* TODO: Change this MACRO */
111025 + ADV_CONFIG_CHECK_START(
111026 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
111027 +
111028 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111029 + FM_PORT_ConfigBufferPrefixContent,
111030 + NCSW_PARAMS(1,
111031 + (t_FmBufferPrefixContent *)))
111032 +
111033 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111034 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111035 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
111036 +
111037 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
111038 + FM_PORT_ConfigExtBufPools,
111039 + NCSW_PARAMS(1, (t_FmExtPools *)))
111040 +
111041 + /* this define contains an else */
111042 + MY_ADV_CONFIG_CHECK_END
111043 + }
111044 +
111045 + /* Advance to next advanced configuration entry */
111046 + i++;
111047 + }
111048 +
111049 +
111050 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
111051 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
111052 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
111053 + FM_PORT_FRM_ERR_IPR_NCSP |
111054 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
111055 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111056 + }
111057 +
111058 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111059 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111060 +
111061 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
111062 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111063 +
111064 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
111065 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111066 +
111067 +/* FMan Fifo sizes behind the scene":
111068 + * Using the following formulae (*), under a set of simplifying assumptions (.):
111069 + * . all ports are configured in Normal Mode (rather than Independent Mode)
111070 + * . the DPAA Eth driver allocates buffers of size:
111071 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
111072 + * + DPA_HASH_RESULTS_SIZE, i.e.:
111073 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
111074 + * MAXFRM + 66
111075 + * . excessive buffer pools not accounted for
111076 + *
111077 + * * for Rx ports on P4080:
111078 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
111079 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
111080 + * add up to 256 to the above
111081 + *
111082 + * * for Rx ports on P1023:
111083 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
111084 + * if at least 2 bpools are configured
111085 + * . IFSZ = 8 * 256, if only a single bpool is configured
111086 + *
111087 + * * for Tx ports:
111088 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
111089 + * + FMBM_TFP[DPDE] * 256, i.e.:
111090 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
111091 + *
111092 + * * for OH ports on P4080:
111093 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
111094 + * * for OH ports on P1023:
111095 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
111096 + * * for both P4080 and P1023:
111097 + * . (conservative decisions, assuming that BMI must bring the entire
111098 + * frame, not only the frame header)
111099 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
111100 + * add up to 256 to the above
111101 + *
111102 + * . for P4080/P5020/P3041/P2040, DPDE is:
111103 + * > 0 or 1, for 1Gb ports, HW default: 0
111104 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
111105 + * . for P1023, DPDE should be 1
111106 + *
111107 + * . for P1023, MXT is in range (0..31)
111108 + * . for P4080, MXT is in range (0..63)
111109 + *
111110 + */
111111 +#if 0
111112 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
111113 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
111114 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
111115 +#endif
111116 + return E_OK;
111117 +}
111118 +
111119 +void fm_set_rx_port_params(struct fm_port *port,
111120 + struct fm_port_params *params)
111121 +{
111122 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111123 + int i;
111124 +
111125 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
111126 + params->errq;
111127 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
111128 + params->defq;
111129 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
111130 + numOfPoolsUsed = params->num_pools;
111131 + for (i = 0; i < params->num_pools; i++) {
111132 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111133 + extBufPools.extBufPool[i].id =
111134 + params->pool_param[i].id;
111135 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
111136 + extBufPools.extBufPool[i].size =
111137 + params->pool_param[i].size;
111138 + }
111139 +
111140 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111141 + params->priv_data_size;
111142 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111143 + params->parse_results;
111144 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111145 + params->hash_results;
111146 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111147 + params->time_stamp;
111148 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111149 + params->data_align;
111150 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111151 + params->manip_extra_space;
111152 +
111153 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111154 + FM_MAX_NUM_OF_ADV_SETTINGS)
111155 +
111156 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111157 + ARGS(1,
111158 + (&p_LnxWrpFmPortDev->
111159 + buffPrefixContent)));
111160 +
111161 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111162 +}
111163 +EXPORT_SYMBOL(fm_set_rx_port_params);
111164 +
111165 +/* this function is called from oh_probe as well, thus it contains oh port
111166 + * specific parameters (make sure everything is checked) */
111167 +void fm_set_tx_port_params(struct fm_port *port,
111168 + struct fm_port_params *params)
111169 +{
111170 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
111171 +
111172 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
111173 + params->errq;
111174 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
111175 + dfltFqid = params->defq;
111176 +
111177 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
111178 + params->priv_data_size;
111179 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
111180 + params->parse_results;
111181 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
111182 + params->hash_results;
111183 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
111184 + params->time_stamp;
111185 + p_LnxWrpFmPortDev->settings.frag_enabled =
111186 + params->frag_enable;
111187 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
111188 + params->data_align;
111189 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
111190 + params->manip_extra_space;
111191 +
111192 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
111193 + FM_MAX_NUM_OF_ADV_SETTINGS)
111194 +
111195 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
111196 + ARGS(1,
111197 + (&p_LnxWrpFmPortDev->
111198 + buffPrefixContent)));
111199 +
111200 + /* oh port specific parameter (for fragmentation only) */
111201 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
111202 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
111203 + params->num_pools) {
111204 + int i;
111205 +
111206 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
111207 + for (i = 0; i < params->num_pools; i++) {
111208 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
111209 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
111210 + }
111211 +
111212 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
111213 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
111214 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
111215 + }
111216 +
111217 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
111218 +}
111219 +EXPORT_SYMBOL(fm_set_tx_port_params);
111220 +
111221 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
111222 + t_Handle h_fm_mac,
111223 + int mac_id)
111224 +{
111225 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
111226 +
111227 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
111228 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
111229 +}
111230 +EXPORT_SYMBOL(fm_mac_set_handle);
111231 +
111232 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
111233 + e_FmPcdExceptions exception)
111234 +{
111235 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111236 +
111237 + ASSERT_COND(p_LnxWrpFmDev);
111238 +
111239 + DBG(INFO, ("got fm-pcd exception %d", exception));
111240 +
111241 + /* do nothing */
111242 + UNUSED(exception);
111243 +}
111244 +
111245 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
111246 + e_FmPcdExceptions exception,
111247 + uint16_t index)
111248 +{
111249 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
111250 +
111251 + ASSERT_COND(p_LnxWrpFmDev);
111252 +
111253 + DBG(INFO,
111254 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
111255 +
111256 + /* do nothing */
111257 + UNUSED(exception);
111258 + UNUSED(index);
111259 +}
111260 +
111261 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111262 +{
111263 + spin_lock_init(&lock);
111264 +
111265 + if (p_LnxWrpFmDev->pcdActive) {
111266 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
111267 + t_FmPcdParams fmPcdParams;
111268 + t_Error err;
111269 +
111270 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
111271 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
111272 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
111273 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
111274 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
111275 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
111276 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
111277 +
111278 +#ifndef CONFIG_GUEST_PARTITION
111279 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
111280 + if (fmPcdParams.kgSupport)
111281 + fmPcdParams.f_ExceptionId =
111282 + LnxwrpFmPcdDevIndexedExceptionsCb;
111283 + fmPcdParams.h_App = p_LnxWrpFmDev;
111284 +#endif /* !CONFIG_GUEST_PARTITION */
111285 +
111286 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
111287 + fmPcdParams.numOfSchemes = 0;
111288 + fmPcdParams.numOfClsPlanEntries = 0;
111289 + fmPcdParams.partitionId = 0;
111290 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
111291 + fmPcdParams.useHostCommand = TRUE;
111292 +
111293 + p_LnxWrpFmDev->hc_tx_fq =
111294 + FqAlloc(p_LnxWrpFmDev,
111295 + 0,
111296 + QMAN_FQ_FLAG_TO_DCPORTAL,
111297 + p_LnxWrpFmPortDev->txCh, 0);
111298 + if (!p_LnxWrpFmDev->hc_tx_fq)
111299 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111300 + ("Frame queue allocation failed..."));
111301 +
111302 + p_LnxWrpFmDev->hc_tx_conf_fq =
111303 + FqAlloc(p_LnxWrpFmDev,
111304 + 0,
111305 + QMAN_FQ_FLAG_NO_ENQUEUE,
111306 + p_LnxWrpFmDev->hcCh, 1);
111307 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
111308 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111309 + ("Frame queue allocation failed..."));
111310 +
111311 + p_LnxWrpFmDev->hc_tx_err_fq =
111312 + FqAlloc(p_LnxWrpFmDev,
111313 + 0,
111314 + QMAN_FQ_FLAG_NO_ENQUEUE,
111315 + p_LnxWrpFmDev->hcCh, 2);
111316 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
111317 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
111318 + ("Frame queue allocation failed..."));
111319 +
111320 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
111321 + fmPcdParams.hc.portId =
111322 + p_LnxWrpFmPortDev->settings.param.portId;
111323 + fmPcdParams.hc.liodnBase =
111324 + p_LnxWrpFmPortDev->settings.param.liodnBase;
111325 + fmPcdParams.hc.errFqid =
111326 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
111327 + fmPcdParams.hc.confFqid =
111328 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
111329 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
111330 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
111331 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
111332 +
111333 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
111334 + if (!p_LnxWrpFmDev->h_PcdDev)
111335 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
111336 +
111337 + err =
111338 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
111339 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
111340 + if (err != E_OK)
111341 + RETURN_ERROR(MAJOR, err, NO_MSG);
111342 +
111343 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
111344 + if (err != E_OK)
111345 + RETURN_ERROR(MAJOR, err, NO_MSG);
111346 +
111347 + if (p_LnxWrpFmDev->err_irq == 0) {
111348 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111349 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
111350 + FALSE);
111351 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111352 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
111353 + FALSE);
111354 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111355 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
111356 + FALSE);
111357 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111358 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
111359 + FALSE);
111360 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111361 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
111362 + FALSE);
111363 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111364 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
111365 + FALSE);
111366 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111367 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
111368 + FALSE);
111369 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
111370 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
111371 + FALSE);
111372 + }
111373 + }
111374 +
111375 + return E_OK;
111376 +}
111377 +
111378 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
111379 +{
111380 +
111381 + if (p_LnxWrpFmDev->h_PcdDev)
111382 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
111383 +
111384 + if (p_LnxWrpFmDev->hc_tx_err_fq)
111385 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
111386 +
111387 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
111388 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
111389 +
111390 + if (p_LnxWrpFmDev->hc_tx_fq)
111391 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
111392 +}
111393 +
111394 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
111395 +{
111396 + t_LnxWrpFmDev *p_LnxWrpFmDev =
111397 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111398 +
111399 + if (!p_LnxWrpFmPortDev->active)
111400 + return;
111401 +
111402 + if (p_LnxWrpFmPortDev->h_Dev)
111403 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
111404 +
111405 + devm_iounmap(p_LnxWrpFmDev->dev,
111406 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
111407 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
111408 + p_LnxWrpFmPortDev->phys_baseAddr,
111409 + p_LnxWrpFmPortDev->memSize);
111410 +}
111411 +
111412 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
111413 +{
111414 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111415 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111416 + struct device *dev;
111417 +
111418 + dev = &of_dev->dev;
111419 +
111420 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
111421 + if (p_LnxWrpFmPortDev == NULL)
111422 + return -EIO;
111423 + /* Port can be inactive, thus will not be probed:
111424 + - in performance mode, OH ports are disabled
111425 + ...
111426 + */
111427 + if (!p_LnxWrpFmPortDev->active)
111428 + return 0;
111429 +
111430 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
111431 + return -EIO;
111432 +
111433 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
111434 +
111435 + if (p_LnxWrpFmPortDev->settings.param.portType ==
111436 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
111437 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
111438 +
111439 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111440 +
111441 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
111442 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111443 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111444 + p_LnxWrpFmPortDev->minor =
111445 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
111446 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111447 + e_FM_PORT_TYPE_RX_10G) {
111448 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111449 + p_LnxWrpFmDev->name,
111450 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
111451 + p_LnxWrpFmPortDev->minor =
111452 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
111453 + DEV_FM_RX_PORTS_MINOR_BASE;
111454 +#ifndef CONFIG_FMAN_ARM
111455 + if (IS_T1023_T1024) {
111456 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
111457 + p_LnxWrpFmDev->name,
111458 + p_LnxWrpFmPortDev->id);
111459 + p_LnxWrpFmPortDev->minor =
111460 + p_LnxWrpFmPortDev->id +
111461 + DEV_FM_RX_PORTS_MINOR_BASE;
111462 + }
111463 +#endif
111464 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111465 + e_FM_PORT_TYPE_TX) {
111466 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111467 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111468 + p_LnxWrpFmPortDev->minor =
111469 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
111470 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111471 + e_FM_PORT_TYPE_TX_10G) {
111472 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111473 + p_LnxWrpFmDev->name,
111474 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
111475 + p_LnxWrpFmPortDev->minor =
111476 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
111477 + DEV_FM_TX_PORTS_MINOR_BASE;
111478 +#ifndef CONFIG_FMAN_ARM
111479 + if (IS_T1023_T1024) {
111480 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
111481 + p_LnxWrpFmDev->name,
111482 + p_LnxWrpFmPortDev->id);
111483 + p_LnxWrpFmPortDev->minor =
111484 + p_LnxWrpFmPortDev->id +
111485 + DEV_FM_TX_PORTS_MINOR_BASE;
111486 + }
111487 +#endif
111488 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111489 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
111490 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111491 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
111492 + p_LnxWrpFmPortDev->minor =
111493 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
111494 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
111495 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
111496 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
111497 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
111498 + p_LnxWrpFmPortDev->minor =
111499 + p_LnxWrpFmPortDev->id + 1 +
111500 + DEV_FM_OH_PORTS_MINOR_BASE;
111501 + }
111502 +
111503 + device_create(p_LnxWrpFmDev->fm_class, NULL,
111504 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
111505 + NULL, p_LnxWrpFmPortDev->name);
111506 +
111507 + /* create sysfs entries for stats and regs */
111508 +
111509 + if (fm_port_sysfs_create(dev) != 0) {
111510 + FreeFmPortDev(p_LnxWrpFmPortDev);
111511 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
111512 + ("Unable to create sys entry - fm port!!!"));
111513 + return -EIO;
111514 + }
111515 +
111516 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
111517 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
111518 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
111519 +
111520 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
111521 +
111522 + return 0;
111523 +}
111524 +
111525 +static int fm_port_remove(struct platform_device *of_dev)
111526 +{
111527 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
111528 + t_LnxWrpFmDev *p_LnxWrpFmDev;
111529 + struct device *dev;
111530 +
111531 + dev = &of_dev->dev;
111532 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
111533 +
111534 + fm_port_sysfs_destroy(dev);
111535 +
111536 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
111537 + device_destroy(p_LnxWrpFmDev->fm_class,
111538 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
111539 +
111540 + FreeFmPortDev(p_LnxWrpFmPortDev);
111541 +
111542 + dev_set_drvdata(dev, NULL);
111543 +
111544 + return 0;
111545 +}
111546 +
111547 +static const struct of_device_id fm_port_match[] = {
111548 + {
111549 + .compatible = "fsl,fman-port-oh"},
111550 + {
111551 + .compatible = "fsl,fman-v2-port-oh"},
111552 + {
111553 + .compatible = "fsl,fman-v3-port-oh"},
111554 + {
111555 + .compatible = "fsl,fman-port-1g-rx"},
111556 + {
111557 + .compatible = "fsl,fman-port-10g-rx"},
111558 + {
111559 + .compatible = "fsl,fman-port-1g-tx"},
111560 + {
111561 + .compatible = "fsl,fman-port-10g-tx"},
111562 + {}
111563 +};
111564 +
111565 +#ifndef MODULE
111566 +MODULE_DEVICE_TABLE(of, fm_port_match);
111567 +#endif /* !MODULE */
111568 +
111569 +static struct platform_driver fm_port_driver = {
111570 +
111571 + .driver = {
111572 + .name = "fsl-fman-port",
111573 + .of_match_table = fm_port_match,
111574 + .owner = THIS_MODULE,
111575 + },
111576 + .probe = fm_port_probe,
111577 + .remove = fm_port_remove
111578 +};
111579 +
111580 +
111581 +t_Error LNXWRP_FM_Port_Init(void)
111582 +{
111583 + /* Register to the DTB for basic FM port API */
111584 + if (platform_driver_register(&fm_port_driver))
111585 + return E_NO_DEVICE;
111586 +
111587 + return E_OK;
111588 +}
111589 +
111590 +void LNXWRP_FM_Port_Free(void)
111591 +{
111592 + platform_driver_unregister(&fm_port_driver);
111593 +}
111594 +
111595 +static int __init __cold fm_port_load(void)
111596 +{
111597 + if (LNXWRP_FM_Port_Init() != E_OK) {
111598 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
111599 + return -ENODEV;
111600 + }
111601 +
111602 + printk(KERN_CRIT "Freescale FM Ports module\n");
111603 +
111604 + return 0;
111605 +}
111606 +
111607 +static void __exit __cold fm_port_unload(void)
111608 +{
111609 + LNXWRP_FM_Port_Free();
111610 +}
111611 +
111612 +module_init(fm_port_load);
111613 +module_exit(fm_port_unload);
111614 --- /dev/null
111615 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
111616 @@ -0,0 +1,4854 @@
111617 +/*
111618 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111619 + *
111620 + * Redistribution and use in source and binary forms, with or without
111621 + * modification, are permitted provided that the following conditions are met:
111622 + * * Redistributions of source code must retain the above copyright
111623 + * notice, this list of conditions and the following disclaimer.
111624 + * * Redistributions in binary form must reproduce the above copyright
111625 + * notice, this list of conditions and the following disclaimer in the
111626 + * documentation and/or other materials provided with the distribution.
111627 + * * Neither the name of Freescale Semiconductor nor the
111628 + * names of its contributors may be used to endorse or promote products
111629 + * derived from this software without specific prior written permission.
111630 + *
111631 + *
111632 + * ALTERNATIVELY, this software may be distributed under the terms of the
111633 + * GNU General Public License ("GPL") as published by the Free Software
111634 + * Foundation, either version 2 of that License or (at your option) any
111635 + * later version.
111636 + *
111637 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111638 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111639 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111640 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111641 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111642 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111643 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111644 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111645 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111646 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111647 + */
111648 +
111649 +/*
111650 + @File lnxwrp_ioctls_fm.c
111651 + @Author Shlomi Gridish
111652 + @Description FM Linux wrapper functions.
111653 +*/
111654 +
111655 +/* Linux Headers ------------------- */
111656 +#include <linux/version.h>
111657 +
111658 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111659 +#define MODVERSIONS
111660 +#endif
111661 +#ifdef MODVERSIONS
111662 +#include <config/modversions.h>
111663 +#endif /* MODVERSIONS */
111664 +
111665 +#include <linux/kernel.h>
111666 +#include <linux/module.h>
111667 +#include <linux/slab.h>
111668 +#include <linux/fs.h>
111669 +#include <linux/cdev.h>
111670 +#include <linux/device.h>
111671 +#include <linux/irq.h>
111672 +#include <linux/interrupt.h>
111673 +#include <linux/io.h>
111674 +#include <linux/ioport.h>
111675 +#include <linux/of_platform.h>
111676 +#include <linux/uaccess.h>
111677 +#include <asm/errno.h>
111678 +#ifndef CONFIG_FMAN_ARM
111679 +#include <sysdev/fsl_soc.h>
111680 +#include <linux/fsl/svr.h>
111681 +#endif
111682 +
111683 +#if defined(CONFIG_COMPAT)
111684 +#include <linux/compat.h>
111685 +#endif
111686 +
111687 +#include "part_ext.h"
111688 +#include "fm_ioctls.h"
111689 +#include "fm_pcd_ioctls.h"
111690 +#include "fm_port_ioctls.h"
111691 +#include "fm_vsp_ext.h"
111692 +
111693 +#ifndef CONFIG_FMAN_ARM
111694 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111695 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111696 +#endif
111697 +
111698 +#define __ERR_MODULE__ MODULE_FM
111699 +
111700 +#if defined(CONFIG_COMPAT)
111701 +#include "lnxwrp_ioctls_fm_compat.h"
111702 +#endif
111703 +
111704 +#include "lnxwrp_fm.h"
111705 +
111706 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
111707 +
111708 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
111709 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
111710 +#error Error: please synchronize IOC_ defines!
111711 +#endif
111712 +
111713 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
111714 +#error Error: please synchronize IOC_ defines!
111715 +#endif
111716 +
111717 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
111718 +#error Error: please synchronize IOC_ defines!
111719 +#endif
111720 +
111721 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
111722 +#error Error: please synchronize IOC_ defines!
111723 +#endif
111724 +
111725 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
111726 +#error Error: please synchronize IOC_ defines!
111727 +#endif
111728 +
111729 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
111730 +#error Error: please synchronize IOC_ defines!
111731 +#endif
111732 +
111733 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
111734 +#error Error: please synchronize IOC_ defines!
111735 +#endif
111736 +
111737 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
111738 +#error Error: please synchronize IOC_ defines!
111739 +#endif
111740 +
111741 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
111742 +#error Error: please synchronize IOC_ defines!
111743 +#endif
111744 +
111745 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
111746 +#error Error: please synchronize IOC_ defines!
111747 +#endif
111748 +
111749 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
111750 +#error Error: please synchronize IOC_ defines!
111751 +#endif
111752 +
111753 +#if DPAA_VERSION >= 11
111754 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
111755 +#error Error: please synchronize IOC_ defines!
111756 +#endif
111757 +#endif
111758 +
111759 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
111760 +#error Error: please synchronize IOC_ defines!
111761 +#endif
111762 +
111763 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
111764 +#error Error: please synchronize IOC_ defines!
111765 +#endif
111766 +
111767 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
111768 +#error Error: please synchronize IOC_ defines!
111769 +#endif
111770 +
111771 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
111772 +#error Error: please synchronize IOC_ defines!
111773 +#endif
111774 +
111775 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
111776 +#error Error: please synchronize IOC_ defines!
111777 +#endif
111778 +
111779 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
111780 +#error Error: please synchronize IOC_ defines!
111781 +#endif
111782 +
111783 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
111784 +#error Error: please synchronize IOC_ defines!
111785 +#endif
111786 +
111787 +/* net_ioctls.h === net_ext.h assertions */
111788 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
111789 +#error Error: please synchronize IOC_ defines!
111790 +#endif
111791 +
111792 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
111793 +#error Error: please synchronize IOC_ defines!
111794 +#endif
111795 +
111796 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
111797 +#error Error: please synchronize IOC_ defines!
111798 +#endif
111799 +
111800 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
111801 +#error Error: please synchronize IOC_ defines!
111802 +#endif
111803 +
111804 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
111805 +#error Error: please synchronize IOC_ defines!
111806 +#endif
111807 +
111808 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
111809 +#error Error: please synchronize IOC_ defines!
111810 +#endif
111811 +
111812 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
111813 +#error Error: please synchronize IOC_ defines!
111814 +#endif
111815 +
111816 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
111817 +#error Error: please synchronize IOC_ defines!
111818 +#endif
111819 +
111820 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
111821 +#error Error: please synchronize IOC_ defines!
111822 +#endif
111823 +
111824 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
111825 +#error Error: please synchronize IOC_ defines!
111826 +#endif
111827 +
111828 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
111829 +#error Error: please synchronize IOC_ defines!
111830 +#endif
111831 +
111832 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
111833 +#error Error: please synchronize IOC_ defines!
111834 +#endif
111835 +
111836 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
111837 +#error Error: please synchronize IOC_ defines!
111838 +#endif
111839 +
111840 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
111841 +#error Error: please synchronize IOC_ defines!
111842 +#endif
111843 +
111844 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
111845 +#error Error: please synchronize IOC_ defines!
111846 +#endif
111847 +
111848 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
111849 +#error Error: please synchronize IOC_ defines!
111850 +#endif
111851 +
111852 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
111853 +#error Error: please synchronize IOC_ defines!
111854 +#endif
111855 +
111856 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
111857 +#error Error: please synchronize IOC_ defines!
111858 +#endif
111859 +
111860 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
111861 +#error Error: please synchronize IOC_ defines!
111862 +#endif
111863 +
111864 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
111865 +#error Error: please synchronize IOC_ defines!
111866 +#endif
111867 +
111868 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
111869 +#error Error: please synchronize IOC_ defines!
111870 +#endif
111871 +
111872 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
111873 +#error Error: please synchronize IOC_ defines!
111874 +#endif
111875 +
111876 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
111877 +#error Error: please synchronize IOC_ defines!
111878 +#endif
111879 +
111880 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
111881 +#error Error: please synchronize IOC_ defines!
111882 +#endif
111883 +
111884 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
111885 +#error Error: please synchronize IOC_ defines!
111886 +#endif
111887 +
111888 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
111889 +#warning Error: please synchronize IOC_ defines!
111890 +#endif
111891 +
111892 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
111893 +#error Error: please synchronize IOC_ defines!
111894 +#endif
111895 +
111896 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
111897 +#error Error: please synchronize IOC_ defines!
111898 +#endif
111899 +
111900 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
111901 +#error Error: please synchronize IOC_ defines!
111902 +#endif
111903 +
111904 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
111905 +#error Error: please synchronize IOC_ defines!
111906 +#endif
111907 +
111908 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
111909 +#error Error: please synchronize IOC_ defines!
111910 +#endif
111911 +
111912 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
111913 +#error Error: please synchronize IOC_ defines!
111914 +#endif
111915 +
111916 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
111917 +#error Error: please synchronize IOC_ defines!
111918 +#endif
111919 +
111920 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
111921 +#error Error: please synchronize IOC_ defines!
111922 +#endif
111923 +
111924 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
111925 +#error Error: please synchronize IOC_ defines!
111926 +#endif
111927 +
111928 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
111929 +#error Error: please synchronize IOC_ defines!
111930 +#endif
111931 +
111932 +/* fm_ioctls.h === fm_ext.h assertions */
111933 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
111934 +#error Error: please synchronize IOC_ defines!
111935 +#endif
111936 +
111937 +void LnxWrpPCDIOCTLTypeChecking(void)
111938 +{
111939 + /* fm_ext.h == fm_ioctls.h */
111940 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
111941 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
111942 +
111943 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
111944 + /*ioc_fm_pcd_counters_params_t : NOT USED */
111945 + /*ioc_fm_pcd_exception_params_t : private */
111946 +#if (DPAA_VERSION >= 11)
111947 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
111948 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
111949 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
111950 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
111951 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
111952 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
111953 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
111954 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
111955 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
111956 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
111957 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
111958 +#endif /* (DPAA_VERSION >= 11) */
111959 +
111960 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
111961 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
111962 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
111963 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
111964 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
111965 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
111966 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
111967 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
111968 +
111969 +#if defined(CONFIG_ARM64)
111970 + /* different alignment */
111971 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
111972 +#else
111973 +#if !defined(CONFIG_COMPAT)
111974 + /* different alignment */
111975 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
111976 +#endif
111977 +#endif
111978 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
111979 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
111980 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
111981 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
111982 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
111983 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
111984 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
111985 +#if (DPAA_VERSION >= 11)
111986 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
111987 +#endif
111988 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
111989 +#if !defined(CONFIG_COMPAT)
111990 + /* different alignment */
111991 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
111992 +#endif
111993 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
111994 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
111995 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
111996 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
111997 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
111998 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
111999 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
112000 +#if !defined(CONFIG_COMPAT)
112001 + /* different alignment */
112002 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
112003 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
112004 +#endif
112005 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
112006 +#if !defined(CONFIG_COMPAT)
112007 + /* different alignment */
112008 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
112009 +#endif
112010 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
112011 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
112012 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
112013 + /*ioc_fm_pcd_port_params_t : private */
112014 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
112015 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
112016 +
112017 +#ifdef FM_CAPWAP_SUPPORT
112018 +#error TODO: unsupported feature
112019 +/*
112020 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
112021 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
112022 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
112023 +*/
112024 +#endif
112025 +
112026 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
112027 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
112028 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
112029 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
112030 + /*ioc_fm_manip_hdr_info_t : private */
112031 + /*ioc_fm_pcd_hash_table_set_t : private */
112032 +
112033 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
112034 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
112035 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
112036 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
112037 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
112038 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
112039 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
112040 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
112041 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
112042 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
112043 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
112044 +#if !defined(CONFIG_COMPAT)
112045 + /* different alignment */
112046 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
112047 +#endif
112048 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
112049 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
112050 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
112051 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
112052 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
112053 +#if DPAA_VERSION >= 11
112054 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
112055 +#endif
112056 +
112057 + /* fm_port_ext.h == fm_port_ioctls.h */
112058 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
112059 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
112060 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
112061 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
112062 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
112063 +
112064 + return;
112065 +}
112066 +
112067 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
112068 +
112069 +void LnxWrpPCDIOCTLEnumChecking(void)
112070 +{
112071 + /* net_ext.h == net_ioctls.h : sampling checks */
112072 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
112073 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
112074 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
112075 +
112076 + /* fm_ext.h == fm_ioctls.h */
112077 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
112078 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
112079 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
112080 +
112081 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
112082 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES == (unsigned long)e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES);
112083 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
112084 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
112085 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
112086 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
112087 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
112088 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
112089 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
112090 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
112091 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
112092 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
112093 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
112094 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
112095 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
112096 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
112097 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
112098 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
112099 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER == (unsigned long)e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER);
112100 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
112101 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR);
112102 +#if !defined(FM_CAPWAP_SUPPORT)
112103 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
112104 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
112105 +#else
112106 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
112107 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
112108 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START);
112109 +#endif
112110 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
112111 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
112112 +
112113 +#ifdef FM_CAPWAP_SUPPORT
112114 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
112115 +#endif
112116 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
112117 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
112118 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
112119 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
112120 +
112121 + /* fm_port_ext.h == fm_port_ioctls.h */
112122 +#if !defined(FM_CAPWAP_SUPPORT)
112123 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR);
112124 +#else
112125 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR == (unsigned long)e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR);
112126 +#endif
112127 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
112128 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 == (unsigned long)e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8);
112129 +
112130 + return;
112131 +}
112132 +
112133 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
112134 +{
112135 + t_Error err = E_OK;
112136 +
112137 +/*
112138 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
112139 +
112140 + FM_PCD_PrsLoadSw
112141 + FM_PCD_SetAdvancedOffloadSupport
112142 + FM_PCD_Enable
112143 + FM_PCD_Disable
112144 + FM_PCD_ForceIntr
112145 + FM_PCD_SetException
112146 + FM_PCD_KgSetAdditionalDataAfterParsing
112147 + FM_PCD_KgSetDfltValue
112148 + FM_PCD_NetEnvCharacteristicsSet
112149 + FM_PCD_NetEnvCharacteristicsDelete
112150 + FM_PCD_KgSchemeSet
112151 + FM_PCD_KgSchemeDelete
112152 + FM_PCD_MatchTableSet
112153 + FM_PCD_MatchTableDelete
112154 + FM_PCD_CcRootBuild
112155 + FM_PCD_CcRootDelete
112156 + FM_PCD_PlcrProfileSet
112157 + FM_PCD_PlcrProfileDelete
112158 + FM_PCD_CcRootModifyNextEngine
112159 + FM_PCD_MatchTableModifyNextEngine
112160 + FM_PCD_MatchTableModifyMissNextEngine
112161 + FM_PCD_MatchTableRemoveKey
112162 + FM_PCD_MatchTableAddKey
112163 + FM_PCD_MatchTableModifyKeyAndNextEngine
112164 + FM_PCD_HashTableSet
112165 + FM_PCD_HashTableDelete
112166 + FM_PCD_HashTableAddKey
112167 + FM_PCD_HashTableRemoveKey
112168 + FM_PCD_MatchTableModifyKey
112169 + FM_PCD_ManipNodeReplace
112170 + FM_PCD_ManipNodeSet
112171 + FM_PCD_ManipNodeDelete
112172 +
112173 +Status: not exported, should be thru sysfs
112174 + FM_PCD_KgSchemeGetCounter
112175 + FM_PCD_KgSchemeSetCounter
112176 + FM_PCD_PlcrProfileGetCounter
112177 + FM_PCD_PlcrProfileSetCounter
112178 +
112179 +Status: not exported
112180 + FM_PCD_MatchTableFindNRemoveKey
112181 + FM_PCD_MatchTableFindNModifyNextEngine
112182 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
112183 + FM_PCD_MatchTableFindNModifyKey
112184 + FM_PCD_MatchTableGetIndexedHashBucket
112185 + FM_PCD_MatchTableGetNextEngine
112186 + FM_PCD_MatchTableGetKeyCounter
112187 +
112188 +Status: not exported, would be nice to have
112189 + FM_PCD_HashTableModifyNextEngine
112190 + FM_PCD_HashTableModifyMissNextEngine
112191 + FM_PCD_HashTableGetMissNextEngine
112192 + FM_PCD_ManipGetStatistics
112193 +
112194 +Status: not exported
112195 +#if DPAA_VERSION >= 11
112196 +
112197 + FM_VSP_GetStatistics -- it's not available yet
112198 +#endif
112199 +
112200 +Status: feature not supported
112201 +#ifdef FM_CAPWAP_SUPPORT
112202 +#error unsupported feature
112203 + FM_PCD_StatisticsSetNode
112204 +#endif
112205 +
112206 + */
112207 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
112208 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
112209 +
112210 + switch (cmd)
112211 + {
112212 +#if defined(CONFIG_COMPAT)
112213 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
112214 +#endif
112215 + case FM_PCD_IOC_PRS_LOAD_SW:
112216 + {
112217 + ioc_fm_pcd_prs_sw_params_t *param;
112218 + uint8_t *p_code;
112219 +
112220 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
112221 + if (!param)
112222 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112223 +
112224 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
112225 +
112226 +#if defined(CONFIG_COMPAT)
112227 + if (compat)
112228 + {
112229 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
112230 +
112231 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
112232 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112233 + if (!compat_param)
112234 + {
112235 + XX_Free(param);
112236 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112237 + }
112238 +
112239 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
112240 + if (copy_from_user(compat_param,
112241 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
112242 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
112243 + {
112244 + XX_Free(compat_param);
112245 + XX_Free(param);
112246 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112247 + }
112248 +
112249 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
112250 +
112251 + XX_Free(compat_param);
112252 + }
112253 + else
112254 +#endif
112255 + {
112256 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
112257 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
112258 + {
112259 + XX_Free(param);
112260 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112261 + }
112262 + }
112263 +
112264 + if (!param->p_code || !param->size)
112265 + {
112266 + XX_Free(param);
112267 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112268 + }
112269 +
112270 + p_code = (uint8_t *) XX_Malloc(param->size);
112271 + if (!p_code)
112272 + {
112273 + XX_Free(param);
112274 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112275 + }
112276 +
112277 + memset(p_code, 0, param->size);
112278 + if (copy_from_user(p_code, param->p_code, param->size))
112279 + {
112280 + XX_Free(p_code);
112281 + XX_Free(param);
112282 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112283 + }
112284 +
112285 + param->p_code = p_code;
112286 +
112287 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
112288 +
112289 + XX_Free(p_code);
112290 + XX_Free(param);
112291 + break;
112292 + }
112293 +
112294 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
112295 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
112296 + break;
112297 +
112298 + case FM_PCD_IOC_ENABLE:
112299 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
112300 + break;
112301 +
112302 + case FM_PCD_IOC_DISABLE:
112303 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
112304 + break;
112305 +
112306 + case FM_PCD_IOC_FORCE_INTR:
112307 + {
112308 + int exception;
112309 +
112310 +#if defined(CONFIG_COMPAT)
112311 + if (compat)
112312 + {
112313 + if (get_user(exception, (int *) compat_ptr(arg)))
112314 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112315 + }
112316 + else
112317 +#endif
112318 + {
112319 + if (get_user(exception, (int *)arg))
112320 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112321 + }
112322 +
112323 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
112324 + break;
112325 + }
112326 +
112327 + case FM_PCD_IOC_SET_EXCEPTION:
112328 + {
112329 + ioc_fm_pcd_exception_params_t *param;
112330 +
112331 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
112332 + sizeof(ioc_fm_pcd_exception_params_t));
112333 + if (!param)
112334 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112335 +
112336 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
112337 +
112338 +#if defined(CONFIG_COMPAT)
112339 + if (compat)
112340 + {
112341 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
112342 + sizeof(ioc_fm_pcd_exception_params_t)))
112343 + {
112344 + XX_Free(param);
112345 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112346 + }
112347 + }
112348 + else
112349 +#endif
112350 + {
112351 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
112352 + sizeof(ioc_fm_pcd_exception_params_t)))
112353 + {
112354 + XX_Free(param);
112355 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112356 + }
112357 + }
112358 +
112359 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
112360 +
112361 + XX_Free(param);
112362 + break;
112363 + }
112364 +
112365 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
112366 + {
112367 + uint8_t payloadOffset;
112368 +
112369 +#if defined(CONFIG_COMPAT)
112370 + if (compat)
112371 + {
112372 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
112373 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112374 + }
112375 + else
112376 +#endif
112377 + {
112378 + if (get_user(payloadOffset, (uint8_t*) arg))
112379 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112380 + }
112381 +
112382 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
112383 + break;
112384 + }
112385 +
112386 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
112387 + {
112388 + ioc_fm_pcd_kg_dflt_value_params_t *param;
112389 +
112390 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
112391 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112392 + if (!param)
112393 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112394 +
112395 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
112396 +
112397 +#if defined(CONFIG_COMPAT)
112398 + if (compat)
112399 + {
112400 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
112401 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112402 + {
112403 + XX_Free(param);
112404 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112405 + }
112406 + }
112407 + else
112408 +#endif
112409 + {
112410 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
112411 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
112412 + {
112413 + XX_Free(param);
112414 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112415 + }
112416 + }
112417 +
112418 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
112419 +
112420 + XX_Free(param);
112421 + break;
112422 + }
112423 +
112424 +#if defined(CONFIG_COMPAT)
112425 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
112426 +#endif
112427 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
112428 + {
112429 + ioc_fm_pcd_net_env_params_t *param;
112430 +
112431 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
112432 + if (!param)
112433 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112434 +
112435 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
112436 +
112437 +#if defined(CONFIG_COMPAT)
112438 + if (compat)
112439 + {
112440 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112441 +
112442 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112443 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112444 + if (!compat_param)
112445 + {
112446 + XX_Free(param);
112447 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112448 + }
112449 +
112450 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112451 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112452 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112453 + {
112454 + XX_Free(compat_param);
112455 + XX_Free(param);
112456 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112457 + }
112458 +
112459 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
112460 + XX_Free(compat_param);
112461 + }
112462 + else
112463 +#endif
112464 + {
112465 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
112466 + sizeof(ioc_fm_pcd_net_env_params_t)))
112467 + {
112468 + XX_Free(param);
112469 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112470 + }
112471 + }
112472 +
112473 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
112474 +
112475 + if (!param->id)
112476 + {
112477 + XX_Free(param);
112478 + err = E_INVALID_VALUE;
112479 + /* Since the LLD has no errno-style error reporting,
112480 + we're left here with no other option than to report
112481 + a generic E_INVALID_VALUE */
112482 + break;
112483 + }
112484 +
112485 +#if defined(CONFIG_COMPAT)
112486 + if (compat)
112487 + {
112488 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
112489 +
112490 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
112491 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
112492 + if (!compat_param)
112493 + {
112494 + XX_Free(param);
112495 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112496 + }
112497 +
112498 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
112499 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
112500 +
112501 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
112502 + compat_param,
112503 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
112504 + err = E_READ_FAILED;
112505 +
112506 + XX_Free(compat_param);
112507 + }
112508 + else
112509 +#endif
112510 + {
112511 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
112512 + param,
112513 + sizeof(ioc_fm_pcd_net_env_params_t)))
112514 + err = E_READ_FAILED;
112515 + }
112516 +
112517 + XX_Free(param);
112518 + break;
112519 + }
112520 +
112521 +#if defined(CONFIG_COMPAT)
112522 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
112523 +#endif
112524 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
112525 + {
112526 + ioc_fm_obj_t id;
112527 +
112528 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112529 +
112530 +#if defined(CONFIG_COMPAT)
112531 + if (compat)
112532 + {
112533 + ioc_compat_fm_obj_t compat_id;
112534 +
112535 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112536 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112537 +
112538 + compat_obj_delete(&compat_id, &id);
112539 + }
112540 + else
112541 +#endif
112542 + {
112543 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112544 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112545 + }
112546 +
112547 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
112548 + break;
112549 + }
112550 +
112551 +#if defined(CONFIG_COMPAT)
112552 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
112553 +#endif
112554 + case FM_PCD_IOC_KG_SCHEME_SET:
112555 + {
112556 + ioc_fm_pcd_kg_scheme_params_t *param;
112557 +
112558 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
112559 + if (!param)
112560 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112561 +
112562 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
112563 +
112564 +#if defined(CONFIG_COMPAT)
112565 + if (compat)
112566 + {
112567 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
112568 +
112569 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112570 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112571 + if (!compat_param)
112572 + {
112573 + XX_Free(param);
112574 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112575 + }
112576 +
112577 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112578 +
112579 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
112580 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112581 + {
112582 + XX_Free(compat_param);
112583 + XX_Free(param);
112584 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112585 + }
112586 +
112587 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
112588 +
112589 + XX_Free(compat_param);
112590 + }
112591 + else
112592 +#endif
112593 + {
112594 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
112595 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112596 + {
112597 + XX_Free(param);
112598 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112599 + }
112600 + }
112601 +
112602 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
112603 +
112604 + if (!param->id)
112605 + {
112606 + XX_Free(param);
112607 + err = E_INVALID_VALUE;
112608 + /* Since the LLD has no errno-style error reporting,
112609 + we're left here with no other option than to report
112610 + a generic E_INVALID_VALUE */
112611 + break;
112612 + }
112613 +
112614 +#if defined(CONFIG_COMPAT)
112615 + if (compat)
112616 + {
112617 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
112618 +
112619 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
112620 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112621 + if (!compat_param)
112622 + {
112623 + XX_Free(param);
112624 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112625 + }
112626 +
112627 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
112628 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
112629 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
112630 + compat_param,
112631 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
112632 + err = E_READ_FAILED;
112633 +
112634 + XX_Free(compat_param);
112635 + }
112636 + else
112637 +#endif
112638 + {
112639 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
112640 + param,
112641 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
112642 + err = E_READ_FAILED;
112643 + }
112644 +
112645 + XX_Free(param);
112646 + break;
112647 + }
112648 +
112649 +#if defined(CONFIG_COMPAT)
112650 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
112651 +#endif
112652 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
112653 + {
112654 + ioc_fm_pcd_kg_scheme_spc_t *param;
112655 +
112656 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112657 + if (!param)
112658 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112659 +
112660 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
112661 +
112662 +#if defined(CONFIG_COMPAT)
112663 + if (compat)
112664 + {
112665 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
112666 +
112667 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112668 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112669 + if (!compat_param)
112670 + {
112671 + XX_Free(param);
112672 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112673 + }
112674 +
112675 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112676 +
112677 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
112678 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112679 + {
112680 + XX_Free(compat_param);
112681 + XX_Free(param);
112682 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112683 + }
112684 +
112685 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
112686 +
112687 + XX_Free(compat_param);
112688 + }
112689 + else
112690 +#endif
112691 + {
112692 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
112693 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112694 + {
112695 + XX_Free(param);
112696 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112697 + }
112698 + }
112699 +
112700 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
112701 +
112702 +#if defined(CONFIG_COMPAT)
112703 + if (compat)
112704 + {
112705 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
112706 +
112707 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
112708 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112709 + if (!compat_param)
112710 + {
112711 + XX_Free(param);
112712 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112713 + }
112714 +
112715 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
112716 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
112717 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
112718 + compat_param,
112719 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
112720 + err = E_READ_FAILED;
112721 +
112722 + XX_Free(compat_param);
112723 + }
112724 + else
112725 +#endif
112726 + {
112727 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
112728 + param,
112729 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
112730 + err = E_READ_FAILED;
112731 + }
112732 +
112733 + XX_Free(param);
112734 + break;
112735 + }
112736 +
112737 +#if defined(CONFIG_COMPAT)
112738 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
112739 +#endif
112740 + case FM_PCD_IOC_KG_SCHEME_DELETE:
112741 + {
112742 + ioc_fm_obj_t id;
112743 +
112744 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112745 +
112746 +#if defined(CONFIG_COMPAT)
112747 + if (compat)
112748 + {
112749 + ioc_compat_fm_obj_t compat_id;
112750 +
112751 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112752 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112753 +
112754 + compat_obj_delete(&compat_id, &id);
112755 + }
112756 + else
112757 +#endif
112758 + {
112759 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112760 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112761 + }
112762 +
112763 + err = FM_PCD_KgSchemeDelete(id.obj);
112764 + break;
112765 + }
112766 +
112767 +#if defined(CONFIG_COMPAT)
112768 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
112769 +#endif
112770 + case FM_PCD_IOC_MATCH_TABLE_SET:
112771 + {
112772 + ioc_fm_pcd_cc_node_params_t *param;
112773 + uint8_t *keys;
112774 + uint8_t *masks;
112775 + int i,k;
112776 +
112777 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
112778 + sizeof(ioc_fm_pcd_cc_node_params_t) +
112779 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112780 + if (!param)
112781 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112782 +
112783 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
112784 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112785 +
112786 + keys = (uint8_t *) (param + 1);
112787 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
112788 +
112789 +#if defined(CONFIG_COMPAT)
112790 + if (compat)
112791 + {
112792 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112793 +
112794 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112795 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112796 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112797 + if (!compat_param)
112798 + {
112799 + XX_Free(param);
112800 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112801 + }
112802 +
112803 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112804 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112805 +
112806 + if (copy_from_user(compat_param,
112807 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112808 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112809 + {
112810 + XX_Free(compat_param);
112811 + XX_Free(param);
112812 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112813 + }
112814 +
112815 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
112816 +
112817 + XX_Free(compat_param);
112818 + }
112819 + else
112820 +#endif
112821 + {
112822 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
112823 + {
112824 + XX_Free(param);
112825 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112826 + }
112827 + }
112828 +
112829 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
112830 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
112831 +
112832 + /* support for indexed lookup */
112833 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
112834 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
112835 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
112836 + {
112837 + for (i=0, k=0;
112838 + i < param->keys_params.num_of_keys;
112839 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
112840 + {
112841 + if (param->keys_params.key_params[i].p_key &&
112842 + param->keys_params.key_size)
112843 + {
112844 + if (copy_from_user(&keys[k],
112845 + param->keys_params.key_params[i].p_key,
112846 + param->keys_params.key_size))
112847 + {
112848 + XX_Free(param);
112849 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112850 + }
112851 +
112852 + param->keys_params.key_params[i].p_key = &keys[k];
112853 + }
112854 +
112855 + if (param->keys_params.key_params[i].p_mask)
112856 + {
112857 + if (copy_from_user(&masks[k],
112858 + param->keys_params.key_params[i].p_mask,
112859 + param->keys_params.key_size))
112860 + {
112861 + XX_Free(param);
112862 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112863 + }
112864 +
112865 + param->keys_params.key_params[i].p_mask = &masks[k];
112866 + }
112867 + }
112868 + }
112869 +
112870 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
112871 +
112872 + if (!param->id) {
112873 + XX_Free(param);
112874 + err = E_INVALID_VALUE;
112875 + /* Since the LLD has no errno-style error reporting,
112876 + we're left here with no other option than to report
112877 + a generic E_INVALID_VALUE */
112878 + break;
112879 + }
112880 +
112881 +#if defined(CONFIG_COMPAT)
112882 + if (compat)
112883 + {
112884 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
112885 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
112886 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112887 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112888 + if (!compat_param)
112889 + {
112890 + XX_Free(param);
112891 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112892 + }
112893 +
112894 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
112895 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
112896 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
112897 +
112898 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
112899 + compat_param,
112900 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
112901 + err = E_READ_FAILED;
112902 +
112903 + XX_Free(compat_param);
112904 + }
112905 + else
112906 +#endif
112907 + {
112908 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
112909 + param,
112910 + sizeof(ioc_fm_pcd_cc_node_params_t)))
112911 + err = E_READ_FAILED;
112912 + }
112913 +
112914 + XX_Free(param);
112915 + break;
112916 + }
112917 +
112918 +#if defined(CONFIG_COMPAT)
112919 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
112920 +#endif
112921 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
112922 + {
112923 + ioc_fm_obj_t id;
112924 +
112925 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
112926 +
112927 +#if defined(CONFIG_COMPAT)
112928 + if (compat)
112929 + {
112930 + ioc_compat_fm_obj_t compat_id;
112931 +
112932 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
112933 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112934 +
112935 + compat_obj_delete(&compat_id, &id);
112936 + }
112937 + else
112938 +#endif
112939 + {
112940 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
112941 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112942 + }
112943 +
112944 + err = FM_PCD_MatchTableDelete(id.obj);
112945 + break;
112946 + }
112947 +
112948 +#if defined(CONFIG_COMPAT)
112949 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
112950 +#endif
112951 + case FM_PCD_IOC_CC_ROOT_BUILD:
112952 + {
112953 + ioc_fm_pcd_cc_tree_params_t *param;
112954 +
112955 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
112956 + if (!param)
112957 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112958 +
112959 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
112960 +
112961 +#if defined(CONFIG_COMPAT)
112962 + if (compat)
112963 + {
112964 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
112965 +
112966 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
112967 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112968 + if (!compat_param)
112969 + {
112970 + XX_Free(param);
112971 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
112972 + }
112973 +
112974 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
112975 + if (copy_from_user(compat_param,
112976 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
112977 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
112978 + {
112979 + XX_Free(compat_param);
112980 + XX_Free(param);
112981 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112982 + }
112983 +
112984 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
112985 +
112986 + XX_Free(compat_param);
112987 + }
112988 + else
112989 +#endif
112990 + {
112991 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
112992 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
112993 + {
112994 + XX_Free(param);
112995 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
112996 + }
112997 + }
112998 +
112999 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
113000 +
113001 + if (!param->id) {
113002 + XX_Free(param);
113003 + err = E_INVALID_VALUE;
113004 + /* Since the LLD has no errno-style error reporting,
113005 + we're left here with no other option than to report
113006 + a generic E_INVALID_VALUE */
113007 + break;
113008 + }
113009 +
113010 +#if defined(CONFIG_COMPAT)
113011 + if (compat)
113012 + {
113013 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
113014 +
113015 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113016 + if (!compat_param)
113017 + {
113018 + XX_Free(param);
113019 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113020 + }
113021 +
113022 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
113023 +
113024 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
113025 +
113026 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
113027 + compat_param,
113028 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
113029 + err = E_READ_FAILED;
113030 +
113031 + XX_Free(compat_param);
113032 + }
113033 + else
113034 +#endif
113035 + {
113036 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
113037 + param,
113038 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
113039 + err = E_READ_FAILED;
113040 + }
113041 +
113042 + XX_Free(param);
113043 + break;
113044 + }
113045 +
113046 +#if defined(CONFIG_COMPAT)
113047 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
113048 +#endif
113049 + case FM_PCD_IOC_CC_ROOT_DELETE:
113050 + {
113051 + ioc_fm_obj_t id;
113052 +
113053 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113054 +
113055 +#if defined(CONFIG_COMPAT)
113056 + if (compat)
113057 + {
113058 + ioc_compat_fm_obj_t compat_id;
113059 +
113060 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113061 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113062 +
113063 + compat_obj_delete(&compat_id, &id);
113064 + }
113065 + else
113066 +#endif
113067 + {
113068 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113069 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113070 + }
113071 +
113072 + err = FM_PCD_CcRootDelete(id.obj);
113073 + break;
113074 + }
113075 +
113076 +#if defined(CONFIG_COMPAT)
113077 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
113078 +#endif
113079 + case FM_PCD_IOC_PLCR_PROFILE_SET:
113080 + {
113081 + ioc_fm_pcd_plcr_profile_params_t *param;
113082 +
113083 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113084 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
113085 + if (!param)
113086 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113087 +
113088 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
113089 +
113090 +#if defined(CONFIG_COMPAT)
113091 + if (compat)
113092 + {
113093 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113094 +
113095 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113096 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113097 + if (!compat_param)
113098 + {
113099 + XX_Free(param);
113100 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113101 + }
113102 +
113103 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113104 + if (copy_from_user(compat_param, (
113105 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
113106 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113107 + {
113108 + XX_Free(compat_param);
113109 + XX_Free(param);
113110 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113111 + }
113112 +
113113 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
113114 +
113115 + XX_Free(compat_param);
113116 + }
113117 + else
113118 +#endif
113119 + {
113120 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
113121 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113122 + {
113123 + XX_Free(param);
113124 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113125 + }
113126 + }
113127 +
113128 + if (!param->modify &&
113129 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
113130 + {
113131 + t_Handle h_Port;
113132 + ioc_fm_pcd_port_params_t *port_params;
113133 +
113134 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
113135 + if (!port_params)
113136 + {
113137 + XX_Free(param);
113138 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113139 + }
113140 +
113141 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
113142 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
113143 + sizeof(ioc_fm_pcd_port_params_t)))
113144 + {
113145 + XX_Free(port_params);
113146 + XX_Free(param);
113147 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113148 + }
113149 +
113150 + switch(port_params->port_type)
113151 + {
113152 + case (e_IOC_FM_PORT_TYPE_RX):
113153 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
113154 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113155 + break;
113156 + }
113157 + goto invalid_port_id;
113158 +
113159 + case (e_IOC_FM_PORT_TYPE_RX_10G):
113160 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
113161 +#ifndef CONFIG_FMAN_ARM
113162 + if (IS_T1023_T1024) {
113163 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
113164 + } else {
113165 +#else
113166 + {
113167 +#endif
113168 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
113169 + }
113170 + break;
113171 + }
113172 + goto invalid_port_id;
113173 +
113174 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
113175 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
113176 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
113177 + break;
113178 + }
113179 + goto invalid_port_id;
113180 +
113181 + default:
113182 +invalid_port_id:
113183 + XX_Free(port_params);
113184 + XX_Free(param);
113185 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
113186 + }
113187 +
113188 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
113189 + XX_Free(port_params);
113190 + }
113191 +
113192 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
113193 +
113194 + if (!param->id) {
113195 + XX_Free(param);
113196 + err = E_INVALID_VALUE;
113197 + /* Since the LLD has no errno-style error reporting,
113198 + we're left here with no other option than to report
113199 + a generic E_INVALID_VALUE */
113200 + break;
113201 + }
113202 +
113203 +#if defined(CONFIG_COMPAT)
113204 + if (compat)
113205 + {
113206 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
113207 +
113208 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
113209 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113210 + if (!compat_param)
113211 + {
113212 + XX_Free(param);
113213 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113214 + }
113215 +
113216 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
113217 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
113218 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
113219 + compat_param,
113220 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
113221 + err = E_READ_FAILED;
113222 +
113223 + XX_Free(compat_param);
113224 + }
113225 + else
113226 +#endif
113227 + {
113228 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
113229 + param,
113230 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
113231 + err = E_READ_FAILED;
113232 + }
113233 +
113234 + XX_Free(param);
113235 + break;
113236 + }
113237 +
113238 +#if defined(CONFIG_COMPAT)
113239 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
113240 +#endif
113241 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
113242 + {
113243 + ioc_fm_obj_t id;
113244 +
113245 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
113246 +
113247 +#if defined(CONFIG_COMPAT)
113248 + if (compat)
113249 + {
113250 + ioc_compat_fm_obj_t compat_id;
113251 +
113252 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
113253 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113254 +
113255 + compat_obj_delete(&compat_id, &id);
113256 + }
113257 + else
113258 +#endif
113259 + {
113260 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
113261 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113262 + }
113263 +
113264 + err = FM_PCD_PlcrProfileDelete(id.obj);
113265 + break;
113266 + }
113267 +
113268 +#if defined(CONFIG_COMPAT)
113269 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
113270 +#endif
113271 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
113272 + {
113273 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
113274 +
113275 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113276 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113277 + if (!param)
113278 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113279 +
113280 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
113281 +
113282 +#if defined(CONFIG_COMPAT)
113283 + if (compat)
113284 + {
113285 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
113286 +
113287 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
113288 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113289 + if (!compat_param)
113290 + {
113291 + XX_Free(param);
113292 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113293 + }
113294 +
113295 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
113296 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
113297 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
113298 + {
113299 + XX_Free(compat_param);
113300 + XX_Free(param);
113301 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113302 + }
113303 +
113304 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113305 +
113306 + XX_Free(compat_param);
113307 + }
113308 + else
113309 +#endif
113310 + {
113311 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
113312 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
113313 + {
113314 + XX_Free(param);
113315 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113316 + }
113317 + }
113318 +
113319 + err = FM_PCD_CcRootModifyNextEngine(param->id,
113320 + param->grp_indx,
113321 + param->indx,
113322 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113323 +
113324 + XX_Free(param);
113325 + break;
113326 + }
113327 +
113328 +#if defined(CONFIG_COMPAT)
113329 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
113330 +#endif
113331 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
113332 + {
113333 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113334 +
113335 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113336 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113337 + if (!param)
113338 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113339 +
113340 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113341 +
113342 +#if defined(CONFIG_COMPAT)
113343 + if (compat)
113344 + {
113345 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113346 +
113347 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113348 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113349 + if (!compat_param)
113350 + {
113351 + XX_Free(param);
113352 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113353 + }
113354 +
113355 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113356 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113357 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113358 + {
113359 + XX_Free(compat_param);
113360 + XX_Free(param);
113361 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113362 + }
113363 +
113364 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113365 +
113366 + XX_Free(compat_param);
113367 + }
113368 + else
113369 +#endif
113370 + {
113371 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
113372 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113373 + {
113374 + XX_Free(param);
113375 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113376 + }
113377 + }
113378 +
113379 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
113380 + param->key_indx,
113381 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113382 +
113383 + XX_Free(param);
113384 + break;
113385 + }
113386 +
113387 +#if defined(CONFIG_COMPAT)
113388 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
113389 +#endif
113390 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
113391 + {
113392 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
113393 +
113394 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113395 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113396 + if (!param)
113397 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113398 +
113399 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
113400 +
113401 +#if defined(CONFIG_COMPAT)
113402 + if (compat)
113403 + {
113404 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
113405 +
113406 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
113407 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113408 + if (!compat_param)
113409 + {
113410 + XX_Free(param);
113411 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113412 + }
113413 +
113414 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
113415 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
113416 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
113417 + {
113418 + XX_Free(compat_param);
113419 + XX_Free(param);
113420 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113421 + }
113422 +
113423 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
113424 +
113425 + XX_Free(compat_param);
113426 + }
113427 + else
113428 +#endif
113429 + {
113430 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
113431 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
113432 + {
113433 + XX_Free(param);
113434 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113435 + }
113436 + }
113437 +
113438 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
113439 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
113440 +
113441 + XX_Free(param);
113442 + break;
113443 + }
113444 +
113445 +#if defined(CONFIG_COMPAT)
113446 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
113447 +#endif
113448 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
113449 + {
113450 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
113451 +
113452 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113453 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113454 + if (!param)
113455 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113456 +
113457 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
113458 +
113459 +#if defined(CONFIG_COMPAT)
113460 + if (compat)
113461 + {
113462 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
113463 +
113464 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
113465 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113466 + if (!compat_param)
113467 + {
113468 + XX_Free(param);
113469 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113470 + }
113471 +
113472 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
113473 + if (copy_from_user(compat_param,
113474 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
113475 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
113476 + {
113477 + XX_Free(compat_param);
113478 + XX_Free(param);
113479 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113480 + }
113481 +
113482 + param->id = compat_ptr(compat_param->id);
113483 + param->key_indx = compat_param->key_indx;
113484 +
113485 + XX_Free(compat_param);
113486 + }
113487 + else
113488 +#endif
113489 + {
113490 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
113491 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
113492 + {
113493 + XX_Free(param);
113494 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113495 + }
113496 + }
113497 +
113498 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
113499 +
113500 + XX_Free(param);
113501 + break;
113502 + }
113503 +#if defined(CONFIG_COMPAT)
113504 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
113505 +#endif
113506 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
113507 + {
113508 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113509 +
113510 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113511 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113512 + if (!param)
113513 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113514 +
113515 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113516 +
113517 +#if defined(CONFIG_COMPAT)
113518 + if (compat)
113519 + {
113520 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113521 +
113522 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113523 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113524 + if (!compat_param)
113525 + {
113526 + XX_Free(param);
113527 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113528 + }
113529 +
113530 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113531 + if (copy_from_user(compat_param,
113532 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113533 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113534 + {
113535 + XX_Free(compat_param);
113536 + XX_Free(param);
113537 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113538 + }
113539 +
113540 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113541 +
113542 + XX_Free(compat_param);
113543 + }
113544 + else
113545 +#endif
113546 + {
113547 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113548 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113549 + {
113550 + XX_Free(param);
113551 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113552 + }
113553 + }
113554 +
113555 + if (param->key_size)
113556 + {
113557 + int size = 0;
113558 +
113559 + if (param->key_params.p_key) size += param->key_size;
113560 + if (param->key_params.p_mask) size += param->key_size;
113561 +
113562 + if (size)
113563 + {
113564 + uint8_t *p_tmp;
113565 +
113566 + p_tmp = (uint8_t*) XX_Malloc(size);
113567 + if (!p_tmp)
113568 + {
113569 + XX_Free(param);
113570 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
113571 + }
113572 +
113573 + if (param->key_params.p_key)
113574 + {
113575 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
113576 + {
113577 + XX_Free(p_tmp);
113578 + XX_Free(param);
113579 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113580 + }
113581 +
113582 + param->key_params.p_key = p_tmp;
113583 + }
113584 +
113585 + if (param->key_params.p_mask)
113586 + {
113587 + p_tmp += param->key_size;
113588 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
113589 + {
113590 + XX_Free(p_tmp - param->key_size);
113591 + XX_Free(param);
113592 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113593 + }
113594 +
113595 + param->key_params.p_mask = p_tmp;
113596 + }
113597 + }
113598 + }
113599 +
113600 + err = FM_PCD_MatchTableAddKey(
113601 + param->id,
113602 + param->key_indx,
113603 + param->key_size,
113604 + (t_FmPcdCcKeyParams*)&param->key_params);
113605 +
113606 + if (param->key_params.p_key)
113607 + XX_Free(param->key_params.p_key);
113608 + XX_Free(param);
113609 + break;
113610 + }
113611 +
113612 +#if defined(CONFIG_COMPAT)
113613 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
113614 +#endif
113615 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
113616 + {
113617 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
113618 +
113619 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113620 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113621 + if (!param)
113622 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113623 +
113624 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113625 +
113626 +#if defined(CONFIG_COMPAT)
113627 + if (compat)
113628 + {
113629 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
113630 +
113631 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
113632 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113633 + if (!compat_param)
113634 + {
113635 + XX_Free(param);
113636 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113637 + }
113638 +
113639 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
113640 + if (copy_from_user(compat_param,
113641 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
113642 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113643 + {
113644 + XX_Free(compat_param);
113645 + XX_Free(param);
113646 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113647 + }
113648 +
113649 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
113650 +
113651 + XX_Free(compat_param);
113652 + }
113653 + else
113654 +#endif
113655 + {
113656 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
113657 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
113658 + {
113659 + XX_Free(param);
113660 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113661 + }
113662 + }
113663 +
113664 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
113665 + param->key_indx,
113666 + param->key_size,
113667 + (t_FmPcdCcKeyParams*)(&param->key_params));
113668 +
113669 + XX_Free(param);
113670 + break;
113671 + }
113672 +
113673 +
113674 +#if defined(CONFIG_COMPAT)
113675 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
113676 +#endif
113677 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
113678 + {
113679 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113680 +
113681 +#if defined(CONFIG_COMPAT)
113682 + if (compat)
113683 + {
113684 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113685 +
113686 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113687 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113688 + if (!compat_param)
113689 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113690 +
113691 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113692 + if (copy_from_user(compat_param,
113693 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113694 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113695 + {
113696 + XX_Free(compat_param);
113697 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113698 + }
113699 +
113700 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113701 +
113702 + XX_Free(compat_param);
113703 + }
113704 + else
113705 +#endif
113706 + {
113707 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113708 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113709 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113710 + }
113711 +
113712 +
113713 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
113714 + param.key_index,
113715 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113716 +
113717 +#if defined(CONFIG_COMPAT)
113718 + if (compat)
113719 + {
113720 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113721 +
113722 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113723 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113724 + if (!compat_param)
113725 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113726 +
113727 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113728 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113729 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113730 + compat_param,
113731 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113732 + XX_Free(compat_param);
113733 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113734 + }
113735 + XX_Free(compat_param);
113736 + }
113737 + else
113738 +#endif
113739 + {
113740 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113741 + &param,
113742 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113743 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113744 + }
113745 +
113746 + break;
113747 + }
113748 +
113749 +
113750 +#if defined(CONFIG_COMPAT)
113751 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
113752 +#endif
113753 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
113754 + {
113755 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113756 +
113757 +#if defined(CONFIG_COMPAT)
113758 + if (compat)
113759 + {
113760 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113761 +
113762 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113763 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113764 + if (!compat_param)
113765 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113766 +
113767 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113768 + if (copy_from_user(compat_param,
113769 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113770 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113771 + {
113772 + XX_Free(compat_param);
113773 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113774 + }
113775 +
113776 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113777 +
113778 + XX_Free(compat_param);
113779 + }
113780 + else
113781 +#endif
113782 + {
113783 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113784 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113785 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113786 + }
113787 +
113788 +
113789 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
113790 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113791 +
113792 +#if defined(CONFIG_COMPAT)
113793 + if (compat)
113794 + {
113795 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113796 +
113797 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113798 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113799 + if (!compat_param)
113800 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113801 +
113802 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113803 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113804 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113805 + compat_param,
113806 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113807 + XX_Free(compat_param);
113808 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113809 + }
113810 + XX_Free(compat_param);
113811 + }
113812 + else
113813 +#endif
113814 + {
113815 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113816 + &param,
113817 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113818 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113819 + }
113820 +
113821 + break;
113822 + }
113823 +
113824 +
113825 +#if defined(CONFIG_COMPAT)
113826 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
113827 +#endif
113828 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
113829 + {
113830 + ioc_fm_pcd_cc_tbl_get_stats_t param;
113831 +
113832 +#if defined(CONFIG_COMPAT)
113833 + if (compat)
113834 + {
113835 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113836 +
113837 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
113838 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113839 + if (!compat_param)
113840 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113841 +
113842 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113843 + if (copy_from_user(compat_param,
113844 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
113845 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
113846 + {
113847 + XX_Free(compat_param);
113848 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113849 + }
113850 +
113851 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
113852 +
113853 + XX_Free(compat_param);
113854 + }
113855 + else
113856 +#endif
113857 + {
113858 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113859 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113860 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113861 + }
113862 +
113863 +
113864 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
113865 + (t_FmPcdCcKeyStatistics *) &param.statistics);
113866 +
113867 +#if defined(CONFIG_COMPAT)
113868 + if (compat)
113869 + {
113870 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
113871 +
113872 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
113873 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113874 + if (!compat_param)
113875 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113876 +
113877 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
113878 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
113879 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
113880 + compat_param,
113881 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
113882 + XX_Free(compat_param);
113883 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113884 + }
113885 + XX_Free(compat_param);
113886 + }
113887 + else
113888 +#endif
113889 + {
113890 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
113891 + &param,
113892 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
113893 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
113894 + }
113895 +
113896 + break;
113897 + }
113898 +
113899 +#if defined(CONFIG_COMPAT)
113900 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
113901 +#endif
113902 + case FM_PCD_IOC_HASH_TABLE_SET:
113903 + {
113904 + ioc_fm_pcd_hash_table_params_t *param;
113905 +
113906 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
113907 + sizeof(ioc_fm_pcd_hash_table_params_t));
113908 + if (!param)
113909 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113910 +
113911 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
113912 +
113913 +#if defined(CONFIG_COMPAT)
113914 + if (compat)
113915 + {
113916 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113917 +
113918 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113919 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113920 + if (!compat_param)
113921 + {
113922 + XX_Free(param);
113923 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113924 + }
113925 +
113926 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113927 + if (copy_from_user(compat_param,
113928 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
113929 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113930 + {
113931 + XX_Free(compat_param);
113932 + XX_Free(param);
113933 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113934 + }
113935 +
113936 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
113937 +
113938 + XX_Free(compat_param);
113939 + }
113940 + else
113941 +#endif
113942 + {
113943 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
113944 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113945 + {
113946 + XX_Free(param);
113947 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113948 + }
113949 + }
113950 +
113951 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
113952 +
113953 + if (!param->id)
113954 + {
113955 + XX_Free(param);
113956 + err = E_INVALID_VALUE;
113957 + /* Since the LLD has no errno-style error reporting,
113958 + we're left here with no other option than to report
113959 + a generic E_INVALID_VALUE */
113960 + break;
113961 + }
113962 +
113963 +#if defined(CONFIG_COMPAT)
113964 + if (compat)
113965 + {
113966 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
113967 +
113968 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
113969 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113970 + if (!compat_param)
113971 + {
113972 + XX_Free(param);
113973 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113974 + }
113975 +
113976 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
113977 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
113978 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
113979 + compat_param,
113980 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
113981 + err = E_READ_FAILED;
113982 +
113983 + XX_Free(compat_param);
113984 + }
113985 + else
113986 +#endif
113987 + {
113988 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
113989 + param,
113990 + sizeof(ioc_fm_pcd_hash_table_params_t)))
113991 + err = E_READ_FAILED;
113992 + }
113993 +
113994 + XX_Free(param);
113995 + break;
113996 + }
113997 +
113998 +#if defined(CONFIG_COMPAT)
113999 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
114000 +#endif
114001 + case FM_PCD_IOC_HASH_TABLE_DELETE:
114002 + {
114003 + ioc_fm_obj_t id;
114004 +
114005 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114006 +
114007 +#if defined(CONFIG_COMPAT)
114008 + if (compat)
114009 + {
114010 + ioc_compat_fm_obj_t compat_id;
114011 +
114012 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114013 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114014 +
114015 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114016 + }
114017 + else
114018 +#endif
114019 + {
114020 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114021 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114022 + }
114023 +
114024 + err = FM_PCD_HashTableDelete(id.obj);
114025 + break;
114026 + }
114027 +
114028 +#if defined(CONFIG_COMPAT)
114029 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
114030 +#endif
114031 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
114032 + {
114033 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
114034 +
114035 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114036 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114037 + if (!param)
114038 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114039 +
114040 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
114041 +
114042 +#if defined(CONFIG_COMPAT)
114043 + if (compat)
114044 + {
114045 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
114046 +
114047 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
114048 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114049 + if (!compat_param)
114050 + {
114051 + XX_Free(param);
114052 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114053 + }
114054 +
114055 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
114056 + if (copy_from_user(compat_param,
114057 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
114058 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
114059 + {
114060 + XX_Free(compat_param);
114061 + XX_Free(param);
114062 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114063 + }
114064 +
114065 + if (compat_param->key_size)
114066 + {
114067 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114068 + param->key_size = compat_param->key_size;
114069 +
114070 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
114071 + }
114072 + else
114073 + {
114074 + XX_Free(compat_param);
114075 + XX_Free(param);
114076 + err = E_INVALID_VALUE;
114077 + break;
114078 + }
114079 +
114080 + XX_Free(compat_param);
114081 + }
114082 + else
114083 +#endif
114084 + {
114085 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
114086 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
114087 + {
114088 + XX_Free(param);
114089 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114090 + }
114091 + }
114092 +
114093 + if (param->key_size)
114094 + {
114095 + int size = 0;
114096 +
114097 + if (param->key_params.p_key) size += param->key_size;
114098 + if (param->key_params.p_mask) size += param->key_size;
114099 +
114100 + if (size)
114101 + {
114102 + uint8_t *p_tmp;
114103 +
114104 + p_tmp = (uint8_t*) XX_Malloc(size);
114105 + if (!p_tmp)
114106 + {
114107 + XX_Free(param);
114108 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114109 + }
114110 +
114111 + if (param->key_params.p_key)
114112 + {
114113 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
114114 + {
114115 + XX_Free(p_tmp);
114116 + XX_Free(param);
114117 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114118 + }
114119 +
114120 + param->key_params.p_key = p_tmp;
114121 + }
114122 +
114123 + if (param->key_params.p_mask)
114124 + {
114125 + p_tmp += param->key_size;
114126 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
114127 + {
114128 + XX_Free(p_tmp - param->key_size);
114129 + XX_Free(param);
114130 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114131 + }
114132 +
114133 + param->key_params.p_mask = p_tmp;
114134 + }
114135 + }
114136 + }
114137 +
114138 + err = FM_PCD_HashTableAddKey(
114139 + param->p_hash_tbl,
114140 + param->key_size,
114141 + (t_FmPcdCcKeyParams*)&param->key_params);
114142 +
114143 + if (param->key_params.p_key)
114144 + XX_Free(param->key_params.p_key);
114145 + XX_Free(param);
114146 + break;
114147 + }
114148 +
114149 +#if defined(CONFIG_COMPAT)
114150 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
114151 +#endif
114152 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
114153 + {
114154 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
114155 +
114156 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114157 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114158 + if (!param)
114159 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114160 +
114161 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
114162 +
114163 +#if defined(CONFIG_COMPAT)
114164 + if (compat)
114165 + {
114166 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
114167 +
114168 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
114169 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114170 + if (!compat_param)
114171 + {
114172 + XX_Free(param);
114173 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114174 + }
114175 +
114176 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
114177 + if (copy_from_user(compat_param,
114178 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
114179 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
114180 + {
114181 + XX_Free(compat_param);
114182 + XX_Free(param);
114183 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114184 + }
114185 +
114186 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
114187 + param->key_size = compat_param->key_size;
114188 +
114189 + XX_Free(compat_param);
114190 + }
114191 + else
114192 +#endif
114193 + {
114194 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
114195 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
114196 + {
114197 + XX_Free(param);
114198 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114199 + }
114200 + }
114201 +
114202 + if (param->key_size)
114203 + {
114204 + uint8_t *p_key;
114205 +
114206 + p_key = (uint8_t*) XX_Malloc(param->key_size);
114207 + if (!p_key)
114208 + {
114209 + XX_Free(param);
114210 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114211 + }
114212 +
114213 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
114214 + {
114215 + XX_Free(p_key);
114216 + XX_Free(param);
114217 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114218 + }
114219 + param->p_key = p_key;
114220 + }
114221 +
114222 + err = FM_PCD_HashTableRemoveKey(
114223 + param->p_hash_tbl,
114224 + param->key_size,
114225 + param->p_key);
114226 +
114227 + if (param->p_key)
114228 + XX_Free(param->p_key);
114229 + XX_Free(param);
114230 + break;
114231 + }
114232 +
114233 +#if defined(CONFIG_COMPAT)
114234 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
114235 +#endif
114236 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
114237 + {
114238 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
114239 +
114240 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114241 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114242 + if (!param)
114243 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114244 +
114245 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
114246 +
114247 +#if defined(CONFIG_COMPAT)
114248 + if (compat)
114249 + {
114250 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
114251 +
114252 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
114253 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114254 + if (!compat_param)
114255 + {
114256 + XX_Free(param);
114257 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114258 + }
114259 +
114260 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
114261 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
114262 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
114263 + {
114264 + XX_Free(compat_param);
114265 + XX_Free(param);
114266 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114267 + }
114268 +
114269 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
114270 +
114271 + XX_Free(compat_param);
114272 + }
114273 + else
114274 +#endif
114275 + {
114276 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
114277 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
114278 + {
114279 + XX_Free(param);
114280 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114281 + }
114282 + }
114283 +
114284 + if (param->key_size)
114285 + {
114286 + int size = 0;
114287 +
114288 + if (param->p_key) size += param->key_size;
114289 + if (param->p_mask) size += param->key_size;
114290 +
114291 + if (size)
114292 + {
114293 + uint8_t *p_tmp;
114294 +
114295 + p_tmp = (uint8_t*) XX_Malloc(size);
114296 + if (!p_tmp)
114297 + {
114298 + XX_Free(param);
114299 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
114300 + }
114301 +
114302 + if (param->p_key)
114303 + {
114304 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
114305 + {
114306 + XX_Free(p_tmp);
114307 + XX_Free(param);
114308 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114309 + }
114310 +
114311 + param->p_key = p_tmp;
114312 + }
114313 +
114314 + if (param->p_mask)
114315 + {
114316 + p_tmp += param->key_size;
114317 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
114318 + {
114319 + XX_Free(p_tmp - param->key_size);
114320 + XX_Free(param);
114321 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114322 + }
114323 +
114324 + param->p_mask = p_tmp;
114325 + }
114326 + }
114327 + }
114328 +
114329 + err = FM_PCD_MatchTableModifyKey(param->id,
114330 + param->key_indx,
114331 + param->key_size,
114332 + param->p_key,
114333 + param->p_mask);
114334 +
114335 + if (param->p_key)
114336 + XX_Free(param->p_key);
114337 + else if (param->p_mask)
114338 + XX_Free(param->p_mask);
114339 + XX_Free(param);
114340 + break;
114341 + }
114342 +
114343 +#if defined(CONFIG_COMPAT)
114344 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
114345 +#endif
114346 + case FM_PCD_IOC_MANIP_NODE_SET:
114347 + {
114348 + ioc_fm_pcd_manip_params_t *param;
114349 + uint8_t *p_data = NULL;
114350 + uint8_t size;
114351 +
114352 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
114353 + sizeof(ioc_fm_pcd_manip_params_t));
114354 +
114355 + if (!param)
114356 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114357 +
114358 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
114359 +
114360 +#if defined(CONFIG_COMPAT)
114361 + if (compat)
114362 + {
114363 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114364 +
114365 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114366 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114367 + if (!compat_param)
114368 + {
114369 + XX_Free(param);
114370 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114371 + }
114372 +
114373 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114374 + if (copy_from_user(compat_param,
114375 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114376 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114377 + {
114378 + XX_Free(compat_param);
114379 + XX_Free(param);
114380 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114381 + }
114382 +
114383 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
114384 +
114385 + XX_Free(compat_param);
114386 + }
114387 + else
114388 +#endif
114389 + {
114390 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
114391 + sizeof(ioc_fm_pcd_manip_params_t)))
114392 + {
114393 + XX_Free(param);
114394 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114395 + }
114396 + }
114397 +
114398 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
114399 + {
114400 + size = param->u.hdr.insrt_params.u.generic.size;
114401 + p_data = (uint8_t *) XX_Malloc(size);
114402 + if (!p_data )
114403 + {
114404 + XX_Free(param);
114405 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
114406 + }
114407 +
114408 + if (param->u.hdr.insrt_params.u.generic.p_data &&
114409 + copy_from_user(p_data,
114410 + param->u.hdr.insrt_params.u.generic.p_data, size))
114411 + {
114412 + XX_Free(p_data);
114413 + XX_Free(param);
114414 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114415 + }
114416 +
114417 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
114418 + }
114419 +
114420 + if (param->id)
114421 + {
114422 + /* Security Hole: the user can pass any piece of garbage
114423 + in 'param->id', and that will go straight through to the LLD,
114424 + no checks being done by the wrapper! */
114425 + err = FM_PCD_ManipNodeReplace(
114426 + (t_Handle) param->id,
114427 + (t_FmPcdManipParams*) param);
114428 + if (err)
114429 + {
114430 + if (p_data)
114431 + XX_Free(p_data);
114432 + XX_Free(param);
114433 + break;
114434 + }
114435 + }
114436 + else
114437 + {
114438 + param->id = FM_PCD_ManipNodeSet(
114439 + p_LnxWrpFmDev->h_PcdDev,
114440 + (t_FmPcdManipParams*) param);
114441 + if (!param->id)
114442 + {
114443 + if (p_data)
114444 + XX_Free(p_data);
114445 + XX_Free(param);
114446 + err = E_INVALID_VALUE;
114447 + /* Since the LLD has no errno-style error reporting,
114448 + we're left here with no other option than to report
114449 + a generic E_INVALID_VALUE */
114450 + break;
114451 + }
114452 + }
114453 +
114454 +#if defined(CONFIG_COMPAT)
114455 + if (compat)
114456 + {
114457 + ioc_compat_fm_pcd_manip_params_t *compat_param;
114458 +
114459 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
114460 + sizeof(ioc_compat_fm_pcd_manip_params_t));
114461 + if (!compat_param)
114462 + {
114463 + if (p_data)
114464 + XX_Free(p_data);
114465 + XX_Free(param);
114466 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114467 + }
114468 +
114469 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
114470 +
114471 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
114472 +
114473 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
114474 + compat_param,
114475 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
114476 + err = E_READ_FAILED;
114477 +
114478 + XX_Free(compat_param);
114479 + }
114480 + else
114481 +#endif
114482 + {
114483 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
114484 + param, sizeof(ioc_fm_pcd_manip_params_t)))
114485 + err = E_READ_FAILED;
114486 + }
114487 +
114488 + if (p_data)
114489 + XX_Free(p_data);
114490 + XX_Free(param);
114491 + break;
114492 + }
114493 +
114494 +#if defined(CONFIG_COMPAT)
114495 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
114496 +#endif
114497 + case FM_PCD_IOC_MANIP_NODE_DELETE:
114498 + {
114499 + ioc_fm_obj_t id;
114500 +
114501 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114502 +#if defined(CONFIG_COMPAT)
114503 + if (compat)
114504 + {
114505 + ioc_compat_fm_obj_t compat_id;
114506 +
114507 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114508 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114509 +
114510 + compat_obj_delete(&compat_id, &id);
114511 + }
114512 + else
114513 +#endif
114514 + {
114515 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114516 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114517 + }
114518 +
114519 + err = FM_PCD_ManipNodeDelete(id.obj);
114520 + break;
114521 + }
114522 +
114523 +#if defined(CONFIG_COMPAT)
114524 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
114525 +#endif
114526 + case FM_PCD_IOC_MANIP_GET_STATS:
114527 + {
114528 + ioc_fm_pcd_manip_get_stats_t param;
114529 +
114530 +#if defined(CONFIG_COMPAT)
114531 + if (compat)
114532 + {
114533 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114534 +
114535 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
114536 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114537 + if (!compat_param)
114538 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114539 +
114540 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114541 + if (copy_from_user(compat_param,
114542 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
114543 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
114544 + {
114545 + XX_Free(compat_param);
114546 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114547 + }
114548 +
114549 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
114550 +
114551 + XX_Free(compat_param);
114552 + }
114553 + else
114554 +#endif
114555 + {
114556 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
114557 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114558 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114559 + }
114560 +
114561 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
114562 + (t_FmPcdManipStats*) &param.stats);
114563 +
114564 +#if defined(CONFIG_COMPAT)
114565 + if (compat)
114566 + {
114567 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
114568 +
114569 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
114570 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114571 + if (!compat_param)
114572 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114573 +
114574 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
114575 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
114576 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
114577 + compat_param,
114578 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
114579 + XX_Free(compat_param);
114580 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114581 + }
114582 + XX_Free(compat_param);
114583 + }
114584 + else
114585 +#endif
114586 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
114587 + &param,
114588 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
114589 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114590 +
114591 + break;
114592 + }
114593 +
114594 +#if (DPAA_VERSION >= 11)
114595 +#if defined(CONFIG_COMPAT)
114596 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
114597 +#endif
114598 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
114599 + {
114600 + ioc_fm_pcd_frm_replic_group_params_t *param;
114601 +
114602 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
114603 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114604 + if (!param)
114605 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114606 +
114607 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
114608 +
114609 +#if defined(CONFIG_COMPAT)
114610 + if (compat)
114611 + {
114612 + ioc_compat_fm_pcd_frm_replic_group_params_t
114613 + *compat_param;
114614 +
114615 + compat_param =
114616 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114617 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114618 + if (!compat_param)
114619 + {
114620 + XX_Free(param);
114621 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114622 + ("IOCTL FM PCD"));
114623 + }
114624 +
114625 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114626 + if (copy_from_user(compat_param,
114627 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114628 + compat_ptr(arg),
114629 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
114630 + XX_Free(compat_param);
114631 + XX_Free(param);
114632 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114633 + }
114634 +
114635 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114636 + param, COMPAT_US_TO_K);
114637 +
114638 + XX_Free(compat_param);
114639 + }
114640 + else
114641 +#endif
114642 + {
114643 + if (copy_from_user(param,
114644 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114645 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114646 + {
114647 + XX_Free(param);
114648 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
114649 + }
114650 + }
114651 +
114652 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
114653 + (t_FmPcdFrmReplicGroupParams*)param);
114654 +
114655 + if (!param->id) {
114656 + XX_Free(param);
114657 + err = E_INVALID_VALUE;
114658 + /*
114659 + * Since the LLD has no errno-style error reporting,
114660 + * we're left here with no other option than to report
114661 + * a generic E_INVALID_VALUE
114662 + */
114663 + break;
114664 + }
114665 +
114666 +#if defined(CONFIG_COMPAT)
114667 + if (compat)
114668 + {
114669 + ioc_compat_fm_pcd_frm_replic_group_params_t
114670 + *compat_param;
114671 +
114672 + compat_param =
114673 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114674 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114675 + if (!compat_param)
114676 + {
114677 + XX_Free(param);
114678 + RETURN_ERROR(MINOR, E_NO_MEMORY,
114679 + ("IOCTL FM PCD"));
114680 + }
114681 +
114682 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
114683 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
114684 + param, COMPAT_K_TO_US);
114685 + if (copy_to_user(
114686 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
114687 + compat_ptr(arg),
114688 + compat_param,
114689 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
114690 + err = E_WRITE_FAILED;
114691 +
114692 + XX_Free(compat_param);
114693 + }
114694 + else
114695 +#endif
114696 + {
114697 + if (copy_to_user(
114698 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
114699 + param,
114700 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
114701 + err = E_WRITE_FAILED;
114702 + }
114703 +
114704 + XX_Free(param);
114705 + break;
114706 + }
114707 + break;
114708 +
114709 +#if defined(CONFIG_COMPAT)
114710 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
114711 +#endif
114712 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
114713 + {
114714 + ioc_fm_obj_t id;
114715 +
114716 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114717 +#if defined(CONFIG_COMPAT)
114718 + if (compat)
114719 + {
114720 + ioc_compat_fm_obj_t compat_id;
114721 +
114722 + if (copy_from_user(&compat_id,
114723 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114724 + sizeof(ioc_compat_fm_obj_t)))
114725 + break;
114726 + compat_obj_delete(&compat_id, &id);
114727 + }
114728 + else
114729 +#endif
114730 + {
114731 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114732 + sizeof(ioc_fm_obj_t)))
114733 + break;
114734 + }
114735 +
114736 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
114737 + }
114738 + break;
114739 +
114740 +#if defined(CONFIG_COMPAT)
114741 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
114742 +#endif
114743 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
114744 + {
114745 + ioc_fm_pcd_frm_replic_member_params_t param;
114746 +
114747 +#if defined(CONFIG_COMPAT)
114748 + if (compat)
114749 + {
114750 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
114751 +
114752 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114753 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114754 +
114755 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
114756 + }
114757 + else
114758 +#endif
114759 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114760 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114761 +
114762 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
114763 + param.member.member_index,
114764 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
114765 + }
114766 + break;
114767 +
114768 +#if defined(CONFIG_COMPAT)
114769 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
114770 +#endif
114771 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
114772 + {
114773 + ioc_fm_pcd_frm_replic_member_t param;
114774 +
114775 +#if defined(CONFIG_COMPAT)
114776 + if (compat)
114777 + {
114778 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
114779 +
114780 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114781 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114782 +
114783 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
114784 + }
114785 + else
114786 +#endif
114787 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114788 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114789 +
114790 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
114791 + }
114792 + break;
114793 +
114794 +#if defined(CONFIG_COMPAT)
114795 + case FM_IOC_VSP_CONFIG_COMPAT:
114796 +#endif
114797 + case FM_IOC_VSP_CONFIG:
114798 + {
114799 + ioc_fm_vsp_params_t param;
114800 +
114801 +#if defined(CONFIG_COMPAT)
114802 + if (compat)
114803 + {
114804 + ioc_compat_fm_vsp_params_t compat_param;
114805 +
114806 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114807 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114808 +
114809 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
114810 + }
114811 + else
114812 +#endif
114813 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114814 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114815 + {
114816 + uint8_t portId = param.port_params.port_id;
114817 + param.liodn_offset =
114818 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
114819 + }
114820 + param.p_fm = p_LnxWrpFmDev->h_Dev;
114821 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
114822 +
114823 +#if defined(CONFIG_COMPAT)
114824 + if (compat)
114825 + {
114826 + ioc_compat_fm_vsp_params_t compat_param;
114827 +
114828 + memset(&compat_param, 0, sizeof(compat_param));
114829 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
114830 +
114831 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
114832 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114833 + }
114834 + else
114835 +#endif
114836 + if (copy_to_user((void *)arg, &param, sizeof(param)))
114837 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114838 + break;
114839 + }
114840 +
114841 +#if defined(CONFIG_COMPAT)
114842 + case FM_IOC_VSP_INIT_COMPAT:
114843 +#endif
114844 + case FM_IOC_VSP_INIT:
114845 + {
114846 + ioc_fm_obj_t id;
114847 +
114848 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114849 +#if defined(CONFIG_COMPAT)
114850 + if (compat)
114851 + {
114852 + ioc_compat_fm_obj_t compat_id;
114853 +
114854 + if (copy_from_user(&compat_id,
114855 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114856 + sizeof(ioc_compat_fm_obj_t)))
114857 + break;
114858 + id.obj = compat_pcd_id2ptr(compat_id.obj);
114859 + }
114860 + else
114861 +#endif
114862 + {
114863 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114864 + sizeof(ioc_fm_obj_t)))
114865 + break;
114866 + }
114867 +
114868 + return FM_VSP_Init(id.obj);
114869 + }
114870 +
114871 +#if defined(CONFIG_COMPAT)
114872 + case FM_IOC_VSP_FREE_COMPAT:
114873 +#endif
114874 + case FM_IOC_VSP_FREE:
114875 + {
114876 + ioc_fm_obj_t id;
114877 +
114878 + memset(&id, 0, sizeof(ioc_fm_obj_t));
114879 +#if defined(CONFIG_COMPAT)
114880 + if (compat)
114881 + {
114882 + ioc_compat_fm_obj_t compat_id;
114883 +
114884 + if (copy_from_user(&compat_id,
114885 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
114886 + sizeof(ioc_compat_fm_obj_t)))
114887 + break;
114888 + compat_obj_delete(&compat_id, &id);
114889 + }
114890 + else
114891 +#endif
114892 + {
114893 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
114894 + sizeof(ioc_fm_obj_t)))
114895 + break;
114896 + }
114897 +
114898 + return FM_VSP_Free(id.obj);
114899 + }
114900 +
114901 +#if defined(CONFIG_COMPAT)
114902 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
114903 +#endif
114904 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
114905 + {
114906 + ioc_fm_buf_pool_depletion_params_t param;
114907 +
114908 +#if defined(CONFIG_COMPAT)
114909 + if (compat)
114910 + {
114911 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
114912 +
114913 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114914 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114915 +
114916 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
114917 + }
114918 + else
114919 +#endif
114920 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114921 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114922 +
114923 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
114924 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
114925 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114926 +
114927 + break;
114928 + }
114929 +
114930 +
114931 +#if defined(CONFIG_COMPAT)
114932 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
114933 +#endif
114934 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
114935 + {
114936 + ioc_fm_buffer_prefix_content_params_t param;
114937 +
114938 +#if defined(CONFIG_COMPAT)
114939 + if (compat)
114940 + {
114941 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
114942 +
114943 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114944 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114945 +
114946 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
114947 + }
114948 + else
114949 +#endif
114950 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114951 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114952 +
114953 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
114954 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
114955 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114956 +
114957 + break;
114958 + }
114959 +
114960 +#if defined(CONFIG_COMPAT)
114961 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
114962 +#endif
114963 + case FM_IOC_VSP_CONFIG_NO_SG:
114964 + {
114965 + ioc_fm_vsp_config_no_sg_params_t param;
114966 +
114967 +#if defined(CONFIG_COMPAT)
114968 + if (compat)
114969 + {
114970 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
114971 +
114972 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
114973 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114974 +
114975 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
114976 + }
114977 + else
114978 +#endif
114979 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
114980 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114981 +
114982 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
114983 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114984 +
114985 + break;
114986 + }
114987 +
114988 +#if defined(CONFIG_COMPAT)
114989 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
114990 +#endif
114991 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
114992 + {
114993 + ioc_fm_vsp_prs_result_params_t param;
114994 +
114995 +#if defined(CONFIG_COMPAT)
114996 + if (compat)
114997 + {
114998 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
114999 +
115000 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
115001 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115002 +
115003 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
115004 + }
115005 + else
115006 +#endif
115007 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
115008 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115009 +
115010 + /* this call just adds the parse results offset to p_data */
115011 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
115012 +
115013 + if (!param.p_data)
115014 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115015 +
115016 +#if defined(CONFIG_COMPAT)
115017 + if (compat)
115018 + {
115019 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
115020 +
115021 + memset(&compat_param, 0, sizeof(compat_param));
115022 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
115023 +
115024 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
115025 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115026 + }
115027 + else
115028 +#endif
115029 + if (copy_to_user((void *)arg, &param, sizeof(param)))
115030 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115031 +
115032 + break;
115033 + }
115034 +#endif /* (DPAA_VERSION >= 11) */
115035 +
115036 +#ifdef FM_CAPWAP_SUPPORT
115037 +#warning "feature not supported!"
115038 +#if defined(CONFIG_COMPAT)
115039 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
115040 +#endif
115041 + case FM_PCD_IOC_STATISTICS_SET_NODE:
115042 + {
115043 +/* ioc_fm_pcd_stats_params_t param;
115044 + ...
115045 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
115046 + (t_FmPcdStatsParams *)&param);
115047 +*/
115048 + err = E_NOT_SUPPORTED;
115049 + break;
115050 + }
115051 +#endif /* FM_CAPWAP_SUPPORT */
115052 +
115053 + default:
115054 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
115055 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
115056 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
115057 + }
115058 +
115059 + if (err)
115060 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
115061 +
115062 + return E_OK;
115063 +}
115064 +
115065 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
115066 +{
115067 + p_version->version.major = FMD_API_VERSION_MAJOR;
115068 + p_version->version.minor = FMD_API_VERSION_MINOR;
115069 + p_version->version.respin = FMD_API_VERSION_RESPIN;
115070 + p_version->version.reserved = 0;
115071 +}
115072 +
115073 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
115074 +{
115075 + t_Error err = E_OK;
115076 +
115077 + switch (cmd)
115078 + {
115079 + case FM_IOC_SET_PORTS_BANDWIDTH:
115080 + {
115081 + ioc_fm_port_bandwidth_params *param;
115082 +
115083 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
115084 + if (!param)
115085 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115086 +
115087 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
115088 +
115089 +#if defined(CONFIG_COMPAT)
115090 + if (compat)
115091 + {
115092 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
115093 + {
115094 + XX_Free(param);
115095 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115096 + }
115097 + }
115098 + else
115099 +#endif
115100 + {
115101 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
115102 + {
115103 + XX_Free(param);
115104 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115105 + }
115106 + }
115107 +
115108 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
115109 +
115110 + XX_Free(param);
115111 + break;
115112 + }
115113 +
115114 + case FM_IOC_GET_REVISION:
115115 + {
115116 + ioc_fm_revision_info_t *param;
115117 +
115118 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
115119 + if (!param)
115120 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115121 +
115122 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
115123 + /* This one never returns anything other than E_OK */
115124 +
115125 +#if defined(CONFIG_COMPAT)
115126 + if (compat)
115127 + {
115128 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
115129 + param,
115130 + sizeof(ioc_fm_revision_info_t))){
115131 + XX_Free(param);
115132 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115133 + }
115134 + }
115135 + else
115136 +#endif
115137 + {
115138 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
115139 + param,
115140 + sizeof(ioc_fm_revision_info_t))){
115141 + XX_Free(param);
115142 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115143 + }
115144 + }
115145 + XX_Free(param);
115146 + break;
115147 + }
115148 +
115149 + case FM_IOC_SET_COUNTER:
115150 + {
115151 + ioc_fm_counters_params_t *param;
115152 +
115153 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115154 + if (!param)
115155 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115156 +
115157 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115158 +
115159 +#if defined(CONFIG_COMPAT)
115160 + if (compat)
115161 + {
115162 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115163 + {
115164 + XX_Free(param);
115165 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115166 + }
115167 + }
115168 + else
115169 +#endif
115170 + {
115171 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115172 + {
115173 + XX_Free(param);
115174 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115175 + }
115176 + }
115177 +
115178 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
115179 +
115180 + XX_Free(param);
115181 + break;
115182 + }
115183 +
115184 + case FM_IOC_GET_COUNTER:
115185 + {
115186 + ioc_fm_counters_params_t *param;
115187 +
115188 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
115189 + if (!param)
115190 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115191 +
115192 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
115193 +
115194 +#if defined(CONFIG_COMPAT)
115195 + if (compat)
115196 + {
115197 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
115198 + {
115199 + XX_Free(param);
115200 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115201 + }
115202 + }
115203 + else
115204 +#endif
115205 + {
115206 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
115207 + {
115208 + XX_Free(param);
115209 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115210 + }
115211 + }
115212 +
115213 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
115214 +
115215 +#if defined(CONFIG_COMPAT)
115216 + if (compat)
115217 + {
115218 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
115219 + err = E_READ_FAILED;
115220 + }
115221 + else
115222 +#endif
115223 + {
115224 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
115225 + err = E_READ_FAILED;
115226 + }
115227 +
115228 + XX_Free(param);
115229 + break;
115230 + }
115231 +
115232 + case FM_IOC_FORCE_INTR:
115233 + {
115234 + ioc_fm_exceptions param;
115235 +
115236 +#if defined(CONFIG_COMPAT)
115237 + if (compat)
115238 + {
115239 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
115240 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115241 + }
115242 + else
115243 +#endif
115244 + {
115245 + if (get_user(param, (ioc_fm_exceptions*)arg))
115246 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115247 + }
115248 +
115249 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
115250 + break;
115251 + }
115252 +
115253 + case FM_IOC_GET_API_VERSION:
115254 + {
115255 + ioc_fm_api_version_t version;
115256 +
115257 + FM_Get_Api_Version(&version);
115258 +
115259 +#if defined(CONFIG_COMPAT)
115260 + if (compat)
115261 + {
115262 + if (copy_to_user(
115263 + (ioc_fm_api_version_t *)compat_ptr(arg),
115264 + &version, sizeof(version)))
115265 + err = E_READ_FAILED;
115266 + }
115267 + else
115268 +#endif
115269 + {
115270 + if (copy_to_user((ioc_fm_api_version_t *)arg,
115271 + &version, sizeof(version)))
115272 + err = E_READ_FAILED;
115273 + }
115274 + }
115275 + break;
115276 +
115277 + case FM_IOC_CTRL_MON_START:
115278 + {
115279 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
115280 + }
115281 + break;
115282 +
115283 + case FM_IOC_CTRL_MON_STOP:
115284 + {
115285 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
115286 + }
115287 + break;
115288 +
115289 +#if defined(CONFIG_COMPAT)
115290 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
115291 +#endif
115292 + case FM_IOC_CTRL_MON_GET_COUNTERS:
115293 + {
115294 + ioc_fm_ctrl_mon_counters_params_t param;
115295 + t_FmCtrlMon mon;
115296 +
115297 +#if defined(CONFIG_COMPAT)
115298 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
115299 +
115300 + if (compat)
115301 + {
115302 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
115303 + sizeof(compat_param)))
115304 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115305 +
115306 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
115307 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
115308 + }
115309 + else
115310 +#endif
115311 + {
115312 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
115313 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115314 + }
115315 +
115316 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
115317 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115318 +
115319 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
115320 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115321 + }
115322 + break;
115323 +
115324 + default:
115325 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
115326 + }
115327 +
115328 + if (err)
115329 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
115330 +
115331 + return E_OK;
115332 +}
115333 +
115334 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
115335 +{
115336 + t_Error err = E_OK;
115337 +
115338 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
115339 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
115340 +
115341 + switch (cmd)
115342 + {
115343 + case FM_PORT_IOC_DISABLE:
115344 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
115345 + /* deliberately ignoring error codes here */
115346 + return E_OK;
115347 +
115348 + case FM_PORT_IOC_ENABLE:
115349 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
115350 + /* deliberately ignoring error codes here */
115351 + return E_OK;
115352 +
115353 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
115354 + {
115355 + ioc_fm_port_frame_err_select_t errs;
115356 +
115357 +#if defined(CONFIG_COMPAT)
115358 + if (compat)
115359 + {
115360 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
115361 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115362 + }
115363 + else
115364 +#endif
115365 + {
115366 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
115367 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115368 + }
115369 +
115370 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
115371 + break;
115372 + }
115373 +
115374 + case FM_PORT_IOC_SET_RATE_LIMIT:
115375 + {
115376 + ioc_fm_port_rate_limit_t *param;
115377 +
115378 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
115379 + if (!param)
115380 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115381 +
115382 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
115383 +
115384 +#if defined(CONFIG_COMPAT)
115385 + if (compat)
115386 + {
115387 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
115388 + {
115389 + XX_Free(param);
115390 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115391 + }
115392 + }
115393 + else
115394 +#endif
115395 + {
115396 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
115397 + {
115398 + XX_Free(param);
115399 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115400 + }
115401 + }
115402 +
115403 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
115404 +
115405 + XX_Free(param);
115406 + break;
115407 + }
115408 +
115409 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
115410 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
115411 + /* deliberately ignoring error codes here */
115412 + return E_OK;
115413 +
115414 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
115415 + {
115416 + ioc_fm_port_pcd_fqids_params_t *param;
115417 +
115418 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
115419 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115420 +
115421 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
115422 + if (!param)
115423 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115424 +
115425 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
115426 +
115427 +#if defined(CONFIG_COMPAT)
115428 + if (compat)
115429 + {
115430 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115431 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115432 + {
115433 + XX_Free(param);
115434 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115435 + }
115436 + }
115437 + else
115438 +#endif
115439 + {
115440 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
115441 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
115442 + {
115443 + XX_Free(param);
115444 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115445 + }
115446 + }
115447 +
115448 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
115449 + param->num_fqids,
115450 + param->alignment,
115451 + &param->base_fqid))
115452 + {
115453 + XX_Free(param);
115454 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
115455 + }
115456 +
115457 +#if defined(CONFIG_COMPAT)
115458 + if (compat)
115459 + {
115460 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
115461 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115462 + err = E_READ_FAILED;
115463 + }
115464 + else
115465 +#endif
115466 + {
115467 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
115468 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
115469 + err = E_READ_FAILED;
115470 + }
115471 +
115472 + XX_Free(param);
115473 + break;
115474 + }
115475 +
115476 + case FM_PORT_IOC_FREE_PCD_FQIDS:
115477 + {
115478 + uint32_t base_fqid;
115479 +
115480 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
115481 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
115482 +
115483 +#if defined(CONFIG_COMPAT)
115484 + if (compat)
115485 + {
115486 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
115487 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115488 + }
115489 + else
115490 +#endif
115491 + {
115492 + if (get_user(base_fqid, (uint32_t*)arg))
115493 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115494 + }
115495 +
115496 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
115497 + err = E_WRITE_FAILED;
115498 +
115499 + break;
115500 + }
115501 +
115502 +#if defined(CONFIG_COMPAT)
115503 + case FM_PORT_IOC_SET_PCD_COMPAT:
115504 +#endif
115505 + case FM_PORT_IOC_SET_PCD:
115506 + {
115507 + ioc_fm_port_pcd_params_t *port_pcd_params;
115508 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
115509 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
115510 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
115511 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
115512 +
115513 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
115514 + sizeof(ioc_fm_port_pcd_params_t) +
115515 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115516 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115517 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115518 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115519 + if (!port_pcd_params)
115520 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115521 +
115522 + memset(port_pcd_params, 0,
115523 + sizeof(ioc_fm_port_pcd_params_t) +
115524 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115525 + sizeof(ioc_fm_port_pcd_cc_params_t) +
115526 + sizeof(ioc_fm_port_pcd_kg_params_t) +
115527 + sizeof(ioc_fm_port_pcd_plcr_params_t));
115528 +
115529 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
115530 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
115531 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
115532 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
115533 +
115534 +#if defined(CONFIG_COMPAT)
115535 + if (compat)
115536 + {
115537 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
115538 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
115539 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
115540 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
115541 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
115542 +
115543 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
115544 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115545 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115546 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115547 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115548 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115549 + if (!compat_port_pcd_params)
115550 + {
115551 + XX_Free(port_pcd_params);
115552 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115553 + }
115554 +
115555 + memset(compat_port_pcd_params, 0,
115556 + sizeof(ioc_compat_fm_port_pcd_params_t) +
115557 + sizeof(ioc_fm_port_pcd_prs_params_t) +
115558 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
115559 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
115560 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
115561 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
115562 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
115563 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
115564 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
115565 +
115566 + if (copy_from_user(compat_port_pcd_params,
115567 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
115568 + sizeof(ioc_compat_fm_port_pcd_params_t)))
115569 + err = E_WRITE_FAILED;
115570 +
115571 + while (!err) /* pseudo-while */
115572 + {
115573 + /* set pointers from where to copy from: */
115574 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
115575 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
115576 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
115577 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
115578 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
115579 +#if (DPAA_VERSION >= 11)
115580 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
115581 +#endif
115582 + /* the prs member is the same, no compat structure...memcpy only */
115583 + if (port_pcd_params->p_prs_params)
115584 + {
115585 + if (copy_from_user(same_port_pcd_prs_params,
115586 + port_pcd_params->p_prs_params,
115587 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115588 + {
115589 + err = E_WRITE_FAILED;
115590 + break; /* from pseudo-while */
115591 + }
115592 +
115593 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
115594 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115595 + }
115596 +
115597 + if (port_pcd_params->p_cc_params)
115598 + {
115599 + if (copy_from_user(compat_port_pcd_cc_params,
115600 + port_pcd_params->p_cc_params,
115601 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
115602 + {
115603 + err = E_WRITE_FAILED;
115604 + break; /* from pseudo-while */
115605 + }
115606 +
115607 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115608 + }
115609 +
115610 + if (port_pcd_params->p_kg_params)
115611 + {
115612 + if (copy_from_user(compat_port_pcd_kg_params,
115613 + port_pcd_params->p_kg_params,
115614 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
115615 + {
115616 + err = E_WRITE_FAILED;
115617 + break; /* from pseudo-while */
115618 + }
115619 +
115620 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115621 + }
115622 +
115623 + if (port_pcd_params->p_plcr_params)
115624 + {
115625 + if (copy_from_user(compat_port_pcd_plcr_params,
115626 + port_pcd_params->p_plcr_params,
115627 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
115628 + {
115629 + err = E_WRITE_FAILED;
115630 + break; /* from pseudo-while */
115631 + }
115632 +
115633 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115634 + }
115635 +
115636 + break; /* pseudo-while: always run once! */
115637 + }
115638 +
115639 + if (!err)
115640 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
115641 +
115642 + XX_Free(compat_port_pcd_params);
115643 + }
115644 + else
115645 +#endif
115646 + {
115647 + if (copy_from_user(port_pcd_params,
115648 + (ioc_fm_port_pcd_params_t*) arg,
115649 + sizeof(ioc_fm_port_pcd_params_t)))
115650 + err = E_WRITE_FAILED;
115651 +
115652 + while (!err) /* pseudo-while */
115653 + {
115654 + if (port_pcd_params->p_prs_params)
115655 + {
115656 + if (copy_from_user(port_pcd_prs_params,
115657 + port_pcd_params->p_prs_params,
115658 + sizeof(ioc_fm_port_pcd_prs_params_t)))
115659 + {
115660 + err = E_WRITE_FAILED;
115661 + break; /* from pseudo-while */
115662 + }
115663 +
115664 + port_pcd_params->p_prs_params = port_pcd_prs_params;
115665 + }
115666 +
115667 + if (port_pcd_params->p_cc_params)
115668 + {
115669 + if (copy_from_user(port_pcd_cc_params,
115670 + port_pcd_params->p_cc_params,
115671 + sizeof(ioc_fm_port_pcd_cc_params_t)))
115672 + {
115673 + err = E_WRITE_FAILED;
115674 + break; /* from pseudo-while */
115675 + }
115676 +
115677 + port_pcd_params->p_cc_params = port_pcd_cc_params;
115678 + }
115679 +
115680 + if (port_pcd_params->p_kg_params)
115681 + {
115682 + if (copy_from_user(port_pcd_kg_params,
115683 + port_pcd_params->p_kg_params,
115684 + sizeof(ioc_fm_port_pcd_kg_params_t)))
115685 + {
115686 + err = E_WRITE_FAILED;
115687 + break; /* from pseudo-while */
115688 + }
115689 +
115690 + port_pcd_params->p_kg_params = port_pcd_kg_params;
115691 + }
115692 +
115693 + if (port_pcd_params->p_plcr_params)
115694 + {
115695 + if (copy_from_user(port_pcd_plcr_params,
115696 + port_pcd_params->p_plcr_params,
115697 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
115698 + {
115699 + err = E_WRITE_FAILED;
115700 + break; /* from pseudo-while */
115701 + }
115702 +
115703 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
115704 + }
115705 +
115706 + break; /* pseudo-while: always run once! */
115707 + }
115708 + }
115709 +
115710 + if (!err)
115711 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
115712 +
115713 + XX_Free(port_pcd_params);
115714 + break;
115715 + }
115716 +
115717 + case FM_PORT_IOC_DELETE_PCD:
115718 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
115719 + break;
115720 +
115721 +#if defined(CONFIG_COMPAT)
115722 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
115723 +#endif
115724 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
115725 + {
115726 + ioc_fm_pcd_kg_scheme_select_t *param;
115727 +
115728 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115729 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
115730 + if (!param)
115731 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115732 +
115733 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
115734 +
115735 +#if defined(CONFIG_COMPAT)
115736 + if (compat)
115737 + {
115738 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
115739 +
115740 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
115741 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115742 + if (!compat_param)
115743 + {
115744 + XX_Free(param);
115745 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115746 + }
115747 +
115748 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
115749 + if (copy_from_user(compat_param,
115750 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
115751 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
115752 + {
115753 + XX_Free(compat_param);
115754 + XX_Free(param);
115755 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115756 + }
115757 +
115758 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
115759 +
115760 + XX_Free(compat_param);
115761 + }
115762 + else
115763 +#endif
115764 + {
115765 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
115766 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
115767 + {
115768 + XX_Free(param);
115769 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115770 + }
115771 + }
115772 +
115773 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
115774 +
115775 + XX_Free(param);
115776 + break;
115777 + }
115778 +
115779 +#if defined(CONFIG_COMPAT)
115780 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
115781 +#endif
115782 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
115783 + {
115784 + ioc_fm_obj_t id;
115785 +
115786 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115787 +
115788 +#if defined(CONFIG_COMPAT)
115789 + if (compat)
115790 + {
115791 + ioc_compat_fm_obj_t compat_id;
115792 +
115793 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115794 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115795 +
115796 + id.obj = compat_ptr(compat_id.obj);
115797 + }
115798 + else
115799 +#endif
115800 + {
115801 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115802 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115803 + }
115804 +
115805 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
115806 + break;
115807 + }
115808 +
115809 +#if defined(CONFIG_COMPAT)
115810 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
115811 +#endif
115812 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
115813 + {
115814 + ioc_fm_pcd_port_schemes_params_t *param;
115815 +
115816 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115817 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115818 + if (!param)
115819 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115820 +
115821 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115822 +
115823 +#if defined(CONFIG_COMPAT)
115824 + if (compat)
115825 + {
115826 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115827 +
115828 + if (copy_from_user(&compat_param,
115829 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115830 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115831 + {
115832 + XX_Free(param);
115833 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115834 + }
115835 +
115836 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115837 + }
115838 + else
115839 +#endif
115840 + {
115841 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115842 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115843 + {
115844 + XX_Free(param);
115845 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115846 + }
115847 + }
115848 +
115849 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115850 +
115851 + XX_Free(param);
115852 + break;
115853 + }
115854 +
115855 +#if defined(CONFIG_COMPAT)
115856 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
115857 +#endif
115858 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
115859 + {
115860 + ioc_fm_pcd_port_schemes_params_t *param;
115861 +
115862 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
115863 + sizeof(ioc_fm_pcd_port_schemes_params_t));
115864 + if (!param)
115865 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115866 +
115867 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
115868 +
115869 +#if defined(CONFIG_COMPAT)
115870 + if (compat)
115871 + {
115872 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
115873 +
115874 + if (copy_from_user(&compat_param,
115875 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
115876 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
115877 + {
115878 + XX_Free(param);
115879 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115880 + }
115881 +
115882 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
115883 + }
115884 + else
115885 +#endif
115886 + {
115887 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
115888 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
115889 + {
115890 + XX_Free(param);
115891 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115892 + }
115893 + }
115894 +
115895 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
115896 +
115897 + XX_Free(param);
115898 + break;
115899 + }
115900 +
115901 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
115902 + {
115903 + uint16_t num;
115904 + if (get_user(num, (uint16_t*) arg))
115905 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115906 +
115907 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
115908 + break;
115909 + }
115910 +
115911 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
115912 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
115913 + break;
115914 +
115915 + case FM_PORT_IOC_DETACH_PCD:
115916 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
115917 + break;
115918 +
115919 + case FM_PORT_IOC_ATTACH_PCD:
115920 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
115921 + break;
115922 +
115923 +#if defined(CONFIG_COMPAT)
115924 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
115925 +#endif
115926 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
115927 + {
115928 + ioc_fm_obj_t id;
115929 +
115930 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
115931 +
115932 +#if defined(CONFIG_COMPAT)
115933 + if (compat)
115934 + {
115935 + ioc_compat_fm_obj_t compat_id;
115936 +
115937 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115938 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115939 +
115940 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
115941 + }
115942 + else
115943 +#endif
115944 + {
115945 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115946 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115947 + }
115948 +
115949 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
115950 + break;
115951 + }
115952 +
115953 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
115954 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
115955 + {
115956 + ioc_fm_port_congestion_groups_t *param;
115957 +
115958 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
115959 + if (!param)
115960 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
115961 +
115962 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
115963 +
115964 +#if defined(CONFIG_COMPAT)
115965 + if (compat)
115966 + {
115967 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
115968 + sizeof(t_FmPortCongestionGrps)))
115969 + {
115970 + XX_Free(param);
115971 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115972 + }
115973 + }
115974 + else
115975 +#endif /* CONFIG_COMPAT */
115976 + {
115977 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
115978 + sizeof(t_FmPortCongestionGrps)))
115979 + {
115980 + XX_Free(param);
115981 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115982 + }
115983 + }
115984 +
115985 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
115986 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115987 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
115988 + ;
115989 +
115990 + XX_Free(param);
115991 + break;
115992 + }
115993 +
115994 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
115995 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
115996 + {
115997 + ioc_fm_port_mac_addr_params_t *param;
115998 +
115999 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
116000 + sizeof(ioc_fm_port_mac_addr_params_t));
116001 + if (!param)
116002 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116003 +
116004 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
116005 +
116006 +#if defined(CONFIG_COMPAT)
116007 + if (compat)
116008 + {
116009 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
116010 + sizeof(ioc_fm_port_mac_addr_params_t)))
116011 + {
116012 + XX_Free(param);
116013 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116014 + }
116015 + }
116016 + else
116017 +#endif /* CONFIG_COMPAT */
116018 + {
116019 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
116020 + sizeof(ioc_fm_port_mac_addr_params_t)))
116021 + {
116022 + XX_Free(param);
116023 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116024 + }
116025 + }
116026 +
116027 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
116028 + {
116029 + int id = -1;
116030 +
116031 + switch(p_LnxWrpFmPortDev->settings.param.portType)
116032 + {
116033 + case e_FM_PORT_TYPE_RX:
116034 + case e_FM_PORT_TYPE_TX:
116035 + id = p_LnxWrpFmPortDev->id;
116036 + break;
116037 + case e_FM_PORT_TYPE_RX_10G:
116038 + case e_FM_PORT_TYPE_TX_10G:
116039 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
116040 + break;
116041 + default:
116042 + err = E_NOT_AVAILABLE;
116043 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
116044 + }
116045 + if (id >= 0)
116046 + {
116047 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116048 + t_Handle mac_handle = fm->macs[id].h_Dev;
116049 +
116050 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
116051 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
116052 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
116053 + }
116054 + }
116055 + else
116056 + {
116057 + err = E_NOT_AVAILABLE;
116058 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
116059 + }
116060 +
116061 + XX_Free(param);
116062 + break;
116063 + }
116064 +
116065 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
116066 + {
116067 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116068 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116069 + ioc_fm_port_tx_pause_frames_params_t param;
116070 + int mac_id = p_LnxWrpFmPortDev->id;
116071 +
116072 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
116073 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116074 +
116075 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
116076 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
116077 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116078 +
116079 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
116080 + {
116081 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116082 + param.priority,
116083 + param.pause_time,
116084 + param.thresh_time);
116085 + }
116086 + else
116087 + {
116088 + err = E_NOT_AVAILABLE;
116089 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
116090 + }
116091 +
116092 + break;
116093 + }
116094 +
116095 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
116096 + {
116097 + ioc_fm_buffer_prefix_content_t *param;
116098 +
116099 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
116100 + if (!param)
116101 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116102 +
116103 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
116104 +
116105 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
116106 + sizeof(ioc_fm_buffer_prefix_content_t)))
116107 + {
116108 + XX_Free(param);
116109 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116110 + }
116111 +
116112 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
116113 + (t_FmBufferPrefixContent *)param))
116114 + {
116115 + XX_Free(param);
116116 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116117 + }
116118 +
116119 + XX_Free(param);
116120 + break;
116121 + }
116122 +
116123 +#if (DPAA_VERSION >= 11)
116124 +#if defined(CONFIG_COMPAT)
116125 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
116126 +#endif
116127 + case FM_PORT_IOC_VSP_ALLOC:
116128 + {
116129 + ioc_fm_port_vsp_alloc_params_t *param;
116130 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116131 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
116132 +
116133 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
116134 + sizeof(ioc_fm_port_vsp_alloc_params_t));
116135 + if (!param)
116136 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116137 +
116138 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
116139 +
116140 +#if defined(CONFIG_COMPAT)
116141 + if (compat)
116142 + {
116143 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
116144 +
116145 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
116146 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116147 + if (!compat_param)
116148 + {
116149 + XX_Free(param);
116150 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
116151 + }
116152 +
116153 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
116154 + if (copy_from_user(compat_param,
116155 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
116156 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
116157 + {
116158 + XX_Free(compat_param);
116159 + XX_Free(param);
116160 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116161 + }
116162 +
116163 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
116164 +
116165 + XX_Free(compat_param);
116166 + }
116167 + else
116168 +#endif
116169 + {
116170 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
116171 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
116172 + {
116173 + XX_Free(param);
116174 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116175 + }
116176 + }
116177 +
116178 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
116179 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
116180 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
116181 + {
116182 + /* Determine the Tx port t_Handle from the Rx port id */
116183 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116184 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
116185 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
116186 + }
116187 +
116188 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
116189 + {
116190 + XX_Free(param);
116191 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116192 + }
116193 +
116194 + XX_Free(param);
116195 + break;
116196 + }
116197 +#endif /* (DPAA_VERSION >= 11) */
116198 +
116199 + case FM_PORT_IOC_GET_MAC_STATISTICS:
116200 + {
116201 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116202 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116203 + ioc_fm_port_mac_statistics_t param;
116204 + int mac_id = p_LnxWrpFmPortDev->id;
116205 +
116206 + if (!p_LnxWrpFmDev)
116207 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116208 +
116209 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116210 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116211 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116212 +
116213 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116214 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116215 +
116216 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116217 + (t_FmMacStatistics *)&param))
116218 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116219 +
116220 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
116221 + sizeof(ioc_fm_port_mac_statistics_t)))
116222 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116223 +
116224 + break;
116225 + }
116226 +
116227 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
116228 + {
116229 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116230 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116231 + ioc_fm_port_mac_frame_size_counters_t param;
116232 + t_FmMacFrameSizeCounters frameSizeCounters;
116233 + int mac_id = p_LnxWrpFmPortDev->id;
116234 +
116235 + if (!p_LnxWrpFmDev)
116236 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116237 +
116238 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
116239 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
116240 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
116241 +
116242 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
116243 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116244 +
116245 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
116246 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116247 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116248 +
116249 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
116250 + &frameSizeCounters, param.type))
116251 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116252 +
116253 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
116254 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
116255 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
116256 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
116257 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
116258 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
116259 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
116260 +
116261 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
116262 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
116263 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116264 +
116265 + break;
116266 + }
116267 +
116268 + case FM_PORT_IOC_GET_BMI_COUNTERS:
116269 + {
116270 + t_LnxWrpFmDev *p_LnxWrpFmDev =
116271 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
116272 + ioc_fm_port_bmi_stats_t param;
116273 +
116274 + if (!p_LnxWrpFmDev)
116275 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
116276 +
116277 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
116278 + (t_FmPortBmiStats *)&param))
116279 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116280 +
116281 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
116282 + sizeof(ioc_fm_port_bmi_stats_t)))
116283 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116284 +
116285 + break;
116286 + }
116287 +
116288 + default:
116289 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116290 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
116291 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116292 + }
116293 +
116294 + if (err)
116295 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
116296 +
116297 + return E_OK;
116298 +}
116299 +
116300 +/*****************************************************************************/
116301 +/* API routines for the FM Linux Device */
116302 +/*****************************************************************************/
116303 +
116304 +static int fm_open(struct inode *inode, struct file *file)
116305 +{
116306 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
116307 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
116308 + unsigned int major = imajor(inode);
116309 + unsigned int minor = iminor(inode);
116310 + struct device_node *fm_node;
116311 + static struct of_device_id fm_node_of_match[] = {
116312 + { .compatible = "fsl,fman", },
116313 + { /* end of list */ },
116314 + };
116315 +
116316 + DBG(TRACE, ("Opening minor - %d - ", minor));
116317 +
116318 + if (file->private_data != NULL)
116319 + return 0;
116320 +
116321 + /* Get all the FM nodes */
116322 + for_each_matching_node(fm_node, fm_node_of_match) {
116323 + struct platform_device *of_dev;
116324 +
116325 + of_dev = of_find_device_by_node(fm_node);
116326 + if (unlikely(of_dev == NULL)) {
116327 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
116328 + return -ENXIO;
116329 + }
116330 +
116331 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
116332 + if (p_LnxWrpFmDev->major == major)
116333 + break;
116334 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116335 + p_LnxWrpFmDev = NULL;
116336 + }
116337 +
116338 + if (!p_LnxWrpFmDev)
116339 + return -ENODEV;
116340 +
116341 + if (minor == DEV_FM_MINOR_BASE)
116342 + file->private_data = p_LnxWrpFmDev;
116343 + else if (minor == DEV_FM_PCD_MINOR_BASE)
116344 + file->private_data = p_LnxWrpFmDev;
116345 + else {
116346 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
116347 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
116348 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
116349 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
116350 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
116351 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
116352 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
116353 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
116354 + else
116355 + return -EINVAL;
116356 +
116357 + /* if trying to open port, check if it initialized */
116358 + if (!p_LnxWrpFmPortDev->h_Dev)
116359 + return -ENODEV;
116360 +
116361 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
116362 + file->private_data = p_LnxWrpFmPortDev;
116363 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116364 + }
116365 +
116366 + if (file->private_data == NULL)
116367 + return -ENXIO;
116368 +
116369 + return 0;
116370 +}
116371 +
116372 +static int fm_close(struct inode *inode, struct file *file)
116373 +{
116374 + t_LnxWrpFmDev *p_LnxWrpFmDev;
116375 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
116376 + unsigned int minor = iminor(inode);
116377 + int err = 0;
116378 +
116379 + DBG(TRACE, ("Closing minor - %d - ", minor));
116380 +
116381 + if ((minor == DEV_FM_MINOR_BASE) ||
116382 + (minor == DEV_FM_PCD_MINOR_BASE))
116383 + {
116384 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
116385 + if (!p_LnxWrpFmDev)
116386 + return -ENODEV;
116387 + fm_unbind((struct fm *)p_LnxWrpFmDev);
116388 + }
116389 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116390 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116391 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116392 + {
116393 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
116394 + if (!p_LnxWrpFmPortDev)
116395 + return -ENODEV;
116396 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
116397 + }
116398 +
116399 + return err;
116400 +}
116401 +
116402 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
116403 +{
116404 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
116405 +
116406 + if ((minor == DEV_FM_MINOR_BASE) ||
116407 + (minor == DEV_FM_PCD_MINOR_BASE))
116408 + {
116409 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
116410 + if (!p_LnxWrpFmDev)
116411 + return -ENODEV;
116412 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
116413 + return -EFAULT;
116414 + }
116415 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
116416 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
116417 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
116418 + {
116419 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
116420 + if (!p_LnxWrpFmPortDev)
116421 + return -ENODEV;
116422 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
116423 + return -EFAULT;
116424 + }
116425 + else
116426 + {
116427 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
116428 + return -ENODEV;
116429 + }
116430 +
116431 + return 0;
116432 +}
116433 +
116434 +#ifdef CONFIG_COMPAT
116435 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116436 +{
116437 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116438 + long res;
116439 +
116440 + fm_mutex_lock();
116441 + res = fm_ioctls(minor, file, cmd, arg, true);
116442 + fm_mutex_unlock();
116443 +
116444 + return res;
116445 +}
116446 +#endif
116447 +
116448 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
116449 +{
116450 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
116451 + long res;
116452 +
116453 + fm_mutex_lock();
116454 + res = fm_ioctls(minor, file, cmd, arg, false);
116455 + fm_mutex_unlock();
116456 +
116457 + return res;
116458 +}
116459 +
116460 +/* Globals for FM character device */
116461 +struct file_operations fm_fops =
116462 +{
116463 + .owner = THIS_MODULE,
116464 + .unlocked_ioctl = fm_ioctl,
116465 +#ifdef CONFIG_COMPAT
116466 + .compat_ioctl = fm_compat_ioctl,
116467 +#endif
116468 + .open = fm_open,
116469 + .release = fm_close,
116470 +};
116471 --- /dev/null
116472 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
116473 @@ -0,0 +1,1297 @@
116474 +/*
116475 + * Copyright 2008-2012 Freescale Semiconductor Inc.
116476 + *
116477 + * Redistribution and use in source and binary forms, with or without
116478 + * modification, are permitted provided that the following conditions are met:
116479 + * * Redistributions of source code must retain the above copyright
116480 + * notice, this list of conditions and the following disclaimer.
116481 + * * Redistributions in binary form must reproduce the above copyright
116482 + * notice, this list of conditions and the following disclaimer in the
116483 + * documentation and/or other materials provided with the distribution.
116484 + * * Neither the name of Freescale Semiconductor nor the
116485 + * names of its contributors may be used to endorse or promote products
116486 + * derived from this software without specific prior written permission.
116487 + *
116488 + *
116489 + * ALTERNATIVELY, this software may be distributed under the terms of the
116490 + * GNU General Public License ("GPL") as published by the Free Software
116491 + * Foundation, either version 2 of that License or (at your option) any
116492 + * later version.
116493 + *
116494 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
116495 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
116496 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
116497 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
116498 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
116499 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
116500 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
116501 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
116502 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
116503 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116504 + */
116505 +
116506 +/*
116507 + @File lnxwrp_fm_compat_ioctls.c
116508 +
116509 + @Description FM PCD compat functions
116510 +
116511 +*/
116512 +
116513 +#if !defined(CONFIG_COMPAT)
116514 +#error "missing COMPAT layer..."
116515 +#endif
116516 +
116517 +
116518 +#include <linux/kernel.h>
116519 +#include <linux/module.h>
116520 +#include <linux/fs.h>
116521 +#include <linux/cdev.h>
116522 +#include <linux/device.h>
116523 +#include <linux/irq.h>
116524 +#include <linux/interrupt.h>
116525 +#include <linux/io.h>
116526 +#include <linux/ioport.h>
116527 +#include <asm/uaccess.h>
116528 +#include <asm/errno.h>
116529 +#ifndef CONFIG_FMAN_ARM
116530 +#include <sysdev/fsl_soc.h>
116531 +#endif
116532 +
116533 +#include "part_ext.h"
116534 +#include "fm_ioctls.h"
116535 +#include "fm_pcd_ioctls.h"
116536 +#include "fm_port_ioctls.h"
116537 +#include "lnxwrp_ioctls_fm_compat.h"
116538 +
116539 +#if defined(FM_COMPAT_DBG)
116540 +static void hex_dump(void * p_addr, unsigned int size)
116541 +{
116542 + int i;
116543 +
116544 + for(i=0; i<size; i+=16)
116545 + {
116546 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
116547 + *(unsigned int *)(p_addr + i),
116548 + *(unsigned int *)(p_addr + i + 4),
116549 + *(unsigned int *)(p_addr + i + 8),
116550 + *(unsigned int *)(p_addr + i +12)
116551 + );
116552 + }
116553 +}
116554 +#endif
116555 +
116556 +/* maping kernel pointers w/ UserSpace id's { */
116557 +struct map_node {
116558 + void *ptr;
116559 + u8 node_type;
116560 +};
116561 +
116562 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
116563 +
116564 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
116565 +{
116566 + compat_uptr_t k;
116567 +
116568 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
116569 +
116570 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116571 + if(compat_ptr2id_array[k].ptr == p){
116572 + compat_ptr2id_array[k].ptr = NULL;
116573 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
116574 + }
116575 +}
116576 +EXPORT_SYMBOL(compat_del_ptr2id);
116577 +
116578 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
116579 +{
116580 + compat_uptr_t k;
116581 +
116582 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
116583 +
116584 + if(!p)
116585 + return 0;
116586 +
116587 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116588 + if(compat_ptr2id_array[k].ptr == NULL)
116589 + {
116590 + compat_ptr2id_array[k].ptr = p;
116591 + compat_ptr2id_array[k].node_type = node_type;
116592 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
116593 + return k | COMPAT_PTR2ID_WATERMARK;
116594 + }
116595 +
116596 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
116597 + return 0;
116598 +}
116599 +EXPORT_SYMBOL(compat_add_ptr2id);
116600 +
116601 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
116602 +{
116603 + compat_uptr_t k;
116604 +
116605 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
116606 +
116607 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
116608 + if(compat_ptr2id_array[k].ptr == p &&
116609 + compat_ptr2id_array[k].node_type == node_type) {
116610 +
116611 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
116612 + return k | COMPAT_PTR2ID_WATERMARK;
116613 + }
116614 +
116615 + return 0;
116616 +}
116617 +EXPORT_SYMBOL(compat_get_ptr2id);
116618 +
116619 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
116620 +{
116621 +
116622 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
116623 +
116624 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
116625 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
116626 + dump_stack();
116627 + return compat_ptr(comp);
116628 + }
116629 +
116630 + comp &= ~COMPAT_PTR2ID_WM_MASK;
116631 +
116632 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
116633 + && compat_ptr2id_array[comp].node_type == node_type)) {
116634 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
116635 + return compat_ptr2id_array[comp].ptr;
116636 + }
116637 + return NULL;
116638 +}
116639 +EXPORT_SYMBOL(compat_get_id2ptr);
116640 +/* } maping kernel pointers w/ UserSpace id's */
116641 +
116642 +void compat_obj_delete(
116643 + ioc_compat_fm_obj_t *compat_id,
116644 + ioc_fm_obj_t *id)
116645 +{
116646 + id->obj = compat_pcd_id2ptr(compat_id->obj);
116647 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
116648 +}
116649 +
116650 +static inline void compat_copy_fm_pcd_plcr_next_engine(
116651 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
116652 + ioc_fm_pcd_plcr_next_engine_params_u *param,
116653 + ioc_fm_pcd_engine next_engine,
116654 + uint8_t compat)
116655 +{
116656 + _fm_cpt_dbg (compat, " {->...\n");
116657 +
116658 + switch (next_engine)
116659 + {
116660 + case e_IOC_FM_PCD_PLCR:
116661 + if (compat == COMPAT_US_TO_K)
116662 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
116663 + else
116664 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
116665 + break;
116666 + case e_IOC_FM_PCD_KG:
116667 + if (compat == COMPAT_US_TO_K)
116668 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116669 + else
116670 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116671 + break;
116672 + default:
116673 + if (compat == COMPAT_US_TO_K)
116674 + param->action = compat_param->action;
116675 + else
116676 + compat_param->action = param->action;
116677 + break;
116678 + }
116679 +
116680 + _fm_cpt_dbg (compat, " ...->}\n");
116681 +}
116682 +
116683 +void compat_copy_fm_pcd_plcr_profile(
116684 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
116685 + ioc_fm_pcd_plcr_profile_params_t *param,
116686 + uint8_t compat)
116687 +{
116688 + _fm_cpt_dbg (compat, " {->...\n");
116689 +
116690 + if (compat == COMPAT_US_TO_K)
116691 + {
116692 + param->modify = compat_param->modify;
116693 +
116694 + /* profile_select */
116695 + if (!compat_param->modify)
116696 + {
116697 + param->profile_select.new_params.profile_type =
116698 + compat_param->profile_select.new_params.profile_type;
116699 + param->profile_select.new_params.p_fm_port =
116700 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
116701 + param->profile_select.new_params.relative_profile_id =
116702 + compat_param->profile_select.new_params.relative_profile_id;
116703 + }
116704 + else
116705 + param->profile_select.p_profile =
116706 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
116707 +
116708 + param->alg_selection = compat_param->alg_selection;
116709 + param->color_mode = compat_param->color_mode;
116710 +
116711 + /* both parameters in the union has the same size, so memcpy works */
116712 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
116713 +
116714 + memcpy(&param->non_passthrough_alg_param,
116715 + &compat_param->non_passthrough_alg_param,
116716 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116717 +
116718 + param->next_engine_on_green = compat_param->next_engine_on_green;
116719 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
116720 + param->next_engine_on_red = compat_param->next_engine_on_red;
116721 +
116722 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
116723 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
116724 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
116725 + }
116726 + else
116727 + {
116728 + compat_param->modify = param->modify;
116729 +
116730 + /* profile_select */
116731 + if (!param->modify)
116732 + {
116733 + compat_param->profile_select.new_params.profile_type =
116734 + param->profile_select.new_params.profile_type;
116735 + compat_param->profile_select.new_params.p_fm_port =
116736 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
116737 + compat_param->profile_select.new_params.relative_profile_id =
116738 + param->profile_select.new_params.relative_profile_id;
116739 + }
116740 + else
116741 + compat_param->profile_select.p_profile =
116742 + compat_pcd_ptr2id(param->profile_select.p_profile);
116743 +
116744 + compat_param->alg_selection = param->alg_selection;
116745 + compat_param->color_mode = param->color_mode;
116746 +
116747 + /* both parameters in the union has the same size, so memcpy works */
116748 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
116749 +
116750 + memcpy(&compat_param->non_passthrough_alg_param,
116751 + &param->non_passthrough_alg_param,
116752 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
116753 +
116754 + compat_param->next_engine_on_green = param->next_engine_on_green;
116755 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
116756 + compat_param->next_engine_on_red = param->next_engine_on_red;
116757 +
116758 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
116759 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
116760 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
116761 +
116762 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
116763 + }
116764 +
116765 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
116766 + &param->params_on_green, param->next_engine_on_green, compat);
116767 +
116768 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
116769 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
116770 +
116771 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
116772 + &param->params_on_red, param->next_engine_on_red, compat);
116773 +
116774 + _fm_cpt_dbg (compat, " ...->}\n");
116775 +}
116776 +
116777 +static inline void compat_copy_fm_pcd_cc_next_kg(
116778 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
116779 + ioc_fm_pcd_cc_next_kg_params_t *param,
116780 + uint8_t compat)
116781 +{
116782 + _fm_cpt_dbg (compat, " {->...\n");
116783 +
116784 + if (compat == COMPAT_US_TO_K)
116785 + {
116786 + param->new_fqid = compat_param->new_fqid;
116787 + param->override_fqid = compat_param->override_fqid;
116788 +#if DPAA_VERSION >= 11
116789 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
116790 +#endif
116791 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
116792 + }
116793 + else
116794 + {
116795 + compat_param->new_fqid = param->new_fqid;
116796 + compat_param->override_fqid = param->override_fqid;
116797 +#if DPAA_VERSION >= 11
116798 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
116799 +#endif
116800 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
116801 + }
116802 +
116803 + _fm_cpt_dbg (compat, " ...->}\n");
116804 +}
116805 +
116806 +static inline void compat_copy_fm_pcd_cc_next_cc(
116807 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
116808 + ioc_fm_pcd_cc_next_cc_params_t *param,
116809 + uint8_t compat)
116810 +{
116811 + _fm_cpt_dbg (compat, " {->...\n");
116812 +
116813 + if (compat == COMPAT_US_TO_K)
116814 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
116815 + else
116816 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
116817 +
116818 + _fm_cpt_dbg (compat, " ...->}\n");
116819 +}
116820 +
116821 +static inline void compat_copy_fm_pcd_cc_next_engine(
116822 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
116823 + ioc_fm_pcd_cc_next_engine_params_t *param,
116824 + uint8_t compat)
116825 +{
116826 + _fm_cpt_dbg (compat, " {->...\n");
116827 +
116828 + if (compat == COMPAT_US_TO_K)
116829 + {
116830 + param->next_engine = compat_param->next_engine;
116831 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
116832 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
116833 +
116834 + switch (param->next_engine)
116835 + {
116836 +#if DPAA_VERSION >= 11
116837 + case e_IOC_FM_PCD_FR:
116838 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
116839 + break;
116840 +#endif /* DPAA_VERSION >= 11 */
116841 + case e_IOC_FM_PCD_CC:
116842 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116843 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116844 + break;
116845 + case e_IOC_FM_PCD_KG:
116846 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116847 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116848 + break;
116849 + case e_IOC_FM_PCD_DONE:
116850 + case e_IOC_FM_PCD_PLCR:
116851 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
116852 + default:
116853 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
116854 + }
116855 + param->statistics_en = compat_param->statistics_en;
116856 + }
116857 + else
116858 + {
116859 + compat_param->next_engine = param->next_engine;
116860 +
116861 + switch (compat_param->next_engine)
116862 + {
116863 +#if DPAA_VERSION >= 11
116864 + case e_IOC_FM_PCD_FR:
116865 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
116866 + break;
116867 +#endif /* DPAA_VERSION >= 11 */
116868 + case e_IOC_FM_PCD_CC:
116869 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116870 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
116871 + break;
116872 + case e_IOC_FM_PCD_KG:
116873 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116874 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
116875 + break;
116876 + case e_IOC_FM_PCD_DONE:
116877 + case e_IOC_FM_PCD_PLCR:
116878 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
116879 + default:
116880 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
116881 + }
116882 + compat_param->statistics_en = param->statistics_en;
116883 + }
116884 +
116885 + _fm_cpt_dbg (compat, " ...->}\n");
116886 +}
116887 +
116888 +void compat_copy_fm_pcd_cc_key(
116889 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
116890 + ioc_fm_pcd_cc_key_params_t *param,
116891 + uint8_t compat)
116892 +{
116893 + if (compat == COMPAT_US_TO_K)
116894 + {
116895 + param->p_key = compat_ptr(compat_param->p_key);
116896 + param->p_mask = compat_ptr(compat_param->p_mask);
116897 + }
116898 + else
116899 + {
116900 + compat_param->p_key = ptr_to_compat(param->p_key);
116901 + compat_param->p_mask = ptr_to_compat(param->p_mask);
116902 + }
116903 +
116904 + compat_copy_fm_pcd_cc_next_engine(
116905 + &compat_param->cc_next_engine_params,
116906 + &param->cc_next_engine_params,
116907 + compat);
116908 +}
116909 +
116910 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
116911 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
116912 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
116913 + uint8_t compat)
116914 +{
116915 + if (compat == COMPAT_US_TO_K)
116916 + {
116917 + param->id = compat_pcd_id2ptr(compat_param->id);
116918 + param->key_indx = compat_param->key_indx;
116919 + param->key_size = compat_param->key_size;
116920 + compat_copy_fm_pcd_cc_key(
116921 + &compat_param->key_params,
116922 + &param->key_params,
116923 + compat);
116924 + }
116925 + else
116926 + {
116927 + compat_param->id = compat_pcd_ptr2id(param->id);
116928 + compat_param->key_indx = param->key_indx;
116929 + compat_param->key_size = param->key_size;
116930 + compat_copy_fm_pcd_cc_key(
116931 + &compat_param->key_params,
116932 + &param->key_params,
116933 + compat);
116934 + }
116935 +}
116936 +
116937 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
116938 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
116939 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
116940 + uint8_t compat)
116941 +{
116942 + if (compat == COMPAT_US_TO_K)
116943 + {
116944 + param->id = compat_pcd_id2ptr(compat_param->id);
116945 + param->key_indx = compat_param->key_indx;
116946 + param->key_size = compat_param->key_size;
116947 + }
116948 + else
116949 + {
116950 + compat_param->id = compat_pcd_ptr2id(param->id);
116951 + compat_param->key_indx = param->key_indx;
116952 + compat_param->key_size = param->key_size;
116953 + }
116954 +
116955 + compat_copy_fm_pcd_cc_next_engine(
116956 + &compat_param->cc_next_engine_params,
116957 + &param->cc_next_engine_params,
116958 + compat);
116959 +}
116960 +
116961 +void compat_fm_pcd_cc_tree_modify_next_engine(
116962 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
116963 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
116964 + uint8_t compat)
116965 +{
116966 + if (compat == COMPAT_US_TO_K)
116967 + {
116968 + param->id = compat_pcd_id2ptr(compat_param->id);
116969 + param->grp_indx = compat_param->grp_indx;
116970 + param->indx = compat_param->indx;
116971 + }
116972 + else
116973 + {
116974 + compat_param->id = compat_pcd_ptr2id(param->id);
116975 + compat_param->grp_indx = param->grp_indx;
116976 + compat_param->indx = param->indx;
116977 + }
116978 +
116979 + compat_copy_fm_pcd_cc_next_engine(
116980 + &compat_param->cc_next_engine_params,
116981 + &param->cc_next_engine_params,
116982 + compat);
116983 +}
116984 +
116985 +void compat_copy_fm_pcd_hash_table(
116986 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
116987 + ioc_fm_pcd_hash_table_params_t *param,
116988 + uint8_t compat)
116989 +{
116990 + if (compat == COMPAT_US_TO_K)
116991 + {
116992 + param->max_num_of_keys = compat_param->max_num_of_keys;
116993 + param->statistics_mode = compat_param->statistics_mode;
116994 + param->kg_hash_shift = compat_param->kg_hash_shift;
116995 + param->hash_res_mask = compat_param->hash_res_mask;
116996 + param->hash_shift = compat_param->hash_shift;
116997 + param->match_key_size = compat_param->match_key_size;
116998 + param->id = compat_pcd_id2ptr(compat_param->id);
116999 + }
117000 + else
117001 + {
117002 + compat_param->max_num_of_keys = param->max_num_of_keys;
117003 + compat_param->statistics_mode = param->statistics_mode;
117004 + compat_param->kg_hash_shift = param->kg_hash_shift;
117005 + compat_param->hash_res_mask = param->hash_res_mask;
117006 + compat_param->hash_shift = param->hash_shift;
117007 + compat_param->match_key_size = param->match_key_size;
117008 +
117009 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117010 + }
117011 +
117012 + compat_copy_fm_pcd_cc_next_engine(
117013 + &compat_param->cc_next_engine_params_for_miss,
117014 + &param->cc_next_engine_params_for_miss,
117015 + compat);
117016 +}
117017 +
117018 +void compat_copy_fm_pcd_cc_grp(
117019 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
117020 + ioc_fm_pcd_cc_grp_params_t *param,
117021 + uint8_t compat)
117022 +{
117023 + int k;
117024 +
117025 + _fm_cpt_dbg (compat, " {->...\n");
117026 +
117027 + if (compat == COMPAT_US_TO_K)
117028 + {
117029 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117030 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117031 + }
117032 + else
117033 + {
117034 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117035 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
117036 + }
117037 +
117038 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
117039 + compat_copy_fm_pcd_cc_next_engine(
117040 + &compat_param->next_engine_per_entries_in_grp[k],
117041 + &param->next_engine_per_entries_in_grp[k],
117042 + compat);
117043 +
117044 + _fm_cpt_dbg (compat, " ...->}\n");
117045 +}
117046 +
117047 +void compat_copy_fm_pcd_cc_tree(
117048 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
117049 + ioc_fm_pcd_cc_tree_params_t *param,
117050 + uint8_t compat)
117051 +{
117052 + int k;
117053 + _fm_cpt_dbg (compat, " {->...\n");
117054 +
117055 + if (compat == COMPAT_US_TO_K)
117056 + {
117057 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117058 + param->num_of_groups = compat_param->num_of_groups;
117059 + }
117060 + else
117061 + {
117062 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
117063 + compat_param->num_of_groups = param->num_of_groups;
117064 +
117065 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117066 + }
117067 +
117068 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
117069 + compat_copy_fm_pcd_cc_grp(
117070 + &compat_param->fm_pcd_cc_group_params[k],
117071 + &param->fm_pcd_cc_group_params[k],
117072 + compat);
117073 +
117074 + _fm_cpt_dbg (compat, " ...->}\n");
117075 +}
117076 +
117077 +void compat_fm_pcd_prs_sw(
117078 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
117079 + ioc_fm_pcd_prs_sw_params_t *param,
117080 + uint8_t compat)
117081 +{
117082 + if (compat == COMPAT_US_TO_K)
117083 + {
117084 + param->override = compat_param->override;
117085 + param->size = compat_param->size;
117086 + param->base = compat_param->base;
117087 + param->p_code = compat_ptr(compat_param->p_code);
117088 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
117089 + param->num_of_labels = compat_param->num_of_labels;
117090 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
117091 + }
117092 +}
117093 +
117094 +void compat_copy_fm_pcd_kg_scheme(
117095 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
117096 + ioc_fm_pcd_kg_scheme_params_t *param,
117097 + uint8_t compat)
117098 +{
117099 + _fm_cpt_dbg(compat," {->...\n");
117100 +
117101 + if (compat == COMPAT_US_TO_K)
117102 + {
117103 + param->modify = compat_param->modify;
117104 +
117105 + /* scm_id */
117106 + if (compat_param->modify)
117107 + {
117108 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
117109 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
117110 + }
117111 + else
117112 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
117113 +
117114 + param->always_direct = compat_param->always_direct;
117115 + /* net_env_params */
117116 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
117117 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
117118 + memcpy(param->net_env_params.unit_ids,
117119 + compat_param->net_env_params.unit_ids,
117120 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117121 +
117122 + param->use_hash = compat_param->use_hash;
117123 + memcpy(&param->key_extract_and_hash_params,
117124 + &compat_param->key_extract_and_hash_params,
117125 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
117126 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
117127 + param->base_fqid = compat_param->base_fqid;
117128 +#if DPAA_VERSION >= 11
117129 + param->override_storage_profile =
117130 + compat_param->override_storage_profile;
117131 + param->storage_profile = compat_param->storage_profile;
117132 +#endif
117133 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
117134 + memcpy(param->extracted_ors,
117135 + compat_param->extracted_ors,
117136 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
117137 + param->next_engine = compat_param->next_engine;
117138 +
117139 + /* kg_next_engine_params */
117140 + if (param->next_engine == e_IOC_FM_PCD_CC)
117141 + {
117142 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
117143 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
117144 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
117145 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117146 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117147 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
117148 + &compat_param->kg_next_engine_params.cc.plcr_profile,
117149 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117150 + }
117151 + else
117152 + memcpy(&param->kg_next_engine_params,
117153 + &compat_param->kg_next_engine_params,
117154 + sizeof(param->kg_next_engine_params));
117155 +
117156 + memcpy(&param->scheme_counter,
117157 + &compat_param->scheme_counter,
117158 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117159 + }
117160 + else
117161 + {
117162 + compat_param->modify = param->modify;
117163 +
117164 + /* scm_id */
117165 + if (param->modify)
117166 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
117167 + else
117168 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
117169 +
117170 + compat_param->always_direct = param->always_direct;
117171 +
117172 + /* net_env_params */
117173 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
117174 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
117175 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117176 +
117177 + compat_param->use_hash = param->use_hash;
117178 + memcpy(&compat_param->key_extract_and_hash_params, &param->key_extract_and_hash_params, sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
117179 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
117180 + compat_param->base_fqid = param->base_fqid;
117181 +#if DPAA_VERSION >= 11
117182 + compat_param->override_storage_profile =
117183 + param->override_storage_profile;
117184 + compat_param->storage_profile = param->storage_profile;
117185 +#endif
117186 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
117187 + memcpy(compat_param->extracted_ors, param->extracted_ors, IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
117188 + compat_param->next_engine = param->next_engine;
117189 +
117190 + /* kg_next_engine_params */
117191 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
117192 + {
117193 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
117194 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
117195 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
117196 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
117197 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
117198 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
117199 + &param->kg_next_engine_params.cc.plcr_profile,
117200 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
117201 + }
117202 + else
117203 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
117204 +
117205 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
117206 +
117207 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117208 + }
117209 +
117210 + _fm_cpt_dbg(compat," ...->}\n");
117211 +}
117212 +
117213 +void compat_copy_fm_pcd_kg_scheme_spc(
117214 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
117215 + ioc_fm_pcd_kg_scheme_spc_t *param,
117216 + uint8_t compat)
117217 +{
117218 + if (compat == COMPAT_US_TO_K)
117219 + {
117220 + param->id = compat_pcd_id2ptr(compat_param->id);
117221 + param->val = compat_param->val;
117222 + } else {
117223 + compat_param->id = compat_pcd_ptr2id(param->id);
117224 + compat_param->val = param->val;
117225 + }
117226 +}
117227 +
117228 +
117229 +void compat_copy_fm_pcd_kg_scheme_select(
117230 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
117231 + ioc_fm_pcd_kg_scheme_select_t *param,
117232 + uint8_t compat)
117233 +{
117234 + if (compat == COMPAT_US_TO_K)
117235 + {
117236 + param->direct = compat_param->direct;
117237 + if (param->direct)
117238 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
117239 + }
117240 +}
117241 +
117242 +void compat_copy_fm_pcd_kg_schemes_params(
117243 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
117244 + ioc_fm_pcd_port_schemes_params_t *param,
117245 + uint8_t compat)
117246 +{
117247 + int k;
117248 +
117249 + if (compat == COMPAT_US_TO_K) {
117250 + param->num_of_schemes = compat_param->num_of_schemes;
117251 + for(k=0; k < compat_param->num_of_schemes; k++)
117252 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117253 + }
117254 +}
117255 +
117256 +void compat_copy_fm_port_pcd_cc(
117257 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
117258 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
117259 + uint8_t compat)
117260 +{
117261 + if (compat == COMPAT_US_TO_K){
117262 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
117263 + }
117264 +}
117265 +
117266 +void compat_copy_fm_port_pcd_kg(
117267 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
117268 + ioc_fm_port_pcd_kg_params_t *param,
117269 + uint8_t compat)
117270 +{
117271 + if (compat == COMPAT_US_TO_K){
117272 + uint8_t k;
117273 +
117274 + param->num_of_schemes = compat_param->num_of_schemes;
117275 + for(k=0; k<compat_param->num_of_schemes; k++)
117276 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
117277 +
117278 + param->direct_scheme = compat_param->direct_scheme;
117279 + if (param->direct_scheme)
117280 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
117281 + }
117282 +}
117283 +
117284 +void compat_copy_fm_port_pcd(
117285 + ioc_compat_fm_port_pcd_params_t *compat_param,
117286 + ioc_fm_port_pcd_params_t *param,
117287 + uint8_t compat)
117288 +{
117289 + if (compat == COMPAT_US_TO_K)
117290 + {
117291 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117292 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117293 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117294 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117295 +
117296 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
117297 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117298 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117299 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117300 +
117301 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
117302 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
117303 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
117304 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
117305 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
117306 +#if (DPAA_VERSION >= 11)
117307 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
117308 +#endif
117309 + param->pcd_support = compat_param->pcd_support;
117310 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
117311 +
117312 + if (param->p_cc_params)
117313 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
117314 + if (param->p_kg_params)
117315 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
117316 + if (param->p_plcr_params)
117317 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
117318 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
117319 +#if (DPAA_VERSION >= 11)
117320 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
117321 +#endif
117322 + }
117323 +}
117324 +
117325 +void compat_copy_fm_port_pcd_modify_tree(
117326 + ioc_compat_fm_obj_t *compat_id,
117327 + ioc_fm_obj_t *id,
117328 + uint8_t compat)
117329 +{
117330 + if (compat == COMPAT_US_TO_K)
117331 + id->obj = compat_pcd_id2ptr(compat_id->obj);
117332 +}
117333 +
117334 +#if (DPAA_VERSION >= 11)
117335 +void compat_copy_fm_port_vsp_alloc_params(
117336 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
117337 + ioc_fm_port_vsp_alloc_params_t *param,
117338 + uint8_t compat)
117339 +{
117340 + if (compat == COMPAT_US_TO_K)
117341 + {
117342 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
117343 +
117344 + param->dflt_relative_id = compat_param->dflt_relative_id;
117345 + param->num_of_profiles = compat_param->num_of_profiles;
117346 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
117347 + }
117348 +}
117349 +#endif /* (DPAA_VERSION >= 11) */
117350 +
117351 +void compat_copy_fm_pcd_cc_tbl_get_stats(
117352 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
117353 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
117354 + uint8_t compat)
117355 +{
117356 + if (compat == COMPAT_US_TO_K)
117357 + {
117358 + param->id = compat_pcd_id2ptr(compat_param->id);
117359 + param->key_index = compat_param->key_index;
117360 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117361 + } else {
117362 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117363 + compat_param->key_index = param->key_index;
117364 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
117365 + }
117366 +}
117367 +
117368 +
117369 +void compat_copy_fm_pcd_net_env(
117370 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
117371 + ioc_fm_pcd_net_env_params_t *param,
117372 + uint8_t compat)
117373 +{
117374 + if (compat == COMPAT_US_TO_K)
117375 + {
117376 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
117377 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117378 + param->id = NULL; /* to avoid passing garbage to the kernel */
117379 + }
117380 + else
117381 + {
117382 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
117383 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
117384 +
117385 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117386 + }
117387 +}
117388 +
117389 +void compat_copy_fm_pcd_cc_node_modify_key(
117390 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
117391 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
117392 + uint8_t compat)
117393 +{
117394 + if (compat == COMPAT_US_TO_K)
117395 + {
117396 + param->key_indx = compat_param->key_indx;
117397 + param->key_size = compat_param->key_size;
117398 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
117399 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
117400 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
117401 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
117402 + param->id = compat_pcd_id2ptr(compat_param->id);
117403 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117404 + }
117405 + else
117406 + {
117407 + compat_param->key_indx = param->key_indx;
117408 + compat_param->key_size = param->key_size;
117409 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
117410 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
117411 +
117412 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117413 + }
117414 +}
117415 +
117416 +void compat_copy_keys(
117417 + ioc_compat_keys_params_t *compat_param,
117418 + ioc_keys_params_t *param,
117419 + uint8_t compat)
117420 +{
117421 + int k = 0;
117422 +
117423 + _fm_cpt_dbg(compat," {->...\n");
117424 +
117425 + if (compat == COMPAT_US_TO_K) {
117426 + param->max_num_of_keys = compat_param->max_num_of_keys;
117427 + param->mask_support = compat_param->mask_support;
117428 + param->statistics_mode = compat_param->statistics_mode;
117429 + param->num_of_keys = compat_param->num_of_keys;
117430 + param->key_size = compat_param->key_size;
117431 +#if (DPAA_VERSION >= 11)
117432 + memcpy(&param->frame_length_ranges,
117433 + &compat_param->frame_length_ranges,
117434 + sizeof(param->frame_length_ranges[0]) *
117435 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117436 +#endif /* (DPAA_VERSION >= 11) */
117437 + }
117438 + else {
117439 + compat_param->max_num_of_keys = param->max_num_of_keys;
117440 + compat_param->mask_support = param->mask_support;
117441 + compat_param->statistics_mode = param->statistics_mode;
117442 + compat_param->num_of_keys = param->num_of_keys;
117443 + compat_param->key_size = param->key_size;
117444 +#if (DPAA_VERSION >= 11)
117445 + memcpy(&compat_param->frame_length_ranges,
117446 + &param->frame_length_ranges,
117447 + sizeof(compat_param->frame_length_ranges[0]) *
117448 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
117449 +#endif /* (DPAA_VERSION >= 11) */
117450 + }
117451 +
117452 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
117453 + compat_copy_fm_pcd_cc_key(
117454 + &compat_param->key_params[k],
117455 + &param->key_params[k],
117456 + compat);
117457 +
117458 + compat_copy_fm_pcd_cc_next_engine(
117459 + &compat_param->cc_next_engine_params_for_miss,
117460 + &param->cc_next_engine_params_for_miss,
117461 + compat);
117462 +
117463 + _fm_cpt_dbg(compat," ...->}\n");
117464 +}
117465 +
117466 +void compat_copy_fm_pcd_cc_node(
117467 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
117468 + ioc_fm_pcd_cc_node_params_t *param,
117469 + uint8_t compat)
117470 +{
117471 + _fm_cpt_dbg(compat," {->...\n");
117472 +
117473 + if (compat == COMPAT_US_TO_K)
117474 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
117475 +
117476 + else
117477 + {
117478 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117479 +
117480 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117481 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
117482 + }
117483 +
117484 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
117485 +
117486 + _fm_cpt_dbg(compat," ...->}\n");
117487 +}
117488 +
117489 +void compat_fm_pcd_manip_set_node(
117490 + ioc_compat_fm_pcd_manip_params_t *compat_param,
117491 + ioc_fm_pcd_manip_params_t *param,
117492 + uint8_t compat)
117493 +{
117494 + if (compat == COMPAT_US_TO_K) {
117495 + param->type = compat_param->type;
117496 + switch (param->type) {
117497 + case e_IOC_FM_PCD_MANIP_HDR:
117498 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
117499 + memcpy(&param->u.hdr.rmv_params,
117500 + &compat_param->u.hdr.rmv_params,
117501 + sizeof(param->u.hdr.rmv_params));
117502 +
117503 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
117504 + param->u.hdr.insrt_params.type =
117505 + compat_param->u.hdr.insrt_params.type;
117506 + switch (compat_param->u.hdr.insrt_params.type)
117507 + {
117508 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
117509 + param->u.hdr.insrt_params.u.generic.offset =
117510 + compat_param->u.hdr.insrt_params.u.generic.offset;
117511 + param->u.hdr.insrt_params.u.generic.size =
117512 + compat_param->u.hdr.insrt_params.u.generic.size;
117513 + param->u.hdr.insrt_params.u.generic.replace =
117514 + compat_param->u.hdr.insrt_params.u.generic.replace;
117515 + param->u.hdr.insrt_params.u.generic.p_data =
117516 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
117517 + break;
117518 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
117519 + param->u.hdr.insrt_params.u.by_hdr.type =
117520 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
117521 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
117522 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
117523 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
117524 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
117525 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
117526 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
117527 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
117528 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
117529 + break;
117530 + default:
117531 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
117532 + }
117533 +
117534 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
117535 + memcpy(&param->u.hdr.field_update_params,
117536 + &compat_param->u.hdr.field_update_params,
117537 + sizeof(param->u.hdr.field_update_params));
117538 +
117539 + param->u.hdr.custom = compat_param->u.hdr.custom;
117540 + memcpy(&param->u.hdr.custom_params,
117541 + &compat_param->u.hdr.custom_params,
117542 + sizeof(param->u.hdr.custom_params));
117543 +
117544 + param->u.hdr.dont_parse_after_manip =
117545 + compat_param->u.hdr.dont_parse_after_manip;
117546 + break;
117547 + case e_IOC_FM_PCD_MANIP_REASSEM:
117548 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
117549 + break;
117550 + case e_IOC_FM_PCD_MANIP_FRAG:
117551 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
117552 + break;
117553 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
117554 + memcpy(&param->u.special_offload,
117555 + &compat_param->u.special_offload,
117556 + sizeof(param->u.special_offload));
117557 + break;
117558 + }
117559 +
117560 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
117561 + param->id = compat_pcd_id2ptr(compat_param->id);
117562 + }
117563 + else {
117564 + compat_param->type = param->type;
117565 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
117566 +
117567 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
117568 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
117569 + compat_param->u.hdr.insrt_params.u.generic.p_data =
117570 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
117571 +
117572 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
117573 + /* ... should be one that was added previously by the very call to
117574 + compat_add_ptr2id() below: */
117575 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117576 + }
117577 +}
117578 +
117579 +void compat_copy_fm_pcd_manip_get_stats(
117580 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
117581 + ioc_fm_pcd_manip_get_stats_t *param,
117582 + uint8_t compat)
117583 +{
117584 + _fm_cpt_dbg (compat, " {->...\n");
117585 +
117586 + if (compat == COMPAT_US_TO_K)
117587 + {
117588 + param->id = compat_pcd_id2ptr(compat_param->id);
117589 + memcpy(&param->stats, &compat_param->stats,
117590 + sizeof(ioc_fm_pcd_manip_stats_t));
117591 + }
117592 + else
117593 + {
117594 + compat_param->id = compat_add_ptr2id(param->id,
117595 + FM_MAP_TYPE_PCD_NODE);
117596 + memcpy(&compat_param->stats, &param->stats,
117597 + sizeof(ioc_fm_pcd_manip_stats_t));
117598 + }
117599 +
117600 + _fm_cpt_dbg (compat, " ...->}\n");
117601 +}
117602 +
117603 +#if (DPAA_VERSION >= 11)
117604 +void compat_copy_fm_pcd_frm_replic_group_params(
117605 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
117606 + ioc_fm_pcd_frm_replic_group_params_t *param,
117607 + uint8_t compat)
117608 +{
117609 + int k;
117610 +
117611 + _fm_cpt_dbg (compat, " {->...\n");
117612 +
117613 + if (compat == COMPAT_US_TO_K)
117614 + {
117615 + param->max_num_of_entries = compat_param->max_num_of_entries;
117616 + param->num_of_entries = compat_param->num_of_entries;
117617 + param->id = compat_pcd_id2ptr(compat_param->id);
117618 + }
117619 + else
117620 + {
117621 + compat_param->max_num_of_entries = param->max_num_of_entries;
117622 + compat_param->num_of_entries = param->num_of_entries;
117623 + compat_param->id = compat_add_ptr2id(param->id,
117624 + FM_MAP_TYPE_PCD_NODE);
117625 + }
117626 +
117627 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
117628 + compat_copy_fm_pcd_cc_next_engine(
117629 + &compat_param->next_engine_params[k],
117630 + &param->next_engine_params[k],
117631 + compat);
117632 +
117633 + _fm_cpt_dbg (compat, " ...->}\n");
117634 +}
117635 +
117636 +void compat_copy_fm_pcd_frm_replic_member(
117637 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
117638 + ioc_fm_pcd_frm_replic_member_t *param,
117639 + uint8_t compat)
117640 +{
117641 + _fm_cpt_dbg (compat, " {->...\n");
117642 +
117643 + if (compat == COMPAT_US_TO_K)
117644 + {
117645 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
117646 + param->member_index = compat_param->member_index;
117647 + }
117648 +
117649 + _fm_cpt_dbg (compat, " ...->}\n");
117650 +}
117651 +
117652 +void compat_copy_fm_pcd_frm_replic_member_params(
117653 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
117654 + ioc_fm_pcd_frm_replic_member_params_t *param,
117655 + uint8_t compat)
117656 +{
117657 + _fm_cpt_dbg (compat, " {->...\n");
117658 +
117659 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
117660 + &param->member, compat);
117661 +
117662 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
117663 + &param->next_engine_params, compat);
117664 +
117665 + _fm_cpt_dbg (compat, " ...->}\n");
117666 +}
117667 +
117668 +void compat_copy_fm_vsp_params(
117669 + ioc_compat_fm_vsp_params_t *compat_param,
117670 + ioc_fm_vsp_params_t *param,
117671 + uint8_t compat)
117672 +{
117673 + _fm_cpt_dbg (compat, " {->...\n");
117674 +
117675 + if (compat == COMPAT_US_TO_K)
117676 + {
117677 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117678 + param->liodn_offset = compat_param->liodn_offset;
117679 + param->port_params.port_id = compat_param->port_params.port_id;
117680 + param->port_params.port_type = compat_param->port_params.port_type;
117681 + param->relative_profile_id = compat_param->relative_profile_id;
117682 + }
117683 + else
117684 + {
117685 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
117686 + compat_param->liodn_offset = param->liodn_offset;
117687 + compat_param->port_params.port_id = param->port_params.port_id;
117688 + compat_param->port_params.port_type = param->port_params.port_type;
117689 + compat_param->relative_profile_id = param->relative_profile_id;
117690 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
117691 + }
117692 +
117693 + _fm_cpt_dbg (compat, " ...->}\n");
117694 +}
117695 +
117696 +void compat_copy_fm_buf_pool_depletion_params(
117697 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
117698 + ioc_fm_buf_pool_depletion_params_t *param,
117699 + uint8_t compat)
117700 +{
117701 + _fm_cpt_dbg (compat, " {->...\n");
117702 +
117703 + if (compat == COMPAT_US_TO_K)
117704 + {
117705 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117706 + memcpy(&param->fm_buf_pool_depletion,
117707 + &compat_param->fm_buf_pool_depletion,
117708 + sizeof(ioc_fm_buf_pool_depletion_t));
117709 + }
117710 +
117711 + _fm_cpt_dbg (compat, " ...->}\n");
117712 +}
117713 +
117714 +void compat_copy_fm_buffer_prefix_content_params(
117715 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
117716 + ioc_fm_buffer_prefix_content_params_t *param,
117717 + uint8_t compat)
117718 +{
117719 + _fm_cpt_dbg (compat, " {->...\n");
117720 +
117721 + if (compat == COMPAT_US_TO_K)
117722 + {
117723 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117724 + memcpy(&param->fm_buffer_prefix_content,
117725 + &compat_param->fm_buffer_prefix_content,
117726 + sizeof(ioc_fm_buffer_prefix_content_t));
117727 + }
117728 +
117729 + _fm_cpt_dbg (compat, " ...->}\n");
117730 +}
117731 +
117732 +void compat_copy_fm_vsp_config_no_sg_params(
117733 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
117734 + ioc_fm_vsp_config_no_sg_params_t *param,
117735 + uint8_t compat)
117736 +{
117737 + _fm_cpt_dbg (compat, " {->...\n");
117738 +
117739 + if (compat == COMPAT_US_TO_K)
117740 + {
117741 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117742 + param->no_sg = compat_param->no_sg;
117743 + }
117744 +
117745 + _fm_cpt_dbg (compat, " ...->}\n");
117746 +}
117747 +
117748 +void compat_copy_fm_vsp_prs_result_params(
117749 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
117750 + ioc_fm_vsp_prs_result_params_t *param,
117751 + uint8_t compat)
117752 +{
117753 + _fm_cpt_dbg (compat, " {->...\n");
117754 +
117755 + if (compat == COMPAT_US_TO_K)
117756 + {
117757 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
117758 + /* p_data is an user-space pointer that needs to remain unmodified */
117759 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
117760 + }
117761 + else
117762 + {
117763 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
117764 + /* p_data is an user-space pointer that needs to remain unmodified */
117765 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
117766 + }
117767 +
117768 + _fm_cpt_dbg (compat, " ...->}\n");
117769 +}
117770 +#endif /* (DPAA_VERSION >= 11) */
117771 --- /dev/null
117772 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
117773 @@ -0,0 +1,755 @@
117774 +/*
117775 + * Copyright 2008-2012 Freescale Semiconductor Inc.
117776 + *
117777 + * Redistribution and use in source and binary forms, with or without
117778 + * modification, are permitted provided that the following conditions are met:
117779 + * * Redistributions of source code must retain the above copyright
117780 + * notice, this list of conditions and the following disclaimer.
117781 + * * Redistributions in binary form must reproduce the above copyright
117782 + * notice, this list of conditions and the following disclaimer in the
117783 + * documentation and/or other materials provided with the distribution.
117784 + * * Neither the name of Freescale Semiconductor nor the
117785 + * names of its contributors may be used to endorse or promote products
117786 + * derived from this software without specific prior written permission.
117787 + *
117788 + *
117789 + * ALTERNATIVELY, this software may be distributed under the terms of the
117790 + * GNU General Public License ("GPL") as published by the Free Software
117791 + * Foundation, either version 2 of that License or (at your option) any
117792 + * later version.
117793 + *
117794 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
117795 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
117796 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117797 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
117798 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
117799 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
117800 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
117801 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
117802 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
117803 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
117804 + */
117805 +
117806 +/*
117807 + @File lnxwrp_ioctls_fm_compat.h
117808 +
117809 + @Description FM PCD compat structures definition.
117810 +
117811 +*/
117812 +
117813 +#ifndef __FM_COMPAT_IOCTLS_H
117814 +#define __FM_COMPAT_IOCTLS_H
117815 +
117816 +#include <linux/compat.h>
117817 +
117818 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
117819 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
117820 +#define COMPAT_GENERIC 2
117821 +
117822 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
117823 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
117824 +
117825 +/* mapping kernel pointers w/ UserSpace id's { */
117826 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
117827 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
117828 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
117829 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
117830 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
117831 +
117832 +/* define it for debug trace */
117833 +/*#define FM_COMPAT_DBG*/
117834 +
117835 +#define _fm_cpt_prk(stage, format, arg...) \
117836 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
117837 +
117838 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
117839 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
117840 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
117841 +
117842 +/* used for compat IOCTL debugging */
117843 +#if defined(FM_COMPAT_DBG)
117844 + #define _fm_cpt_dbg(from, format, arg...) \
117845 + do{ \
117846 + if (from == COMPAT_US_TO_K) \
117847 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
117848 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117849 + else if (from == COMPAT_K_TO_US) \
117850 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
117851 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117852 + else \
117853 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
117854 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
117855 + }while(0)
117856 +#else
117857 +# define _fm_cpt_dbg(arg...)
117858 +#endif
117859 +
117860 +/*TODO: per FMan module:
117861 + *
117862 + * Parser: FM_MAP_TYPE_PARSER_NODE,
117863 + * Kg: FM_MAP_TYPE_KG_NODE,
117864 + * Policer: FM_MAP_TYPE_POLICER_NODE
117865 + * Manip: FM_MAP_TYPE_MANIP_NODE
117866 + **/
117867 +enum fm_map_node_type {
117868 + FM_MAP_TYPE_UNSPEC = 0,
117869 + FM_MAP_TYPE_PCD_NODE,
117870 +
117871 + /* add types here, update the policy */
117872 +
117873 + __FM_MAP_TYPE_AFTER_LAST,
117874 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
117875 +};
117876 +
117877 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
117878 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
117879 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
117880 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
117881 +
117882 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
117883 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
117884 + : (compat_uptr_t) 0;
117885 +}
117886 +
117887 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
117888 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
117889 + : NULL;
117890 +}
117891 +
117892 +/* other similar inlines may be added as new nodes are added
117893 + to enum fm_map_node_type above... */
117894 +/* } mapping kernel pointers w/ UserSpace id's */
117895 +
117896 +/* pcd compat structures { */
117897 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
117898 + compat_uptr_t id;
117899 + uint16_t key_indx;
117900 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
117901 +
117902 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
117903 + ioc_fm_pcd_done_action action;
117904 + compat_uptr_t p_profile;
117905 + compat_uptr_t p_direct_scheme;
117906 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
117907 +
117908 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
117909 + bool modify;
117910 + union {
117911 + struct {
117912 + ioc_fm_pcd_profile_type_selection profile_type;
117913 + compat_uptr_t p_fm_port;
117914 + uint16_t relative_profile_id;
117915 + } new_params;
117916 + compat_uptr_t p_profile;
117917 + } profile_select;
117918 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
117919 + ioc_fm_pcd_plcr_color_mode color_mode;
117920 +
117921 + union {
117922 + ioc_fm_pcd_plcr_color dflt_color;
117923 + ioc_fm_pcd_plcr_color override;
117924 + } color;
117925 +
117926 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
117927 +
117928 + ioc_fm_pcd_engine next_engine_on_green;
117929 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
117930 +
117931 + ioc_fm_pcd_engine next_engine_on_yellow;
117932 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
117933 +
117934 + ioc_fm_pcd_engine next_engine_on_red;
117935 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
117936 +
117937 + bool trap_profile_on_flow_A;
117938 + bool trap_profile_on_flow_B;
117939 + bool trap_profile_on_flow_C;
117940 + compat_uptr_t id;
117941 +} ioc_compat_fm_pcd_plcr_profile_params_t;
117942 +
117943 +typedef struct ioc_compat_fm_obj_t {
117944 + compat_uptr_t obj;
117945 +} ioc_compat_fm_obj_t;
117946 +
117947 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
117948 + bool direct;
117949 + compat_uptr_t scheme_id;
117950 +} ioc_compat_fm_pcd_kg_scheme_select_t;
117951 +
117952 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
117953 + uint8_t num_of_schemes;
117954 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
117955 +} ioc_compat_fm_pcd_port_schemes_params_t;
117956 +
117957 +#if (DPAA_VERSION >= 11)
117958 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
117959 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
117960 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
117961 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
117962 + if relevant function called for Rx port */
117963 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
117964 +}ioc_compat_fm_port_vsp_alloc_params_t;
117965 +#endif /* (DPAA_VERSION >= 11) */
117966 +
117967 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
117968 + uint8_t num_of_distinction_units;
117969 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
117970 + compat_uptr_t id;
117971 +} ioc_compat_fm_pcd_net_env_params_t;
117972 +
117973 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
117974 + bool override;
117975 + uint32_t size;
117976 + uint16_t base;
117977 + compat_uptr_t p_code;
117978 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
117979 + uint8_t num_of_labels;
117980 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
117981 +} ioc_compat_fm_pcd_prs_sw_params_t;
117982 +
117983 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
117984 + bool override_fqid;
117985 + uint32_t new_fqid;
117986 +#if DPAA_VERSION >= 11
117987 + uint8_t new_relative_storage_profile_id;
117988 +#endif
117989 + compat_uptr_t p_direct_scheme;
117990 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
117991 +
117992 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
117993 + compat_uptr_t cc_node_id;
117994 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
117995 +
117996 +#if DPAA_VERSION >= 11
117997 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
117998 + compat_uptr_t frm_replic_id;
117999 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
118000 +#endif /* DPAA_VERSION >= 11 */
118001 +
118002 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
118003 + ioc_fm_pcd_engine next_engine;
118004 + union {
118005 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
118006 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
118007 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
118008 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
118009 +#if DPAA_VERSION >= 11
118010 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
118011 +#endif /* DPAA_VERSION >= 11 */
118012 + } params;
118013 + compat_uptr_t manip_id;
118014 + bool statistics_en;
118015 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
118016 +
118017 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
118018 + uint8_t num_of_distinction_units;
118019 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
118020 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
118021 +} ioc_compat_fm_pcd_cc_grp_params_t;
118022 +
118023 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
118024 + compat_uptr_t net_env_id;
118025 + uint8_t num_of_groups;
118026 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
118027 + compat_uptr_t id;
118028 +} ioc_compat_fm_pcd_cc_tree_params_t;
118029 +
118030 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
118031 + compat_uptr_t id;
118032 + uint8_t grp_indx;
118033 + uint8_t indx;
118034 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118035 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
118036 +
118037 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
118038 + compat_uptr_t p_key;
118039 + compat_uptr_t p_mask;
118040 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
118041 +} ioc_compat_fm_pcd_cc_key_params_t;
118042 +
118043 +typedef struct ioc_compat_keys_params_t {
118044 + uint16_t max_num_of_keys;
118045 + bool mask_support;
118046 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118047 +#if (DPAA_VERSION >= 11)
118048 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
118049 +#endif /* (DPAA_VERSION >= 11) */
118050 + uint16_t num_of_keys;
118051 + uint8_t key_size;
118052 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
118053 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
118054 +} ioc_compat_keys_params_t;
118055 +
118056 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
118057 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
118058 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
118059 + compat_uptr_t id;
118060 +} ioc_compat_fm_pcd_cc_node_params_t;
118061 +
118062 +/**************************************************************************//**
118063 + @Description Parameters for defining a hash table
118064 +*//***************************************************************************/
118065 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
118066 + uint16_t max_num_of_keys;
118067 + ioc_fm_pcd_cc_stats_mode statistics_mode;
118068 + uint8_t kg_hash_shift;
118069 + uint16_t hash_res_mask;
118070 + uint8_t hash_shift;
118071 + uint8_t match_key_size;
118072 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
118073 + compat_uptr_t id;
118074 +} ioc_compat_fm_pcd_hash_table_params_t;
118075 +
118076 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
118077 + compat_uptr_t p_hash_tbl;
118078 + uint8_t key_size;
118079 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118080 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
118081 +
118082 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
118083 + compat_uptr_t id;
118084 + uint16_t key_indx;
118085 + uint8_t key_size;
118086 + compat_uptr_t p_key;
118087 + compat_uptr_t p_mask;
118088 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
118089 +
118090 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
118091 + compat_uptr_t p_hash_tbl;
118092 + uint8_t key_size;
118093 + compat_uptr_t p_key;
118094 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
118095 +
118096 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
118097 + compat_uptr_t id;
118098 + uint16_t key_indx;
118099 + uint8_t key_size;
118100 + ioc_compat_fm_pcd_cc_key_params_t key_params;
118101 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
118102 +
118103 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
118104 + compat_uptr_t plcr_profile_id;
118105 +} ioc_compat_fm_port_pcd_plcr_params_t;
118106 +
118107 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
118108 + compat_uptr_t cc_tree_id;
118109 +} ioc_compat_fm_port_pcd_cc_params_t;
118110 +
118111 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
118112 + uint8_t num_of_schemes;
118113 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
118114 + bool direct_scheme;
118115 + compat_uptr_t direct_scheme_id;
118116 +} ioc_compat_fm_port_pcd_kg_params_t;
118117 +
118118 +typedef struct ioc_compat_fm_port_pcd_params_t {
118119 + ioc_fm_port_pcd_support pcd_support;
118120 + compat_uptr_t net_env_id;
118121 + compat_uptr_t p_prs_params;
118122 + compat_uptr_t p_cc_params;
118123 + compat_uptr_t p_kg_params;
118124 + compat_uptr_t p_plcr_params;
118125 + compat_uptr_t p_ip_reassembly_manip;
118126 +#if DPAA_VERSION >= 11
118127 + compat_uptr_t p_capwap_reassembly_manip;
118128 +#endif
118129 +} ioc_compat_fm_port_pcd_params_t;
118130 +
118131 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
118132 + compat_uptr_t tree_id;
118133 + uint8_t grp_id;
118134 + bool plcr_next;
118135 + bool bypass_plcr_profile_generation;
118136 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118137 +} ioc_compat_fm_pcd_kg_cc_t;
118138 +
118139 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
118140 + bool modify;
118141 + union {
118142 + uint8_t relative_scheme_id;
118143 + compat_uptr_t scheme_id;
118144 + } scm_id;
118145 + bool always_direct;
118146 + struct {
118147 + compat_uptr_t net_env_id;
118148 + uint8_t num_of_distinction_units;
118149 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
118150 + } net_env_params;
118151 + bool use_hash;
118152 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
118153 + bool bypass_fqid_generation;
118154 + uint32_t base_fqid;
118155 + uint8_t num_of_used_extracted_ors;
118156 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
118157 +#if DPAA_VERSION >= 11
118158 + bool override_storage_profile;
118159 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
118160 +#endif /* DPAA_VERSION >= 11 */
118161 + ioc_fm_pcd_engine next_engine;
118162 + union{
118163 + ioc_fm_pcd_done_action done_action;
118164 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
118165 + ioc_compat_fm_pcd_kg_cc_t cc;
118166 + } kg_next_engine_params;
118167 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
118168 + compat_uptr_t id;
118169 +} ioc_compat_fm_pcd_kg_scheme_params_t;
118170 +
118171 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
118172 + compat_uptr_t id;
118173 + uint16_t key_indx;
118174 + uint8_t key_size;
118175 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
118176 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
118177 +
118178 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
118179 + uint8_t offset;
118180 + uint8_t size;
118181 + bool replace;
118182 + compat_uptr_t p_data;
118183 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
118184 +
118185 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
118186 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
118187 + bool update;
118188 + uint8_t size;
118189 + compat_uptr_t p_data;
118190 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
118191 +
118192 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
118193 + uint8_t size; /**< size of inserted section */
118194 + compat_uptr_t p_data; /**< data to be inserted */
118195 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
118196 +
118197 +#if (DPAA_VERSION >= 11)
118198 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
118199 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
118200 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
118201 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
118202 + the inserted header */
118203 + uint16_t id; /**< 16 bit New IP ID */
118204 + bool dont_frag_overwrite;
118205 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
118206 + * This byte is configured to be overwritten when RPD is set. */
118207 + uint8_t last_dst_offset;
118208 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
118209 + * in order to calculate UDP checksum pseudo header;
118210 + * Otherwise set it to '0'. */
118211 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
118212 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
118213 +#endif /* (DPAA_VERSION >= 11) */
118214 +
118215 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
118216 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
118217 + union {
118218 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
118219 +#if (DPAA_VERSION >= 11)
118220 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
118221 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
118222 +#endif /* (DPAA_VERSION >= 11) */
118223 + } u;
118224 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
118225 +
118226 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
118227 + ioc_fm_pcd_manip_hdr_insrt_type type;
118228 + union {
118229 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
118230 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
118231 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118232 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118233 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
118234 +#endif /* FM_CAPWAP_SUPPORT */
118235 + } u;
118236 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
118237 +
118238 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
118239 + bool rmv;
118240 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
118241 + bool insrt;
118242 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
118243 + bool field_update;
118244 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
118245 + bool custom;
118246 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
118247 + bool dont_parse_after_manip;
118248 +} ioc_compat_fm_pcd_manip_hdr_params_t;
118249 +
118250 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
118251 + bool decryption;
118252 + bool ecn_copy;
118253 + bool dscp_copy;
118254 + bool variable_ip_hdr_len;
118255 + bool variable_ip_version;
118256 + uint8_t outer_ip_hdr_len;
118257 + uint16_t arw_size;
118258 + compat_uptr_t arw_addr;
118259 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
118260 +
118261 +typedef struct ioc_compat_fm_pcd_manip_params_t {
118262 + ioc_fm_pcd_manip_type type;
118263 + union {
118264 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
118265 + ioc_fm_pcd_manip_reassem_params_t reassem;
118266 + ioc_fm_pcd_manip_frag_params_t frag;
118267 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
118268 + } u;
118269 + compat_uptr_t p_next_manip;
118270 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
118271 +#error "FM_CAPWAP_SUPPORT feature not supported!"
118272 + bool frag_or_reasm;
118273 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
118274 +#endif /* FM_CAPWAP_SUPPORT */
118275 + compat_uptr_t id;
118276 +} ioc_compat_fm_pcd_manip_params_t;
118277 +
118278 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
118279 + compat_uptr_t id;
118280 + ioc_fm_pcd_manip_stats_t stats;
118281 +} ioc_compat_fm_pcd_manip_get_stats_t;
118282 +
118283 +#if (DPAA_VERSION >= 11)
118284 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
118285 + uint8_t max_num_of_entries;
118286 + uint8_t num_of_entries;
118287 + ioc_compat_fm_pcd_cc_next_engine_params_t
118288 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
118289 + compat_uptr_t id;
118290 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
118291 +
118292 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
118293 + compat_uptr_t h_replic_group;
118294 + uint16_t member_index;
118295 +} ioc_compat_fm_pcd_frm_replic_member_t;
118296 +
118297 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
118298 + ioc_compat_fm_pcd_frm_replic_member_t member;
118299 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
118300 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
118301 +
118302 +typedef struct ioc_compat_fm_vsp_params_t {
118303 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
118304 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
118305 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
118306 + parameter associated with Rx / OP port */
118307 + uint16_t liodn_offset; /**< VSP's LIODN offset */
118308 + struct {
118309 + ioc_fm_port_type port_type; /**< Port type */
118310 + uint8_t port_id; /**< Port Id - relative to type */
118311 + } port_params;
118312 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
118313 + defined in relevant FM object */
118314 + compat_uptr_t id; /**< return value */
118315 +} ioc_compat_fm_vsp_params_t;
118316 +
118317 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
118318 + compat_uptr_t p_fm_vsp;
118319 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
118320 +} ioc_compat_fm_buf_pool_depletion_params_t;
118321 +
118322 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
118323 + compat_uptr_t p_fm_vsp;
118324 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
118325 +} ioc_compat_fm_buffer_prefix_content_params_t;
118326 +
118327 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
118328 + compat_uptr_t p_fm_vsp;
118329 + bool no_sg;
118330 +} ioc_compat_fm_vsp_config_no_sg_params_t;
118331 +
118332 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
118333 + compat_uptr_t p_fm_vsp;
118334 + compat_uptr_t p_data;
118335 +} ioc_compat_fm_vsp_prs_result_params_t;
118336 +
118337 +#endif /* (DPAA_VERSION >= 11) */
118338 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
118339 + uint32_t val;
118340 + compat_uptr_t id;
118341 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
118342 +
118343 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
118344 + uint8_t fm_ctrl_index;
118345 + compat_uptr_t p_mon;
118346 +} ioc_compat_fm_ctrl_mon_counters_params_t;
118347 +
118348 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
118349 + compat_uptr_t id;
118350 + uint16_t key_index;
118351 + ioc_fm_pcd_cc_key_statistics_t statistics;
118352 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
118353 +
118354 +
118355 +/* } pcd compat structures */
118356 +
118357 +void compat_obj_delete(
118358 + ioc_compat_fm_obj_t *compat_id,
118359 + ioc_fm_obj_t *id);
118360 +
118361 +/* pcd compat functions { */
118362 +void compat_copy_fm_pcd_plcr_profile(
118363 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118364 + ioc_fm_pcd_plcr_profile_params_t *param,
118365 + uint8_t compat);
118366 +
118367 +void compat_copy_fm_pcd_cc_key(
118368 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118369 + ioc_fm_pcd_cc_key_params_t *param,
118370 + uint8_t compat);
118371 +
118372 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118373 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118374 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118375 + uint8_t compat);
118376 +
118377 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118378 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118379 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118380 + uint8_t compat);
118381 +
118382 +void compat_fm_pcd_cc_tree_modify_next_engine(
118383 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118384 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118385 + uint8_t compat);
118386 +
118387 +void compat_copy_fm_pcd_hash_table(
118388 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118389 + ioc_fm_pcd_hash_table_params_t *param,
118390 + uint8_t compat);
118391 +
118392 +void compat_copy_fm_pcd_cc_grp(
118393 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118394 + ioc_fm_pcd_cc_grp_params_t *param,
118395 + uint8_t compat);
118396 +
118397 +void compat_copy_fm_pcd_cc_tree(
118398 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118399 + ioc_fm_pcd_cc_tree_params_t *param,
118400 + uint8_t compat);
118401 +
118402 +void compat_copy_fm_pcd_cc_tbl_get_stats(
118403 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
118404 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
118405 + uint8_t compat);
118406 +
118407 +void compat_fm_pcd_prs_sw(
118408 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118409 + ioc_fm_pcd_prs_sw_params_t *param,
118410 + uint8_t compat);
118411 +
118412 +void compat_copy_fm_pcd_kg_scheme(
118413 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118414 + ioc_fm_pcd_kg_scheme_params_t *param,
118415 + uint8_t compat);
118416 +
118417 +void compat_copy_fm_pcd_kg_scheme_select(
118418 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118419 + ioc_fm_pcd_kg_scheme_select_t *param,
118420 + uint8_t compat);
118421 +
118422 +void compat_copy_fm_pcd_kg_schemes_params(
118423 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118424 + ioc_fm_pcd_port_schemes_params_t *param,
118425 + uint8_t compat);
118426 +
118427 +void compat_copy_fm_port_pcd_kg(
118428 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118429 + ioc_fm_port_pcd_kg_params_t *param,
118430 + uint8_t compat);
118431 +
118432 +void compat_copy_fm_port_pcd(
118433 + ioc_compat_fm_port_pcd_params_t *compat_param,
118434 + ioc_fm_port_pcd_params_t *param,
118435 + uint8_t compat);
118436 +
118437 +#if (DPAA_VERSION >= 11)
118438 +void compat_copy_fm_port_vsp_alloc_params(
118439 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
118440 + ioc_fm_port_vsp_alloc_params_t *param,
118441 + uint8_t compat);
118442 +#endif /* (DPAA_VERSION >= 11) */
118443 +
118444 +void compat_copy_fm_pcd_net_env(
118445 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
118446 + ioc_fm_pcd_net_env_params_t *param,
118447 + uint8_t compat);
118448 +
118449 +void compat_copy_fm_pcd_cc_node_modify_key(
118450 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
118451 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
118452 + uint8_t compat);
118453 +
118454 +void compat_copy_keys(
118455 + ioc_compat_keys_params_t *compat_param,
118456 + ioc_keys_params_t *param,
118457 + uint8_t compat);
118458 +
118459 +void compat_copy_fm_pcd_cc_node(
118460 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
118461 + ioc_fm_pcd_cc_node_params_t *param,
118462 + uint8_t compat);
118463 +
118464 +void compat_fm_pcd_manip_set_node(
118465 + ioc_compat_fm_pcd_manip_params_t *compat_param,
118466 + ioc_fm_pcd_manip_params_t *param,
118467 + uint8_t compat);
118468 +
118469 +void compat_copy_fm_pcd_manip_get_stats(
118470 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
118471 + ioc_fm_pcd_manip_get_stats_t *param,
118472 + uint8_t compat);
118473 +
118474 +void compat_copy_fm_port_pcd_modify_tree(
118475 + ioc_compat_fm_obj_t *compat_id,
118476 + ioc_fm_obj_t *id,
118477 + uint8_t compat);
118478 +
118479 +#if (DPAA_VERSION >= 11)
118480 +void compat_copy_fm_pcd_frm_replic_group_params(
118481 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
118482 + ioc_fm_pcd_frm_replic_group_params_t *param,
118483 + uint8_t compat);
118484 +
118485 +void compat_copy_fm_pcd_frm_replic_member(
118486 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
118487 + ioc_fm_pcd_frm_replic_member_t *param,
118488 + uint8_t compat);
118489 +
118490 +void compat_copy_fm_pcd_frm_replic_member_params(
118491 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
118492 + ioc_fm_pcd_frm_replic_member_params_t *param,
118493 + uint8_t compat);
118494 +
118495 +void compat_copy_fm_vsp_params(
118496 + ioc_compat_fm_vsp_params_t *compat_param,
118497 + ioc_fm_vsp_params_t *param,
118498 + uint8_t compat);
118499 +
118500 +void compat_copy_fm_buf_pool_depletion_params(
118501 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
118502 + ioc_fm_buf_pool_depletion_params_t *param,
118503 + uint8_t compat);
118504 +
118505 +void compat_copy_fm_buffer_prefix_content_params(
118506 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
118507 + ioc_fm_buffer_prefix_content_params_t *param,
118508 + uint8_t compat);
118509 +
118510 +void compat_copy_fm_vsp_config_no_sg_params(
118511 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
118512 + ioc_fm_vsp_config_no_sg_params_t *param,
118513 + uint8_t compat);
118514 +
118515 +void compat_copy_fm_vsp_prs_result_params(
118516 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
118517 + ioc_fm_vsp_prs_result_params_t *param,
118518 + uint8_t compat);
118519 +
118520 +#endif /* (DPAA_VERSION >= 11) */
118521 +
118522 +void compat_copy_fm_pcd_kg_scheme_spc(
118523 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118524 + ioc_fm_pcd_kg_scheme_spc_t *param,
118525 + uint8_t compat);
118526 +
118527 +/* } pcd compat functions */
118528 +#endif
118529 --- /dev/null
118530 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
118531 @@ -0,0 +1,121 @@
118532 +/*
118533 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118534 + *
118535 + * Redistribution and use in source and binary forms, with or without
118536 + * modification, are permitted provided that the following conditions are met:
118537 + * * Redistributions of source code must retain the above copyright
118538 + * notice, this list of conditions and the following disclaimer.
118539 + * * Redistributions in binary form must reproduce the above copyright
118540 + * notice, this list of conditions and the following disclaimer in the
118541 + * documentation and/or other materials provided with the distribution.
118542 + * * Neither the name of Freescale Semiconductor nor the
118543 + * names of its contributors may be used to endorse or promote products
118544 + * derived from this software without specific prior written permission.
118545 + *
118546 + *
118547 + * ALTERNATIVELY, this software may be distributed under the terms of the
118548 + * GNU General Public License ("GPL") as published by the Free Software
118549 + * Foundation, either version 2 of that License or (at your option) any
118550 + * later version.
118551 + *
118552 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118553 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118554 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118555 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118556 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118557 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118558 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118559 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118560 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118561 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118562 + */
118563 +
118564 +/*
118565 + @File lnxwrp_resources.h
118566 +
118567 + @Description FMD wrapper resource allocation functions.
118568 +
118569 +*/
118570 +
118571 +#ifndef LNXWRP_RESOURCES_H_
118572 +#define LNXWRP_RESOURCES_H_
118573 +
118574 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118575 +#include "lnxwrp_fm.h"
118576 +#else
118577 +#include "lnxwrp_resources_ut.h"
118578 +#endif
118579 +
118580 +#define ROUND(X) ((2*(X)+1)/2)
118581 +#define CEIL(X) ((X)+1)
118582 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
118583 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
118584 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
118585 +
118586 +/* used for resource calculus */
118587 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
118588 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
118589 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
118590 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
118591 +
118592 +int fm_set_active_fman_ports(struct platform_device *of_dev,
118593 + t_LnxWrpFmDev *p_LnxWrpFmDev);
118594 +
118595 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
118596 + * value and s/g software support (! Kernel does not suport s/g).
118597 + *
118598 + * Algorithm summary:
118599 + * - Calculate the the minimum fifosize required for every type of port
118600 + * (TX,RX for 1G, 2.5G and 10G).
118601 + * - Set TX the minimum fifosize required.
118602 + * - Distribute the remaining buffers (after all TX were set) to RX ports
118603 + * based on:
118604 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
118605 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
118606 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
118607 + * - if the RX is smaller than the minimum required, then set the minimum
118608 + * required
118609 + * - In the end distribuite the leftovers if there are any (due to
118610 + * unprecise calculus) or if over allocation cat some buffers from all RX
118611 + * ports w/o pass over minimum required treshold, but if there must be
118612 + * pass the treshold in order to cat the over allocation ,then this
118613 + * configuration can not be set - KERN_ALERT.
118614 +*/
118615 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
118616 + int muram_fifo_size);
118617 +
118618 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118619 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118620 +#endif
118621 +
118622 +/* Compute FMan open DMA based on total number of open DMAs and
118623 + * number of available fman ports.
118624 + *
118625 + * By default 10g ports are set to input parameters. The other ports
118626 + * tries to keep the proportion rx=2tx open dmas or tresholds.
118627 + *
118628 + * If leftovers, then those will be set as shared.
118629 + *
118630 + * If after computing overflow appears, then it decrements open dma
118631 + * for all ports w/o cross the tresholds. If the tresholds are meet
118632 + * and is still overflow, then it returns error.
118633 +*/
118634 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
118635 + int max_fm_open_dma,
118636 + int default_tx_10g_dmas,
118637 + int default_rx_10g_dmas,
118638 + int min_tx_10g_treshold, int min_rx_10g_treshold);
118639 +
118640 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118641 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118642 +#endif
118643 +
118644 +/* Compute FMan tnums based on available tnums and number of ports.
118645 + * Set defaults (minim tresholds) and then distribute leftovers.*/
118646 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
118647 +
118648 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
118649 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
118650 +#endif
118651 +
118652 +#endif /* LNXWRP_RESOURCES_H_ */
118653 --- /dev/null
118654 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
118655 @@ -0,0 +1,191 @@
118656 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
118657 + * All rights reserved.
118658 + *
118659 + * Redistribution and use in source and binary forms, with or without
118660 + * modification, are permitted provided that the following conditions are met:
118661 + * * Redistributions of source code must retain the above copyright
118662 + * notice, this list of conditions and the following disclaimer.
118663 + * * Redistributions in binary form must reproduce the above copyright
118664 + * notice, this list of conditions and the following disclaimer in the
118665 + * documentation and/or other materials provided with the distribution.
118666 + * * Neither the name of Freescale Semiconductor nor the
118667 + * names of its contributors may be used to endorse or promote products
118668 + * derived from this software without specific prior written permission.
118669 + *
118670 + *
118671 + * ALTERNATIVELY, this software may be distributed under the terms of the
118672 + * GNU General Public License ("GPL") as published by the Free Software
118673 + * Foundation, either version 2 of that License or (at your option) any
118674 + * later version.
118675 + *
118676 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118677 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118678 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118679 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118680 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118681 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118682 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118683 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118684 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118685 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118686 + */
118687 +
118688 +#include "lnxwrp_resources.h"
118689 +#include "lnxwrp_resources_ut.h"
118690 +
118691 +#define KILOBYTE 0x400 /* 1024 */
118692 +
118693 +typedef enum e_board_type {
118694 + e_p3041,
118695 + e_p4080,
118696 + e_p5020,
118697 + e_p1023
118698 +} e_board_type;
118699 +
118700 +uint8_t board_type;
118701 +uint32_t muram_size = 0;
118702 +uint32_t dmas_num = 0;
118703 +uint32_t task_num = 0;
118704 +uint32_t frame_size = 0;
118705 +uint32_t oh_num = 0;
118706 +uint32_t num_ports_1g = 0;
118707 +uint32_t num_ports_10g = 0;
118708 +uint32_t num_ports_2g5 = 0;
118709 +uint32_t fsl_fman_phy_maxfrm = 0;
118710 +uint32_t dpa_rx_extra_headroom = 0;
118711 +
118712 +void show_help(void){
118713 + printf(" help: \n");
118714 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
118715 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
118716 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
118717 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
118718 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
118719 + printf(" Number of ports:\n");
118720 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
118721 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
118722 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
118723 + printf(" MTU: Default:1522, Jumbo:9600 \n");
118724 +}
118725 +
118726 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
118727 + struct fm_active_ports *fm_active_ports_info = NULL;
118728 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
118729 +
118730 + switch(board_type){
118731 + case e_p3041:
118732 + case e_p5020:
118733 + muram_size = 160*KILOBYTE;
118734 + dmas_num = 32;
118735 + task_num = 128;
118736 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
118737 + goto err_fm_set_param;
118738 + break;
118739 + case e_p4080:
118740 + muram_size = 160*KILOBYTE;
118741 + dmas_num = 32;
118742 + task_num = 128;
118743 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
118744 + goto err_fm_set_param;
118745 + break;
118746 + case e_p1023:
118747 + muram_size = 64*KILOBYTE;
118748 + dmas_num = 16;
118749 + task_num = 128;
118750 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
118751 + goto err_fm_set_param;
118752 + break;
118753 + default:
118754 + goto err_fm_set_param;
118755 + break;
118756 + }
118757 +
118758 + p_LnxWrpFmDev->id = 0;
118759 + fsl_fman_phy_maxfrm = frame_size;
118760 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
118761 + fm_active_ports_info->num_oh_ports = oh_num;
118762 + fm_active_ports_info->num_tx_ports = num_ports_1g;
118763 + fm_active_ports_info->num_rx_ports = num_ports_1g;
118764 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
118765 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
118766 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
118767 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
118768 +
118769 + return 0;
118770 +
118771 +err_fm_set_param:
118772 + printf(" ERR: To many ports!!! \n");
118773 + return -1;
118774 +}
118775 +
118776 +int main (int argc, char *argv[]){
118777 + t_LnxWrpFmDev LnxWrpFmDev;
118778 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
118779 + int tokens_cnt = 1;
118780 +
118781 + char *token = NULL;
118782 +
118783 + while(tokens_cnt < argc)
118784 + {
118785 + token = argv[tokens_cnt++];
118786 + if (strcmp(token, "-b") == 0){
118787 + if(strcmp(argv[tokens_cnt],"p3") == 0)
118788 + board_type = e_p3041;
118789 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
118790 + board_type = e_p4080;
118791 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
118792 + board_type = e_p5020;
118793 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
118794 + board_type = e_p1023;
118795 + else
118796 + show_help();
118797 + tokens_cnt++;
118798 + }
118799 + else if(strcmp(token, "-d") == 0){
118800 + dmas_num = atoi(argv[tokens_cnt++]);
118801 + }
118802 + else if(strcmp(token, "-t") == 0)
118803 + task_num = atoi(argv[tokens_cnt++]);
118804 + else if(strcmp(token, "-f") == 0)
118805 + frame_size = atoi(argv[tokens_cnt++]);
118806 + else if(strcmp(token, "-o") == 0)
118807 + oh_num = atoi(argv[tokens_cnt++]);
118808 + else if(strcmp(token, "-g1") == 0)
118809 + num_ports_1g = atoi(argv[tokens_cnt++]);
118810 + else if(strcmp(token, "-g10") == 0)
118811 + num_ports_10g = atoi(argv[tokens_cnt++]);
118812 + else if(strcmp(token, "-g25") == 0)
118813 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
118814 + else {
118815 + show_help();
118816 + return -1;
118817 + }
118818 + }
118819 +
118820 + if(fm_set_param(p_LnxWrpFmDev) < 0){
118821 + show_help();
118822 + return -1;
118823 + }
118824 +
118825 + if(fm_precalculate_fifosizes(
118826 + p_LnxWrpFmDev,
118827 + 128*KILOBYTE)
118828 + != 0)
118829 + return -1;
118830 + if(fm_precalculate_open_dma(
118831 + p_LnxWrpFmDev,
118832 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
118833 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
118834 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
118835 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
118836 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
118837 + != 0)
118838 + return -1;
118839 + if(fm_precalculate_tnums(
118840 + p_LnxWrpFmDev,
118841 + task_num) /* max TNUMS: dpa integration file. */
118842 + != 0)
118843 + return -1;
118844 +
118845 + return 0;
118846 +}
118847 --- /dev/null
118848 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
118849 @@ -0,0 +1,144 @@
118850 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
118851 + * All rights reserved.
118852 + *
118853 + * Redistribution and use in source and binary forms, with or without
118854 + * modification, are permitted provided that the following conditions are met:
118855 + * * Redistributions of source code must retain the above copyright
118856 + * notice, this list of conditions and the following disclaimer.
118857 + * * Redistributions in binary form must reproduce the above copyright
118858 + * notice, this list of conditions and the following disclaimer in the
118859 + * documentation and/or other materials provided with the distribution.
118860 + * * Neither the name of Freescale Semiconductor nor the
118861 + * names of its contributors may be used to endorse or promote products
118862 + * derived from this software without specific prior written permission.
118863 + *
118864 + *
118865 + * ALTERNATIVELY, this software may be distributed under the terms of the
118866 + * GNU General Public License ("GPL") as published by the Free Software
118867 + * Foundation, either version 2 of that License or (at your option) any
118868 + * later version.
118869 + *
118870 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118871 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118872 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118873 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118874 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118875 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118876 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118877 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118878 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118879 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118880 + */
118881 +
118882 +#ifndef FM_RESS_TEST_H_
118883 +#define FM_RESS_TEST_H_
118884 +
118885 +#include <stdint.h>
118886 +#include <stdbool.h>
118887 +#include <stdio.h>
118888 +#include <assert.h>
118889 +#include <string.h>
118890 +#include <stdlib.h>
118891 +
118892 +#define _Packed
118893 +#define _PackedType __attribute__ ((packed))
118894 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
118895 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
118896 +#define KERN_ALERT ""
118897 +#define KERN_INFO ""
118898 +#define ASSERT_COND assert
118899 +#define printk printf
118900 +#define NET_IP_ALIGN 0
118901 +#define FM_FIFO_ALLOCATION_OLD_ALG
118902 +
118903 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
118904 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
118905 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
118906 +#else
118907 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
118908 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
118909 +#endif
118910 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
118911 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
118912 +
118913 +/* information about all active ports for an FMan.
118914 + * !Some ports may be disabled by u-boot, thus will not be available */
118915 +struct fm_active_ports {
118916 + uint32_t num_oh_ports;
118917 + uint32_t num_tx_ports;
118918 + uint32_t num_rx_ports;
118919 + uint32_t num_tx25_ports;
118920 + uint32_t num_rx25_ports;
118921 + uint32_t num_tx10_ports;
118922 + uint32_t num_rx10_ports;
118923 +};
118924 +
118925 +/* FMan resources precalculated at fm probe based
118926 + * on available FMan port. */
118927 +struct fm_resource_settings {
118928 + /* buffers - fifo sizes */
118929 + uint32_t tx1g_num_buffers;
118930 + uint32_t rx1g_num_buffers;
118931 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
118932 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
118933 + uint32_t tx10g_num_buffers;
118934 + uint32_t rx10g_num_buffers;
118935 + uint32_t oh_num_buffers;
118936 + uint32_t shared_ext_buffers;
118937 +
118938 +
118939 + /* open DMAs */
118940 + uint32_t tx_1g_dmas;
118941 + uint32_t rx_1g_dmas;
118942 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
118943 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
118944 + uint32_t tx_10g_dmas;
118945 + uint32_t rx_10g_dmas;
118946 + uint32_t oh_dmas;
118947 + uint32_t shared_ext_open_dma;
118948 +
118949 + /* Tnums */
118950 + uint32_t tx_1g_tnums;
118951 + uint32_t rx_1g_tnums;
118952 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
118953 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
118954 + uint32_t tx_10g_tnums;
118955 + uint32_t rx_10g_tnums;
118956 + uint32_t oh_tnums;
118957 + uint32_t shared_ext_tnums;
118958 +};
118959 +
118960 +typedef struct {
118961 + uint8_t id;
118962 + struct fm_active_ports fm_active_ports_info;
118963 + struct fm_resource_settings fm_resource_settings_info;
118964 +} t_LnxWrpFmDev;
118965 +
118966 +typedef struct {
118967 + uint8_t id;
118968 +} t_LnxWrpFmPortDev;
118969 +
118970 +typedef _Packed struct t_FmPrsResult {
118971 + volatile uint8_t lpid; /**< Logical port id */
118972 + volatile uint8_t shimr; /**< Shim header result */
118973 + volatile uint16_t l2r; /**< Layer 2 result */
118974 + volatile uint16_t l3r; /**< Layer 3 result */
118975 + volatile uint8_t l4r; /**< Layer 4 result */
118976 + volatile uint8_t cplan; /**< Classification plan id */
118977 + volatile uint16_t nxthdr; /**< Next Header */
118978 + volatile uint16_t cksum; /**< Checksum */
118979 + volatile uint32_t lcv; /**< LCV */
118980 + volatile uint8_t shim_off[3]; /**< Shim offset */
118981 + volatile uint8_t eth_off; /**< ETH offset */
118982 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
118983 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
118984 + volatile uint8_t etype_off; /**< ETYPE offset */
118985 + volatile uint8_t pppoe_off; /**< PPP offset */
118986 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
118987 + volatile uint8_t ip_off[2]; /**< IP offset */
118988 + volatile uint8_t gre_off; /**< GRE offset */
118989 + volatile uint8_t l4_off; /**< Layer 4 offset */
118990 + volatile uint8_t nxthdr_off; /**< Parser end point */
118991 +} _PackedType t_FmPrsResult;
118992 +
118993 +#endif
118994 --- /dev/null
118995 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
118996 @@ -0,0 +1,28 @@
118997 +CC=gcc
118998 +
118999 +LNXWRP_RESS_UT=lnxwrp_resources_ut
119000 +OBJ=lnxwrp_resources
119001 +
119002 +INC_PATH=
119003 +LIB_PATH=
119004 +
119005 +INC=$(addprefix -I,$(INC_PATH))
119006 +LIB=$(addprefix -L,$(LIB_PATH))
119007 +
119008 +CFLAGS= -gdwarf-2 -g -O0 -Wall
119009 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
119010 +
119011 +all: $(LNXWRP_RESS_UT)
119012 +
119013 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
119014 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
119015 +
119016 +%.o: %.c
119017 + @(echo " (CC) $@")
119018 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
119019 +
119020 +.PHONY: clean
119021 +
119022 +clean:
119023 + rm -f *.o
119024 + rm -f $(LNXWRP_RESS_UT)
119025 --- /dev/null
119026 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
119027 @@ -0,0 +1,60 @@
119028 +/*
119029 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119030 + *
119031 + * Redistribution and use in source and binary forms, with or without
119032 + * modification, are permitted provided that the following conditions are met:
119033 + * * Redistributions of source code must retain the above copyright
119034 + * notice, this list of conditions and the following disclaimer.
119035 + * * Redistributions in binary form must reproduce the above copyright
119036 + * notice, this list of conditions and the following disclaimer in the
119037 + * documentation and/or other materials provided with the distribution.
119038 + * * Neither the name of Freescale Semiconductor nor the
119039 + * names of its contributors may be used to endorse or promote products
119040 + * derived from this software without specific prior written permission.
119041 + *
119042 + *
119043 + * ALTERNATIVELY, this software may be distributed under the terms of the
119044 + * GNU General Public License ("GPL") as published by the Free Software
119045 + * Foundation, either version 2 of that License or (at your option) any
119046 + * later version.
119047 + *
119048 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119049 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119050 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119051 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119052 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119053 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119054 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119055 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119056 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119057 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119058 + */
119059 +
119060 +/*
119061 + @File lnxwrp_sysfs.c
119062 +
119063 + @Description FM wrapper sysfs related functions.
119064 +
119065 +*/
119066 +
119067 +#include <linux/types.h>
119068 +#include "lnxwrp_sysfs.h"
119069 +
119070 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119071 + const struct sysfs_stats_t *sysfs_stats,
119072 + uint8_t *offset)
119073 +{
119074 + int i = 0;
119075 +
119076 + while (sysfs_stats[i].stat_name != NULL) {
119077 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
119078 + if (offset != NULL)
119079 + *offset = i;
119080 + return sysfs_stats[i].stat_counter;
119081 + }
119082 +
119083 + i++;
119084 + }
119085 + WARN(1, "FMD: Should never get here!");
119086 + return 0;
119087 +}
119088 --- /dev/null
119089 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
119090 @@ -0,0 +1,60 @@
119091 +/*
119092 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119093 + *
119094 + * Redistribution and use in source and binary forms, with or without
119095 + * modification, are permitted provided that the following conditions are met:
119096 + * * Redistributions of source code must retain the above copyright
119097 + * notice, this list of conditions and the following disclaimer.
119098 + * * Redistributions in binary form must reproduce the above copyright
119099 + * notice, this list of conditions and the following disclaimer in the
119100 + * documentation and/or other materials provided with the distribution.
119101 + * * Neither the name of Freescale Semiconductor nor the
119102 + * names of its contributors may be used to endorse or promote products
119103 + * derived from this software without specific prior written permission.
119104 + *
119105 + *
119106 + * ALTERNATIVELY, this software may be distributed under the terms of the
119107 + * GNU General Public License ("GPL") as published by the Free Software
119108 + * Foundation, either version 2 of that License or (at your option) any
119109 + * later version.
119110 + *
119111 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119112 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119113 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119114 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119115 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119116 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119117 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119118 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119119 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119120 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119121 + */
119122 +
119123 +#ifndef LNXWRP_SYSFS_H_
119124 +#define LNXWRP_SYSFS_H_
119125 +
119126 +/* Linux Headers ------------------- */
119127 +#include <linux/version.h>
119128 +
119129 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
119130 +#define MODVERSIONS
119131 +#endif
119132 +#ifdef MODVERSIONS
119133 +#include <config/modversions.h>
119134 +#endif /* MODVERSIONS */
119135 +
119136 +#include <linux/kernel.h>
119137 +#include <linux/module.h>
119138 +#include <linux/device.h>
119139 +#include <linux/sysfs.h>
119140 +
119141 +struct sysfs_stats_t {
119142 + const char *stat_name;
119143 + uint8_t stat_counter;
119144 +};
119145 +
119146 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
119147 + const struct sysfs_stats_t *sysfs_stats,
119148 + uint8_t *offset);
119149 +
119150 +#endif /* LNXWRP_SYSFS_H_ */
119151 --- /dev/null
119152 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
119153 @@ -0,0 +1,1855 @@
119154 +/*
119155 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119156 + *
119157 + * Redistribution and use in source and binary forms, with or without
119158 + * modification, are permitted provided that the following conditions are met:
119159 + * * Redistributions of source code must retain the above copyright
119160 + * notice, this list of conditions and the following disclaimer.
119161 + * * Redistributions in binary form must reproduce the above copyright
119162 + * notice, this list of conditions and the following disclaimer in the
119163 + * documentation and/or other materials provided with the distribution.
119164 + * * Neither the name of Freescale Semiconductor nor the
119165 + * names of its contributors may be used to endorse or promote products
119166 + * derived from this software without specific prior written permission.
119167 + *
119168 + *
119169 + * ALTERNATIVELY, this software may be distributed under the terms of the
119170 + * GNU General Public License ("GPL") as published by the Free Software
119171 + * Foundation, either version 2 of that License or (at your option) any
119172 + * later version.
119173 + *
119174 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119175 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119176 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119177 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119178 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119179 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119180 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119181 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119182 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119183 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119184 + */
119185 +
119186 +#include "lnxwrp_sysfs.h"
119187 +#include "lnxwrp_sysfs_fm.h"
119188 +#include "lnxwrp_fm.h"
119189 +
119190 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
119191 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
119192 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
119193 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
119194 +
119195 +#if defined(__ERR_MODULE__)
119196 +#undef __ERR_MODULE__
119197 +#endif
119198 +
119199 +#include "../../sdk_fman/Peripherals/FM/fm.h"
119200 +#include <linux/delay.h>
119201 +
119202 +
119203 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
119204 +
119205 +enum fm_dma_match_stats {
119206 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119207 + FM_DMA_COUNTERS_BUS_ERROR,
119208 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119209 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119210 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
119211 +};
119212 +
119213 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
119214 + /* FM statistics */
119215 + {
119216 + .stat_name = "enq_total_frame",
119217 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
119218 + },
119219 + {
119220 + .stat_name = "deq_total_frame",
119221 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
119222 + },
119223 + {
119224 + .stat_name = "deq_0",
119225 + .stat_counter = e_FM_COUNTERS_DEQ_0,
119226 + },
119227 + {
119228 + .stat_name = "deq_1",
119229 + .stat_counter = e_FM_COUNTERS_DEQ_1,
119230 + },
119231 + {
119232 + .stat_name = "deq_2",
119233 + .stat_counter = e_FM_COUNTERS_DEQ_2,
119234 + },
119235 + {
119236 + .stat_name = "deq_3",
119237 + .stat_counter = e_FM_COUNTERS_DEQ_3,
119238 + },
119239 + {
119240 + .stat_name = "deq_from_default",
119241 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
119242 + },
119243 + {
119244 + .stat_name = "deq_from_context",
119245 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
119246 + },
119247 + {
119248 + .stat_name = "deq_from_fd",
119249 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
119250 + },
119251 + {
119252 + .stat_name = "deq_confirm",
119253 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
119254 + },
119255 + /* FM:DMA statistics */
119256 + {
119257 + .stat_name = "cmq_not_empty",
119258 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
119259 + },
119260 + {
119261 + .stat_name = "bus_error",
119262 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
119263 + },
119264 + {
119265 + .stat_name = "read_buf_ecc_error",
119266 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
119267 + },
119268 + {
119269 + .stat_name = "write_buf_ecc_sys_error",
119270 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
119271 + },
119272 + {
119273 + .stat_name = "write_buf_ecc_fm_error",
119274 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
119275 + },
119276 + /* FM:PCD statistics */
119277 + {
119278 + .stat_name = "pcd_kg_total",
119279 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
119280 + },
119281 + {
119282 + .stat_name = "pcd_plcr_yellow",
119283 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
119284 + },
119285 + {
119286 + .stat_name = "pcd_plcr_red",
119287 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
119288 + },
119289 + {
119290 + .stat_name = "pcd_plcr_recolored_to_red",
119291 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
119292 + },
119293 + {
119294 + .stat_name = "pcd_plcr_recolored_to_yellow",
119295 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
119296 + },
119297 + {
119298 + .stat_name = "pcd_plcr_total",
119299 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
119300 + },
119301 + {
119302 + .stat_name = "pcd_plcr_length_mismatch",
119303 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
119304 + },
119305 + {
119306 + .stat_name = "pcd_prs_parse_dispatch",
119307 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
119308 + },
119309 + {
119310 + .stat_name = "pcd_prs_l2_parse_result_returned",
119311 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
119312 + },
119313 + {
119314 + .stat_name = "pcd_prs_l3_parse_result_returned",
119315 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
119316 + },
119317 + {
119318 + .stat_name = "pcd_prs_l4_parse_result_returned",
119319 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
119320 + },
119321 + {
119322 + .stat_name = "pcd_prs_shim_parse_result_returned",
119323 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
119324 + },
119325 + {
119326 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
119327 + .stat_counter =
119328 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
119329 + },
119330 + {
119331 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
119332 + .stat_counter =
119333 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
119334 + },
119335 + {
119336 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
119337 + .stat_counter =
119338 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
119339 + },
119340 + {
119341 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
119342 + .stat_counter =
119343 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
119344 + },
119345 + {
119346 + .stat_name = "pcd_prs_soft_prs_cycles",
119347 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
119348 + },
119349 + {
119350 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
119351 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
119352 + },
119353 + {
119354 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
119355 + .stat_counter =
119356 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
119357 + },
119358 + {
119359 + .stat_name = "pcd_prs_muram_read_cycles",
119360 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
119361 + },
119362 + {
119363 + .stat_name = "pcd_prs_muram_read_stall_cycles",
119364 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
119365 + },
119366 + {
119367 + .stat_name = "pcd_prs_muram_write_cycles",
119368 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
119369 + },
119370 + {
119371 + .stat_name = "pcd_prs_muram_write_stall_cycles",
119372 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
119373 + },
119374 + {
119375 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
119376 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
119377 + },
119378 + {}
119379 +};
119380 +
119381 +
119382 +static ssize_t show_fm_risc_load(struct device *dev,
119383 + struct device_attribute *attr, char *buf)
119384 +{
119385 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119386 + unsigned long flags;
119387 + int m =0;
119388 + int err =0;
119389 + unsigned n = 0;
119390 + t_FmCtrlMon util;
119391 + uint8_t i =0 ;
119392 +
119393 + if (attr == NULL || buf == NULL || dev == NULL)
119394 + return -EINVAL;
119395 +
119396 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119397 + if (WARN_ON(p_wrp_fm_dev == NULL))
119398 + return -EINVAL;
119399 +
119400 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119401 + return -EIO;
119402 +
119403 + local_irq_save(flags);
119404 +
119405 + /* Calculate risc load */
119406 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
119407 + msleep(1000);
119408 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
119409 +
119410 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
119411 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
119412 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
119413 + i, util.percentCnt[0], util.percentCnt[1]);
119414 + n=m+n;
119415 + }
119416 +
119417 + local_irq_restore(flags);
119418 +
119419 + return n;
119420 +}
119421 +
119422 +/* Fm stats and regs dumps via sysfs */
119423 +static ssize_t show_fm_dma_stats(struct device *dev,
119424 + struct device_attribute *attr, char *buf)
119425 +{
119426 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119427 + t_FmDmaStatus dma_status;
119428 + unsigned long flags = 0;
119429 + unsigned n = 0;
119430 + uint8_t counter_value = 0, counter = 0;
119431 +
119432 + if (attr == NULL || buf == NULL || dev == NULL)
119433 + return -EINVAL;
119434 +
119435 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119436 + if (WARN_ON(p_wrp_fm_dev == NULL))
119437 + return -EINVAL;
119438 +
119439 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119440 + return -EIO;
119441 +
119442 + counter = fm_find_statistic_counter_by_name(
119443 + attr->attr.name,
119444 + fm_sysfs_stats, NULL);
119445 +
119446 + local_irq_save(flags);
119447 +
119448 + memset(&dma_status, 0, sizeof(dma_status));
119449 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
119450 +
119451 + switch (counter) {
119452 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
119453 + counter_value = dma_status.cmqNotEmpty;
119454 + break;
119455 + case FM_DMA_COUNTERS_BUS_ERROR:
119456 + counter_value = dma_status.busError;
119457 + break;
119458 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
119459 + counter_value = dma_status.readBufEccError;
119460 + break;
119461 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
119462 + counter_value = dma_status.writeBufEccSysError;
119463 + break;
119464 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
119465 + counter_value = dma_status.writeBufEccFmError;
119466 + break;
119467 + default:
119468 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
119469 + __func__);
119470 + break;
119471 + };
119472 +
119473 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
119474 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
119475 +
119476 + local_irq_restore(flags);
119477 +
119478 + return n;
119479 +}
119480 +
119481 +static ssize_t show_fm_stats(struct device *dev,
119482 + struct device_attribute *attr, char *buf)
119483 +{
119484 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119485 + unsigned long flags = 0;
119486 + unsigned n = 0, cnt_e = 0;
119487 + uint32_t cnt_val;
119488 + int err;
119489 +
119490 + if (attr == NULL || buf == NULL || dev == NULL)
119491 + return -EINVAL;
119492 +
119493 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119494 + if (WARN_ON(p_wrp_fm_dev == NULL))
119495 + return -EINVAL;
119496 +
119497 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119498 + return -EIO;
119499 +
119500 + cnt_e = fm_find_statistic_counter_by_name(
119501 + attr->attr.name,
119502 + fm_sysfs_stats, NULL);
119503 +
119504 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
119505 + (e_FmCounters) cnt_e, &cnt_val);
119506 +
119507 + if (err)
119508 + return err;
119509 +
119510 + local_irq_save(flags);
119511 +
119512 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119513 + p_wrp_fm_dev->id, cnt_val);
119514 +
119515 + local_irq_restore(flags);
119516 +
119517 + return n;
119518 +}
119519 +
119520 +static ssize_t show_fm_muram_free_sz(struct device *dev,
119521 + struct device_attribute *attr, char *buf)
119522 +{
119523 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119524 + unsigned long flags = 0;
119525 + unsigned n = 0;
119526 + uint64_t muram_free_size = 0;
119527 +
119528 + if (attr == NULL || buf == NULL || dev == NULL)
119529 + return -EINVAL;
119530 +
119531 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119532 + if (WARN_ON(p_wrp_fm_dev == NULL))
119533 + return -EINVAL;
119534 +
119535 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119536 + return -EIO;
119537 +
119538 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
119539 +
119540 + local_irq_save(flags);
119541 +
119542 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
119543 + p_wrp_fm_dev->id, muram_free_size);
119544 +
119545 + local_irq_restore(flags);
119546 +
119547 + return n;
119548 +}
119549 +
119550 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
119551 + struct device_attribute *attr, char *buf)
119552 +{
119553 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119554 + unsigned long flags = 0;
119555 + unsigned n = 0;
119556 + t_FmCtrlCodeRevisionInfo rv_info;
119557 +
119558 + if (attr == NULL || buf == NULL || dev == NULL)
119559 + return -EINVAL;
119560 +
119561 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119562 + if (WARN_ON(p_wrp_fm_dev == NULL))
119563 + return -EINVAL;
119564 +
119565 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
119566 + return -EIO;
119567 +
119568 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
119569 +
119570 + local_irq_save(flags);
119571 +
119572 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
119573 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
119574 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
119575 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
119576 +
119577 + local_irq_restore(flags);
119578 +
119579 + return n;
119580 +}
119581 +
119582 +static ssize_t show_fm_pcd_stats(struct device *dev,
119583 + struct device_attribute *attr, char *buf)
119584 +{
119585 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119586 + unsigned long flags = 0;
119587 + unsigned n = 0, counter = 0;
119588 +
119589 + if (attr == NULL || buf == NULL || dev == NULL)
119590 + return -EINVAL;
119591 +
119592 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119593 + if (WARN_ON(p_wrp_fm_dev == NULL))
119594 + return -EINVAL;
119595 +
119596 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
119597 + !p_wrp_fm_dev->h_PcdDev)
119598 + return -EIO;
119599 +
119600 + counter = fm_find_statistic_counter_by_name(
119601 + attr->attr.name,
119602 + fm_sysfs_stats, NULL);
119603 +
119604 + local_irq_save(flags);
119605 +
119606 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
119607 + p_wrp_fm_dev->id,
119608 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
119609 + (e_FmPcdCounters) counter));
119610 +
119611 + local_irq_restore(flags);
119612 +
119613 + return n;
119614 +}
119615 +
119616 +static ssize_t show_fm_tnum_dbg(struct device *dev,
119617 + struct device_attribute *attr,
119618 + char *buf)
119619 +{
119620 + unsigned long flags;
119621 + unsigned n = 0;
119622 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119623 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119624 +#endif
119625 +
119626 + if (attr == NULL || buf == NULL || dev == NULL)
119627 + return -EINVAL;
119628 +
119629 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119630 +
119631 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119632 + if (WARN_ON(p_wrp_fm_dev == NULL))
119633 + return -EINVAL;
119634 +
119635 + local_irq_save(flags);
119636 +
119637 + if (!p_wrp_fm_dev->active)
119638 + return -EIO;
119639 + else {
119640 + int tn_s;
119641 +
119642 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
119643 + return -EINVAL;
119644 +
119645 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
119646 + tn_s, tn_s + 15, buf, n);
119647 + }
119648 + local_irq_restore(flags);
119649 +#else
119650 +
119651 + local_irq_save(flags);
119652 + n = snprintf(buf, PAGE_SIZE,
119653 + "Debug level is too low to dump registers!!!\n");
119654 + local_irq_restore(flags);
119655 +#endif /* (defined(DEBUG_ERRORS) && ... */
119656 +
119657 + return n;
119658 +}
119659 +
119660 +static ssize_t show_fm_cls_plan(struct device *dev,
119661 + struct device_attribute *attr,
119662 + char *buf)
119663 +{
119664 + unsigned long flags;
119665 + unsigned n = 0;
119666 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119667 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119668 +#endif
119669 +
119670 + if (attr == NULL || buf == NULL || dev == NULL)
119671 + return -EINVAL;
119672 +
119673 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119674 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119675 + if (WARN_ON(p_wrp_fm_dev == NULL))
119676 + return -EINVAL;
119677 +
119678 + local_irq_save(flags);
119679 +
119680 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
119681 +
119682 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119683 + return -EIO;
119684 + else {
119685 + int cpn;
119686 +
119687 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
119688 + return -EINVAL;
119689 +
119690 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
119691 + }
119692 + local_irq_restore(flags);
119693 +#else
119694 + local_irq_save(flags);
119695 + n = snprintf(buf, PAGE_SIZE,
119696 + "Debug level is too low to dump registers!!!\n");
119697 + local_irq_restore(flags);
119698 +#endif /* (defined(DEBUG_ERRORS) && ... */
119699 +
119700 + return n;
119701 +}
119702 +
119703 +static ssize_t show_fm_profiles(struct device *dev,
119704 + struct device_attribute *attr,
119705 + char *buf)
119706 +{
119707 + unsigned long flags;
119708 + unsigned n = 0;
119709 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119710 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119711 +#endif
119712 +
119713 + if (attr == NULL || buf == NULL || dev == NULL)
119714 + return -EINVAL;
119715 +
119716 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119717 +
119718 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119719 + if (WARN_ON(p_wrp_fm_dev == NULL))
119720 + return -EINVAL;
119721 +
119722 + local_irq_save(flags);
119723 +
119724 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
119725 +
119726 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119727 + return -EIO;
119728 + else {
119729 + int pn;
119730 +
119731 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
119732 + return -EINVAL;
119733 +
119734 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
119735 + }
119736 + local_irq_restore(flags);
119737 +#else
119738 + local_irq_save(flags);
119739 + n = snprintf(buf, PAGE_SIZE,
119740 + "Debug level is too low to dump registers!!!\n");
119741 + local_irq_restore(flags);
119742 +#endif /* (defined(DEBUG_ERRORS) && ... */
119743 +
119744 + return n;
119745 +}
119746 +
119747 +static ssize_t show_fm_schemes(struct device *dev,
119748 + struct device_attribute *attr,
119749 + char *buf)
119750 +{
119751 + unsigned long flags;
119752 + unsigned n = 0;
119753 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119754 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
119755 +#endif
119756 +
119757 + if (attr == NULL || buf == NULL || dev == NULL)
119758 + return -EINVAL;
119759 +
119760 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
119761 +
119762 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
119763 + if (WARN_ON(p_wrp_fm_dev == NULL))
119764 + return -EINVAL;
119765 +
119766 + local_irq_save(flags);
119767 +
119768 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
119769 +
119770 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
119771 + return -EIO;
119772 + else {
119773 + int sn;
119774 +
119775 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
119776 + return -EINVAL;
119777 +
119778 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
119779 + }
119780 + local_irq_restore(flags);
119781 +#else
119782 +
119783 + local_irq_save(flags);
119784 + n = snprintf(buf, PAGE_SIZE,
119785 + "Debug level is too low to dump registers!!!\n");
119786 + local_irq_restore(flags);
119787 +#endif /* (defined(DEBUG_ERRORS) && ... */
119788 +
119789 + return n;
119790 +}
119791 +
119792 +/* FM */
119793 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
119794 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
119795 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
119796 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
119797 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
119798 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
119799 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
119800 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
119801 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
119802 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
119803 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
119804 +/* FM:DMA */
119805 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
119806 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
119807 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
119808 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
119809 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
119810 +/* FM:PCD */
119811 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
119812 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
119813 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
119814 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
119815 + NULL);
119816 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
119817 + NULL);
119818 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
119819 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
119820 + NULL);
119821 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
119822 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
119823 + show_fm_pcd_stats, NULL);
119824 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
119825 + show_fm_pcd_stats, NULL);
119826 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
119827 + show_fm_pcd_stats, NULL);
119828 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
119829 + show_fm_pcd_stats, NULL);
119830 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
119831 + show_fm_pcd_stats, NULL);
119832 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
119833 + show_fm_pcd_stats, NULL);
119834 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
119835 + show_fm_pcd_stats, NULL);
119836 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
119837 + show_fm_pcd_stats, NULL);
119838 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
119839 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
119840 + NULL);
119841 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
119842 + show_fm_pcd_stats, NULL);
119843 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
119844 + NULL);
119845 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
119846 + show_fm_pcd_stats, NULL);
119847 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
119848 + NULL);
119849 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
119850 + show_fm_pcd_stats, NULL);
119851 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
119852 + show_fm_pcd_stats, NULL);
119853 +
119854 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
119855 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
119856 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
119857 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
119858 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
119859 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
119860 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
119861 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
119862 +
119863 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
119864 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
119865 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
119866 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
119867 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
119868 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
119869 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
119870 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
119871 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
119872 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
119873 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
119874 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
119875 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
119876 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
119877 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
119878 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
119879 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
119880 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
119881 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
119882 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
119883 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
119884 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
119885 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
119886 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
119887 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
119888 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
119889 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
119890 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
119891 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
119892 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
119893 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
119894 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
119895 +
119896 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
119897 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
119898 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
119899 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
119900 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
119901 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
119902 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
119903 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
119904 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
119905 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
119906 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
119907 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
119908 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
119909 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
119910 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
119911 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
119912 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
119913 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
119914 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
119915 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
119916 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
119917 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
119918 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
119919 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
119920 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
119921 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
119922 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
119923 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
119924 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
119925 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
119926 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
119927 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
119928 +
119929 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
119930 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
119931 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
119932 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
119933 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
119934 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
119935 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
119936 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
119937 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
119938 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
119939 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
119940 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
119941 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
119942 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
119943 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
119944 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
119945 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
119946 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
119947 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
119948 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
119949 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
119950 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
119951 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
119952 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
119953 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
119954 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
119955 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
119956 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
119957 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
119958 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
119959 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
119960 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
119961 +
119962 +
119963 +static struct attribute *fm_dev_stats_attributes[] = {
119964 + &dev_attr_enq_total_frame.attr,
119965 + &dev_attr_deq_total_frame.attr,
119966 + &dev_attr_deq_0.attr,
119967 + &dev_attr_deq_1.attr,
119968 + &dev_attr_deq_2.attr,
119969 + &dev_attr_deq_3.attr,
119970 + &dev_attr_deq_from_default.attr,
119971 + &dev_attr_deq_from_context.attr,
119972 + &dev_attr_deq_from_fd.attr,
119973 + &dev_attr_deq_confirm.attr,
119974 + &dev_attr_cmq_not_empty.attr,
119975 + &dev_attr_bus_error.attr,
119976 + &dev_attr_read_buf_ecc_error.attr,
119977 + &dev_attr_write_buf_ecc_sys_error.attr,
119978 + &dev_attr_write_buf_ecc_fm_error.attr,
119979 + &dev_attr_pcd_kg_total.attr,
119980 + &dev_attr_pcd_plcr_yellow.attr,
119981 + &dev_attr_pcd_plcr_red.attr,
119982 + &dev_attr_pcd_plcr_recolored_to_red.attr,
119983 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
119984 + &dev_attr_pcd_plcr_total.attr,
119985 + &dev_attr_pcd_plcr_length_mismatch.attr,
119986 + &dev_attr_pcd_prs_parse_dispatch.attr,
119987 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
119988 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
119989 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
119990 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
119991 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
119992 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
119993 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
119994 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
119995 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
119996 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
119997 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
119998 + &dev_attr_pcd_prs_muram_read_cycles.attr,
119999 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
120000 + &dev_attr_pcd_prs_muram_write_cycles.attr,
120001 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
120002 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
120003 + NULL
120004 +};
120005 +
120006 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
120007 + &dev_attr_tnum_dbg_0.attr,
120008 + &dev_attr_tnum_dbg_16.attr,
120009 + &dev_attr_tnum_dbg_32.attr,
120010 + &dev_attr_tnum_dbg_48.attr,
120011 + &dev_attr_tnum_dbg_64.attr,
120012 + &dev_attr_tnum_dbg_80.attr,
120013 + &dev_attr_tnum_dbg_96.attr,
120014 + &dev_attr_tnum_dbg_112.attr,
120015 + NULL
120016 +};
120017 +
120018 +static struct attribute *fm_dev_cls_plans_attributes[] = {
120019 + &dev_attr_cls_plan_0.attr,
120020 + &dev_attr_cls_plan_1.attr,
120021 + &dev_attr_cls_plan_2.attr,
120022 + &dev_attr_cls_plan_3.attr,
120023 + &dev_attr_cls_plan_4.attr,
120024 + &dev_attr_cls_plan_5.attr,
120025 + &dev_attr_cls_plan_6.attr,
120026 + &dev_attr_cls_plan_7.attr,
120027 + &dev_attr_cls_plan_8.attr,
120028 + &dev_attr_cls_plan_9.attr,
120029 + &dev_attr_cls_plan_10.attr,
120030 + &dev_attr_cls_plan_11.attr,
120031 + &dev_attr_cls_plan_12.attr,
120032 + &dev_attr_cls_plan_13.attr,
120033 + &dev_attr_cls_plan_14.attr,
120034 + &dev_attr_cls_plan_15.attr,
120035 + &dev_attr_cls_plan_16.attr,
120036 + &dev_attr_cls_plan_17.attr,
120037 + &dev_attr_cls_plan_18.attr,
120038 + &dev_attr_cls_plan_19.attr,
120039 + &dev_attr_cls_plan_20.attr,
120040 + &dev_attr_cls_plan_21.attr,
120041 + &dev_attr_cls_plan_22.attr,
120042 + &dev_attr_cls_plan_23.attr,
120043 + &dev_attr_cls_plan_24.attr,
120044 + &dev_attr_cls_plan_25.attr,
120045 + &dev_attr_cls_plan_26.attr,
120046 + &dev_attr_cls_plan_27.attr,
120047 + &dev_attr_cls_plan_28.attr,
120048 + &dev_attr_cls_plan_29.attr,
120049 + &dev_attr_cls_plan_30.attr,
120050 + &dev_attr_cls_plan_31.attr,
120051 + NULL
120052 +};
120053 +
120054 +static struct attribute *fm_dev_profiles_attributes[] = {
120055 + &dev_attr_profile_0.attr,
120056 + &dev_attr_profile_1.attr,
120057 + &dev_attr_profile_2.attr,
120058 + &dev_attr_profile_3.attr,
120059 + &dev_attr_profile_4.attr,
120060 + &dev_attr_profile_5.attr,
120061 + &dev_attr_profile_6.attr,
120062 + &dev_attr_profile_7.attr,
120063 + &dev_attr_profile_8.attr,
120064 + &dev_attr_profile_9.attr,
120065 + &dev_attr_profile_10.attr,
120066 + &dev_attr_profile_11.attr,
120067 + &dev_attr_profile_12.attr,
120068 + &dev_attr_profile_13.attr,
120069 + &dev_attr_profile_14.attr,
120070 + &dev_attr_profile_15.attr,
120071 + &dev_attr_profile_16.attr,
120072 + &dev_attr_profile_17.attr,
120073 + &dev_attr_profile_18.attr,
120074 + &dev_attr_profile_19.attr,
120075 + &dev_attr_profile_20.attr,
120076 + &dev_attr_profile_21.attr,
120077 + &dev_attr_profile_22.attr,
120078 + &dev_attr_profile_23.attr,
120079 + &dev_attr_profile_24.attr,
120080 + &dev_attr_profile_25.attr,
120081 + &dev_attr_profile_26.attr,
120082 + &dev_attr_profile_27.attr,
120083 + &dev_attr_profile_28.attr,
120084 + &dev_attr_profile_29.attr,
120085 + &dev_attr_profile_30.attr,
120086 + &dev_attr_profile_31.attr,
120087 + NULL
120088 +};
120089 +
120090 +static struct attribute *fm_dev_schemes_attributes[] = {
120091 + &dev_attr_scheme_0.attr,
120092 + &dev_attr_scheme_1.attr,
120093 + &dev_attr_scheme_2.attr,
120094 + &dev_attr_scheme_3.attr,
120095 + &dev_attr_scheme_4.attr,
120096 + &dev_attr_scheme_5.attr,
120097 + &dev_attr_scheme_6.attr,
120098 + &dev_attr_scheme_7.attr,
120099 + &dev_attr_scheme_8.attr,
120100 + &dev_attr_scheme_9.attr,
120101 + &dev_attr_scheme_10.attr,
120102 + &dev_attr_scheme_11.attr,
120103 + &dev_attr_scheme_12.attr,
120104 + &dev_attr_scheme_13.attr,
120105 + &dev_attr_scheme_14.attr,
120106 + &dev_attr_scheme_15.attr,
120107 + &dev_attr_scheme_16.attr,
120108 + &dev_attr_scheme_17.attr,
120109 + &dev_attr_scheme_18.attr,
120110 + &dev_attr_scheme_19.attr,
120111 + &dev_attr_scheme_20.attr,
120112 + &dev_attr_scheme_21.attr,
120113 + &dev_attr_scheme_22.attr,
120114 + &dev_attr_scheme_23.attr,
120115 + &dev_attr_scheme_24.attr,
120116 + &dev_attr_scheme_25.attr,
120117 + &dev_attr_scheme_26.attr,
120118 + &dev_attr_scheme_27.attr,
120119 + &dev_attr_scheme_28.attr,
120120 + &dev_attr_scheme_29.attr,
120121 + &dev_attr_scheme_30.attr,
120122 + &dev_attr_scheme_31.attr,
120123 + NULL
120124 +};
120125 +
120126 +static const struct attribute_group fm_dev_stats_attr_grp = {
120127 + .name = "statistics",
120128 + .attrs = fm_dev_stats_attributes
120129 +};
120130 +
120131 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
120132 + .name = "tnums_dbg",
120133 + .attrs = fm_dev_tnums_dbg_attributes
120134 +};
120135 +
120136 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
120137 + .name = "cls_plans",
120138 + .attrs = fm_dev_cls_plans_attributes
120139 +};
120140 +
120141 +static const struct attribute_group fm_dev_schemes_attr_grp = {
120142 + .name = "schemes",
120143 + .attrs = fm_dev_schemes_attributes
120144 +};
120145 +
120146 +static const struct attribute_group fm_dev_profiles_attr_grp = {
120147 + .name = "profiles",
120148 + .attrs = fm_dev_profiles_attributes
120149 +};
120150 +
120151 +static ssize_t show_fm_regs(struct device *dev,
120152 + struct device_attribute *attr,
120153 + char *buf)
120154 +{
120155 + unsigned long flags;
120156 + unsigned n = 0;
120157 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120158 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120159 +#endif
120160 + if (attr == NULL || buf == NULL || dev == NULL)
120161 + return -EINVAL;
120162 +
120163 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120164 +
120165 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120166 + if (WARN_ON(p_wrp_fm_dev == NULL))
120167 + return -EINVAL;
120168 +
120169 + local_irq_save(flags);
120170 +
120171 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
120172 +
120173 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120174 + return -EIO;
120175 + else
120176 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120177 +
120178 + local_irq_restore(flags);
120179 +#else
120180 +
120181 + local_irq_save(flags);
120182 + n = snprintf(buf, PAGE_SIZE,
120183 + "Debug level is too low to dump registers!!!\n");
120184 + local_irq_restore(flags);
120185 +#endif /* (defined(DEBUG_ERRORS) && ... */
120186 +
120187 + return n;
120188 +}
120189 +
120190 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
120191 + struct device_attribute *attr,
120192 + char *buf)
120193 +{
120194 + unsigned long flags;
120195 + unsigned n = 0;
120196 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120197 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120198 +#endif
120199 +
120200 + if (attr == NULL || buf == NULL || dev == NULL)
120201 + return -EINVAL;
120202 +
120203 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120204 +
120205 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120206 + if (WARN_ON(p_wrp_fm_dev == NULL))
120207 + return -EINVAL;
120208 +
120209 + local_irq_save(flags);
120210 +
120211 + n = snprintf(buf, PAGE_SIZE,
120212 + "\n FM-KG Port Partition Config registers dump.\n");
120213 +
120214 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120215 + return -EIO;
120216 + else
120217 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120218 +
120219 + local_irq_restore(flags);
120220 +#else
120221 +
120222 + local_irq_save(flags);
120223 + n = snprintf(buf, PAGE_SIZE,
120224 + "Debug level is too low to dump registers!!!\n");
120225 + local_irq_restore(flags);
120226 +#endif /* (defined(DEBUG_ERRORS) && ... */
120227 +
120228 + return n;
120229 +}
120230 +
120231 +static ssize_t show_fm_kg_regs(struct device *dev,
120232 + struct device_attribute *attr,
120233 + char *buf)
120234 +{
120235 + unsigned long flags;
120236 + unsigned n = 0;
120237 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120238 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120239 +#endif
120240 +
120241 + if (attr == NULL || buf == NULL || dev == NULL)
120242 + return -EINVAL;
120243 +
120244 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120245 +
120246 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120247 + if (WARN_ON(p_wrp_fm_dev == NULL))
120248 + return -EINVAL;
120249 +
120250 + local_irq_save(flags);
120251 +
120252 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
120253 +
120254 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120255 + return -EIO;
120256 + else
120257 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120258 +
120259 + local_irq_restore(flags);
120260 +#else
120261 +
120262 + local_irq_save(flags);
120263 + n = snprintf(buf, PAGE_SIZE,
120264 + "Debug level is too low to dump registers!!!\n");
120265 + local_irq_restore(flags);
120266 +#endif /* (defined(DEBUG_ERRORS) && ... */
120267 +
120268 + return n;
120269 +}
120270 +
120271 +
120272 +static ssize_t show_fm_fpm_regs(struct device *dev,
120273 + struct device_attribute *attr,
120274 + char *buf)
120275 +{
120276 + unsigned long flags;
120277 + unsigned n = 0;
120278 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120279 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120280 +#endif
120281 +
120282 + if (attr == NULL || buf == NULL || dev == NULL)
120283 + return -EINVAL;
120284 +
120285 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120286 +
120287 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120288 + if (WARN_ON(p_wrp_fm_dev == NULL))
120289 + return -EINVAL;
120290 +
120291 + local_irq_save(flags);
120292 +
120293 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
120294 +
120295 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
120296 + return -EIO;
120297 + else
120298 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
120299 +
120300 + local_irq_restore(flags);
120301 +#else
120302 +
120303 + local_irq_save(flags);
120304 + n = snprintf(buf, PAGE_SIZE,
120305 + "Debug level is too low to dump registers!!!\n");
120306 + local_irq_restore(flags);
120307 +#endif /* (defined(DEBUG_ERRORS) && ... */
120308 +
120309 + return n;
120310 +}
120311 +
120312 +static ssize_t show_prs_regs(struct device *dev,
120313 + struct device_attribute *attr, char *buf)
120314 +{
120315 + unsigned long flags;
120316 + unsigned n = 0;
120317 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120318 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120319 +#endif
120320 +
120321 + if (attr == NULL || buf == NULL || dev == NULL)
120322 + return -EINVAL;
120323 +
120324 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120325 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120326 + if (WARN_ON(p_wrp_fm_dev == NULL))
120327 + return -EINVAL;
120328 +
120329 + local_irq_save(flags);
120330 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120331 +
120332 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120333 + return -EIO;
120334 + else
120335 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120336 +
120337 + local_irq_restore(flags);
120338 +#else
120339 +
120340 + local_irq_save(flags);
120341 + n = snprintf(buf, PAGE_SIZE,
120342 + "Debug level is too low to dump registers!!!\n");
120343 + local_irq_restore(flags);
120344 +
120345 +#endif /* (defined(DEBUG_ERRORS) && ... */
120346 +
120347 + return n;
120348 +}
120349 +
120350 +static ssize_t show_plcr_regs(struct device *dev,
120351 + struct device_attribute *attr,
120352 + char *buf)
120353 +{
120354 + unsigned long flags;
120355 + unsigned n = 0;
120356 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120357 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120358 +#endif
120359 +
120360 + if (attr == NULL || buf == NULL || dev == NULL)
120361 + return -EINVAL;
120362 +
120363 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
120364 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120365 + if (WARN_ON(p_wrp_fm_dev == NULL))
120366 + return -EINVAL;
120367 +
120368 + local_irq_save(flags);
120369 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
120370 +
120371 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
120372 + return -EIO;
120373 + else
120374 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
120375 +
120376 + local_irq_restore(flags);
120377 +#else
120378 +
120379 + local_irq_save(flags);
120380 + n = snprintf(buf, PAGE_SIZE,
120381 + "Debug level is too low to dump registers!!!\n");
120382 + local_irq_restore(flags);
120383 +
120384 +#endif /* (defined(DEBUG_ERRORS) && ... */
120385 +
120386 + return n;
120387 +}
120388 +
120389 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
120390 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
120391 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
120392 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
120393 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
120394 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
120395 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
120396 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
120397 +
120398 +int fm_sysfs_create(struct device *dev)
120399 +{
120400 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120401 +
120402 + if (dev == NULL)
120403 + return -EIO;
120404 +
120405 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120406 +
120407 + /* store to remove them when module is disabled */
120408 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
120409 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
120410 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
120411 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
120412 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
120413 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
120414 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
120415 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
120416 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
120417 +
120418 + /* Create sysfs statistics group for FM module */
120419 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
120420 + return -EIO;
120421 +
120422 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
120423 + return -EIO;
120424 +
120425 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
120426 + return -EIO;
120427 +
120428 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
120429 + return -EIO;
120430 +
120431 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
120432 + return -EIO;
120433 +
120434 + /* Registers dump entry - in future will be moved to debugfs */
120435 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
120436 + return -EIO;
120437 +
120438 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
120439 + return -EIO;
120440 +
120441 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
120442 + return -EIO;
120443 +
120444 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
120445 + return -EIO;
120446 +
120447 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
120448 + return -EIO;
120449 +
120450 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
120451 + return -EIO;
120452 +
120453 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
120454 + return -EIO;
120455 +
120456 + /* muram free size */
120457 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
120458 + return -EIO;
120459 +
120460 + /* fm ctrl code version */
120461 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
120462 + return -EIO;
120463 +
120464 + return 0;
120465 +}
120466 +
120467 +void fm_sysfs_destroy(struct device *dev)
120468 +{
120469 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
120470 +
120471 + if (WARN_ON(dev == NULL))
120472 + return;
120473 +
120474 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
120475 + if (WARN_ON(p_wrp_fm_dev == NULL))
120476 + return;
120477 +
120478 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
120479 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
120480 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
120481 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
120482 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
120483 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
120484 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
120485 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
120486 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
120487 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
120488 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
120489 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
120490 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
120491 +}
120492 +
120493 +int fm_dump_regs(void *h_fm, char *buf, int nn)
120494 +{
120495 + t_Fm *p_Fm = (t_Fm *)h_fm;
120496 + uint8_t i = 0;
120497 + int n = nn;
120498 +
120499 + FM_DMP_SUBTITLE(buf, n, "\n");
120500 +
120501 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
120502 +
120503 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
120504 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
120505 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
120506 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
120507 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
120508 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
120509 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
120510 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
120511 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
120512 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
120513 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
120514 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
120515 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
120516 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
120517 +
120518 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
120519 +
120520 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
120521 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
120522 +
120523 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
120524 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
120525 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
120526 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
120527 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
120528 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
120529 +
120530 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
120531 + for (i = 0; i < 8 ; ++i)
120532 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
120533 +
120534 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
120535 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
120536 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
120537 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
120538 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
120539 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
120540 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
120541 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
120542 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
120543 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
120544 +
120545 + return n;
120546 +}
120547 +
120548 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
120549 +{
120550 + t_Fm *p_Fm = (t_Fm *)h_fm;
120551 + uint8_t i, j = 0;
120552 + int n = nn;
120553 +
120554 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
120555 + tn_s, tn_e);
120556 +
120557 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
120558 +
120559 + mb();
120560 +
120561 + for (j = tn_s; j <= tn_e; j++) {
120562 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
120563 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
120564 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
120565 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
120566 +
120567 + for (i = 0; i < 4 ; ++i)
120568 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
120569 +
120570 + FM_DMP_LN(buf, n, "\n");
120571 +
120572 + }
120573 +
120574 + return n;
120575 +}
120576 +
120577 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
120578 +{
120579 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120580 + int i = 0;
120581 + uint32_t tmp;
120582 + unsigned long i_flg;
120583 + int n = nn;
120584 + u_FmPcdKgIndirectAccessRegs *idac;
120585 + spinlock_t *p_lk;
120586 +
120587 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120588 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120589 +
120590 + spin_lock_irqsave(p_lk, i_flg);
120591 +
120592 + /* Read ClsPlan Block Action Regs */
120593 + tmp = (uint32_t)(FM_KG_KGAR_GO |
120594 + FM_KG_KGAR_READ |
120595 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
120596 + DUMMY_PORT_ID |
120597 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
120598 + FM_PCD_KG_KGAR_WSEL_MASK);
120599 +
120600 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
120601 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120602 + spin_unlock_irqrestore(p_lk, i_flg);
120603 + return nn;
120604 + }
120605 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
120606 + "ClsPlan %d Indirect Access Regs", cpn);
120607 +
120608 + for (i = 0; i < 8; i++)
120609 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
120610 +
120611 + spin_unlock_irqrestore(p_lk, i_flg);
120612 +
120613 + return n;
120614 +}
120615 +
120616 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
120617 +{
120618 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120619 + t_FmPcdPlcrProfileRegs *p_prof_regs;
120620 + t_FmPcdPlcrRegs *p_plcr_regs;
120621 + t_FmPcdPlcr *p_plcr;
120622 + uint32_t tmp;
120623 + unsigned long i_flg;
120624 + int n = nn;
120625 + int toc = 10;
120626 + spinlock_t *p_lk;
120627 +
120628 + p_plcr = p_pcd->p_FmPcdPlcr;
120629 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
120630 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
120631 +
120632 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
120633 +
120634 + FM_DMP_SUBTITLE(buf, n, "\n");
120635 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
120636 +
120637 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
120638 + FM_PCD_PLCR_PAR_R |
120639 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
120640 + FM_PCD_PLCR_PAR_PWSEL_MASK);
120641 +
120642 + spin_lock_irqsave(p_lk, i_flg);
120643 +
120644 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
120645 +
120646 + mb();
120647 +
120648 + /* wait for the porfile regs to be present */
120649 + do {
120650 + --toc;
120651 + udelay(10);
120652 + if (!toc) {
120653 + /* looks like PLCR_PAR_GO refuses to clear */
120654 + spin_unlock_irqrestore(p_lk, i_flg);
120655 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
120656 + FM_DMP_LN(buf, n, " check profile init process\n");
120657 + return n;
120658 + }
120659 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
120660 +
120661 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
120662 +
120663 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
120664 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
120665 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
120666 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
120667 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
120668 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
120669 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
120670 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
120671 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
120672 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
120673 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
120674 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
120675 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
120676 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
120677 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
120678 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
120679 +
120680 + spin_unlock_irqrestore(p_lk, i_flg);
120681 +
120682 + return n;
120683 +}
120684 +
120685 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
120686 +{
120687 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120688 + uint32_t tmp_ar;
120689 + unsigned long i_flg;
120690 + int i, n = nn;
120691 + spinlock_t *p_lk;
120692 + u_FmPcdKgIndirectAccessRegs *idac;
120693 +
120694 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120695 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
120696 +
120697 + spin_lock_irqsave(p_lk, i_flg);
120698 +
120699 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
120700 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
120701 + FM_DMP_LN(buf, nn,
120702 + "Keygen scheme access violation or no such scheme");
120703 + spin_unlock_irqrestore(p_lk, i_flg);
120704 + return nn;
120705 + }
120706 +
120707 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
120708 + "Scheme %d Indirect Access Regs", scnum);
120709 +
120710 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
120711 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
120712 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
120713 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
120714 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
120715 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
120716 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
120717 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
120718 +
120719 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
120720 +
120721 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
120722 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
120723 +
120724 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
120725 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
120726 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
120727 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
120728 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
120729 +
120730 + FM_DMP_SUBTITLE(buf, n, "\n");
120731 +
120732 + spin_unlock_irqrestore(p_lk, i_flg);
120733 +
120734 + return n;
120735 +}
120736 +
120737 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
120738 +{
120739 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120740 + int i = 0;
120741 + uint8_t prt_id = 0;
120742 + uint32_t tmp_ar;
120743 + unsigned long i_flg;
120744 + int n = nn;
120745 + u_FmPcdKgIndirectAccessRegs *idac;
120746 + t_FmPcdKg *p_kg;
120747 + spinlock_t *p_lk;
120748 +
120749 + p_kg = p_pcd->p_FmPcdKg;
120750 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
120751 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
120752 +
120753 + spin_lock_irqsave(p_lk, i_flg);
120754 +
120755 + FM_DMP_SUBTITLE(buf, n, "\n");
120756 +
120757 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
120758 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
120759 +
120760 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
120761 +
120762 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
120763 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
120764 + spin_unlock_irqrestore(p_lk, i_flg);
120765 + return nn;
120766 + }
120767 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
120768 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
120769 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
120770 + }
120771 +
120772 + FM_DMP_SUBTITLE(buf, n, "\n");
120773 +
120774 + spin_unlock_irqrestore(p_lk, i_flg);
120775 +
120776 + return n;
120777 +}
120778 +
120779 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
120780 +{
120781 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120782 + int n = nn;
120783 +
120784 + FM_DMP_SUBTITLE(buf, n, "\n");
120785 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
120786 + "FmPcdKgRegs Regs");
120787 +
120788 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
120789 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
120790 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
120791 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
120792 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
120793 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
120794 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
120795 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
120796 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
120797 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
120798 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
120799 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
120800 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
120801 +
120802 + FM_DMP_SUBTITLE(buf, n, "\n");
120803 +
120804 + return n;
120805 +}
120806 +
120807 +
120808 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
120809 +{
120810 + t_Fm *p_fm = (t_Fm *)h_fm;
120811 + uint8_t i;
120812 + int n = nn;
120813 +
120814 + FM_DMP_SUBTITLE(buf, n, "\n");
120815 +
120816 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
120817 +
120818 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
120819 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
120820 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
120821 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
120822 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
120823 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
120824 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
120825 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
120826 +
120827 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
120828 + for (i = 0; i < 4; ++i)
120829 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
120830 +
120831 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
120832 + for (i = 0; i < 4; ++i)
120833 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
120834 +
120835 + FM_DMP_SUBTITLE(buf, n, "\n");
120836 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
120837 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
120838 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
120839 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
120840 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
120841 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
120842 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
120843 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
120844 +
120845 + FM_DMP_SUBTITLE(buf, n, "\n");
120846 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
120847 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
120848 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
120849 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
120850 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
120851 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
120852 +
120853 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
120854 + for (i = 0; i < 4; ++i)
120855 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
120856 +
120857 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
120858 + for (i = 0; i < 64; ++i)
120859 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
120860 +
120861 + return n;
120862 +}
120863 +
120864 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
120865 +{
120866 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120867 + int n = nn;
120868 +
120869 + FM_DMP_SUBTITLE(buf, n, "\n");
120870 +
120871 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
120872 + "FM-PCD parser regs");
120873 +
120874 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
120875 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
120876 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
120877 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
120878 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
120879 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
120880 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
120881 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
120882 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
120883 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
120884 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
120885 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
120886 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
120887 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
120888 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
120889 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
120890 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
120891 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
120892 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
120893 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
120894 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
120895 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
120896 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
120897 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
120898 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
120899 +
120900 + return n;
120901 +}
120902 +
120903 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
120904 +{
120905 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
120906 + int i = 0;
120907 + int n = nn;
120908 +
120909 + FM_DMP_SUBTITLE(buf, n, "\n");
120910 +
120911 + FM_DMP_TITLE(buf, n,
120912 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
120913 + "FM policer regs");
120914 +
120915 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
120916 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
120917 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
120918 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
120919 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
120920 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
120921 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
120922 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
120923 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
120924 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
120925 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
120926 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
120927 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
120928 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
120929 +
120930 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
120931 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
120932 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
120933 +
120934 + FM_DMP_TITLE(buf, n,
120935 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
120936 + "fmpl_pmr");
120937 +
120938 + for (i = 0; i < 63; ++i)
120939 + FM_DMP_MEM_32(buf, n,
120940 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
120941 +
120942 + return n;
120943 +}
120944 +
120945 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
120946 +{
120947 + t_Fm *p_fm = (t_Fm *)h_fm;
120948 +
120949 + /* When applicable (when there is an "enable counters" bit),
120950 + check that counters are enabled */
120951 +
120952 + switch (cnt_e) {
120953 + case (e_FM_COUNTERS_DEQ_1):
120954 + case (e_FM_COUNTERS_DEQ_2):
120955 + case (e_FM_COUNTERS_DEQ_3):
120956 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
120957 + return -EINVAL; /* counter not available */
120958 +
120959 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120960 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120961 + case (e_FM_COUNTERS_DEQ_0):
120962 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120963 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120964 + case (e_FM_COUNTERS_DEQ_FROM_FD):
120965 + case (e_FM_COUNTERS_DEQ_CONFIRM):
120966 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
120967 + QMI_CFG_EN_COUNTERS))
120968 + return -EINVAL; /* Requested counter not available */
120969 + break;
120970 + default:
120971 + break;
120972 + }
120973 +
120974 + switch (cnt_e) {
120975 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
120976 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
120977 + return 0;
120978 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
120979 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
120980 + return 0;
120981 + case (e_FM_COUNTERS_DEQ_0):
120982 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
120983 + return 0;
120984 + case (e_FM_COUNTERS_DEQ_1):
120985 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
120986 + return 0;
120987 + case (e_FM_COUNTERS_DEQ_2):
120988 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
120989 + return 0;
120990 + case (e_FM_COUNTERS_DEQ_3):
120991 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
120992 + return 0;
120993 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
120994 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
120995 + return 0;
120996 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
120997 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
120998 + return 0;
120999 + case (e_FM_COUNTERS_DEQ_FROM_FD):
121000 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
121001 + return 0;
121002 + case (e_FM_COUNTERS_DEQ_CONFIRM):
121003 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
121004 + return 0;
121005 + }
121006 + /* should never get here */
121007 + return -EINVAL; /* counter not available */
121008 +}
121009 --- /dev/null
121010 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
121011 @@ -0,0 +1,136 @@
121012 +/*
121013 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121014 + *
121015 + * Redistribution and use in source and binary forms, with or without
121016 + * modification, are permitted provided that the following conditions are met:
121017 + * * Redistributions of source code must retain the above copyright
121018 + * notice, this list of conditions and the following disclaimer.
121019 + * * Redistributions in binary form must reproduce the above copyright
121020 + * notice, this list of conditions and the following disclaimer in the
121021 + * documentation and/or other materials provided with the distribution.
121022 + * * Neither the name of Freescale Semiconductor nor the
121023 + * names of its contributors may be used to endorse or promote products
121024 + * derived from this software without specific prior written permission.
121025 + *
121026 + *
121027 + * ALTERNATIVELY, this software may be distributed under the terms of the
121028 + * GNU General Public License ("GPL") as published by the Free Software
121029 + * Foundation, either version 2 of that License or (at your option) any
121030 + * later version.
121031 + *
121032 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121033 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121034 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121035 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121036 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121037 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121038 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121039 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121040 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121041 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121042 + */
121043 +
121044 +
121045 +#ifndef LNXWRP_SYSFS_FM_H_
121046 +#define LNXWRP_SYSFS_FM_H_
121047 +
121048 +#include "lnxwrp_sysfs.h"
121049 +
121050 +int fm_sysfs_create(struct device *dev);
121051 +void fm_sysfs_destroy(struct device *dev);
121052 +int fm_dump_regs(void *h_dev, char *buf, int nn);
121053 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
121054 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
121055 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
121056 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
121057 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
121058 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
121059 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
121060 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
121061 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
121062 +
121063 +#define FM_DMP_PGSZ_ERR { \
121064 + snprintf(&buf[PAGE_SIZE - 80], 70, \
121065 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
121066 + n = PAGE_SIZE - 2; \
121067 + }
121068 +
121069 +#define FM_DMP_LN(buf, n, ...) \
121070 + do { \
121071 + int k, m = n; \
121072 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121073 + if (k < 0 || m > PAGE_SIZE - 90) \
121074 + FM_DMP_PGSZ_ERR \
121075 + n = m; \
121076 + } while (0)
121077 +
121078 +#define FM_DMP_TITLE(buf, n, addr, ...) \
121079 + do { \
121080 + int k, m = n; \
121081 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121082 + if (k < 0 || m > PAGE_SIZE - 90) \
121083 + FM_DMP_PGSZ_ERR \
121084 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121085 + if (k < 0 || m > PAGE_SIZE - 90) \
121086 + FM_DMP_PGSZ_ERR \
121087 + if (addr) { \
121088 + phys_addr_t pa; \
121089 + pa = virt_to_phys(addr); \
121090 + m += k = \
121091 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
121092 + (long unsigned int)(pa)); \
121093 + if (k < 0 || m > PAGE_SIZE - 90) \
121094 + FM_DMP_PGSZ_ERR \
121095 + } \
121096 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
121097 + "\n----------------------------------------\n\n"); \
121098 + if (k < 0 || m > PAGE_SIZE - 90) \
121099 + FM_DMP_PGSZ_ERR \
121100 + n = m; \
121101 + } while (0)
121102 +
121103 +#define FM_DMP_SUBTITLE(buf, n, ...) \
121104 + do { \
121105 + int k, m = n; \
121106 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
121107 + if (k < 0 || m > PAGE_SIZE - 90) \
121108 + FM_DMP_PGSZ_ERR \
121109 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
121110 + if (k < 0 || m > PAGE_SIZE - 90) \
121111 + FM_DMP_PGSZ_ERR \
121112 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
121113 + if (k < 0 || m > PAGE_SIZE - 90) \
121114 + FM_DMP_PGSZ_ERR \
121115 + n = m; \
121116 + } while (0)
121117 +
121118 +#define FM_DMP_MEM_32(buf, n, addr) \
121119 + { \
121120 + uint32_t val; \
121121 + phys_addr_t pa; \
121122 + int k, m = n; \
121123 + pa = virt_to_phys(addr); \
121124 + val = ioread32be((addr)); \
121125 + do { \
121126 + m += k = snprintf(&buf[m], \
121127 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
121128 + pa, val); \
121129 + if (k < 0 || m > PAGE_SIZE - 90) \
121130 + FM_DMP_PGSZ_ERR \
121131 + n += k; \
121132 + } while (0) ;\
121133 + }
121134 +
121135 +#define FM_DMP_V32(buf, n, st, phrase) \
121136 + do { \
121137 + int k, m = n; \
121138 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
121139 + k = snprintf(&buf[m], PAGE_SIZE - m, \
121140 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
121141 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
121142 + if (k < 0 || m > PAGE_SIZE - 90) \
121143 + FM_DMP_PGSZ_ERR \
121144 + n += k; \
121145 + } while (0)
121146 +
121147 +#endif /* LNXWRP_SYSFS_FM_H_ */
121148 --- /dev/null
121149 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
121150 @@ -0,0 +1,1268 @@
121151 +/*
121152 + * Copyright 2008-2012 Freescale Semiconductor Inc.
121153 + *
121154 + * Redistribution and use in source and binary forms, with or without
121155 + * modification, are permitted provided that the following conditions are met:
121156 + * * Redistributions of source code must retain the above copyright
121157 + * notice, this list of conditions and the following disclaimer.
121158 + * * Redistributions in binary form must reproduce the above copyright
121159 + * notice, this list of conditions and the following disclaimer in the
121160 + * documentation and/or other materials provided with the distribution.
121161 + * * Neither the name of Freescale Semiconductor nor the
121162 + * names of its contributors may be used to endorse or promote products
121163 + * derived from this software without specific prior written permission.
121164 + *
121165 + *
121166 + * ALTERNATIVELY, this software may be distributed under the terms of the
121167 + * GNU General Public License ("GPL") as published by the Free Software
121168 + * Foundation, either version 2 of that License or (at your option) any
121169 + * later version.
121170 + *
121171 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
121172 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
121173 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
121174 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
121175 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
121176 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
121177 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
121178 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
121179 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
121180 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
121181 + */
121182 +
121183 +#include "lnxwrp_sysfs.h"
121184 +#include "lnxwrp_fm.h"
121185 +#include "debug_ext.h"
121186 +#include "lnxwrp_sysfs_fm_port.h"
121187 +#include "lnxwrp_sysfs_fm.h"
121188 +
121189 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
121190 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
121191 +
121192 +#if defined(__ERR_MODULE__)
121193 +#undef __ERR_MODULE__
121194 +#endif
121195 +
121196 +#include "../../sdk_fman/Peripherals/FM/fm.h"
121197 +
121198 +static const struct sysfs_stats_t portSysfsStats[] = {
121199 + /* RX/TX/OH common statistics */
121200 + {
121201 + .stat_name = "port_frame",
121202 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
121203 + },
121204 + {
121205 + .stat_name = "port_discard_frame",
121206 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
121207 + },
121208 + {
121209 + .stat_name = "port_dealloc_buf",
121210 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
121211 + },
121212 + {
121213 + .stat_name = "port_enq_total",
121214 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
121215 + },
121216 + /* TX/OH */
121217 + {
121218 + .stat_name = "port_length_err",
121219 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
121220 + },
121221 + {
121222 + .stat_name = "port_unsupprted_format",
121223 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
121224 + },
121225 + {
121226 + .stat_name = "port_deq_total",
121227 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
121228 + },
121229 + {
121230 + .stat_name = "port_deq_from_default",
121231 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
121232 + },
121233 + {
121234 + .stat_name = "port_deq_confirm",
121235 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
121236 + },
121237 + /* RX/OH */
121238 + {
121239 + .stat_name = "port_rx_bad_frame",
121240 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
121241 + },
121242 + {
121243 + .stat_name = "port_rx_large_frame",
121244 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
121245 + },
121246 + {
121247 + .stat_name = "port_rx_out_of_buffers_discard",
121248 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
121249 + },
121250 + {
121251 + .stat_name = "port_rx_filter_frame",
121252 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
121253 + },
121254 + /* TODO: Particular statistics for OH ports */
121255 + {}
121256 +};
121257 +
121258 +static ssize_t show_fm_port_stats(struct device *dev,
121259 + struct device_attribute *attr, char *buf)
121260 +{
121261 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121262 + t_LnxWrpFmDev *p_LnxWrpFmDev;
121263 + unsigned long flags;
121264 + int n = 0;
121265 + uint8_t counter = 0;
121266 +
121267 + if (attr == NULL || buf == NULL || dev == NULL)
121268 + return -EINVAL;
121269 +
121270 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121271 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121272 + return -EINVAL;
121273 +
121274 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
121275 + if (WARN_ON(p_LnxWrpFmDev == NULL))
121276 + return -EINVAL;
121277 +
121278 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
121279 + return -EIO;
121280 +
121281 + if (!p_LnxWrpFmPortDev->h_Dev) {
121282 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121283 + return n;
121284 + }
121285 +
121286 + counter = fm_find_statistic_counter_by_name(
121287 + attr->attr.name,
121288 + portSysfsStats, NULL);
121289 +
121290 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
121291 + uint32_t fmRev = 0;
121292 + fmRev = 0xffff &
121293 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
121294 + 0x000c30c4));
121295 +
121296 + if (fmRev == 0x0100) {
121297 + local_irq_save(flags);
121298 + n = snprintf(buf, PAGE_SIZE,
121299 + "counter not available for revision 1\n");
121300 + local_irq_restore(flags);
121301 + }
121302 + return n;
121303 + }
121304 +
121305 + local_irq_save(flags);
121306 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
121307 + p_LnxWrpFmPortDev->name,
121308 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
121309 + (e_FmPortCounters) counter));
121310 + local_irq_restore(flags);
121311 +
121312 + return n;
121313 +}
121314 +
121315 +/* FM PORT RX/TX/OH statistics */
121316 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
121317 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
121318 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
121319 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
121320 +/* FM PORT TX/OH statistics */
121321 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
121322 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
121323 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
121324 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
121325 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
121326 +/* FM PORT RX/OH statistics */
121327 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
121328 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
121329 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
121330 + show_fm_port_stats, NULL);
121331 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
121332 +
121333 +/* FM PORT TX statistics */
121334 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
121335 + &dev_attr_port_frame.attr,
121336 + &dev_attr_port_discard_frame.attr,
121337 + &dev_attr_port_dealloc_buf.attr,
121338 + &dev_attr_port_enq_total.attr,
121339 + &dev_attr_port_length_err.attr,
121340 + &dev_attr_port_unsupprted_format.attr,
121341 + &dev_attr_port_deq_total.attr,
121342 + &dev_attr_port_deq_from_default.attr,
121343 + &dev_attr_port_deq_confirm.attr,
121344 + NULL
121345 +};
121346 +
121347 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
121348 + .name = "statistics",
121349 + .attrs = fm_tx_port_dev_stats_attributes
121350 +};
121351 +
121352 +/* FM PORT RX statistics */
121353 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
121354 + &dev_attr_port_frame.attr,
121355 + &dev_attr_port_discard_frame.attr,
121356 + &dev_attr_port_dealloc_buf.attr,
121357 + &dev_attr_port_enq_total.attr,
121358 + &dev_attr_port_rx_bad_frame.attr,
121359 + &dev_attr_port_rx_large_frame.attr,
121360 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121361 + &dev_attr_port_rx_filter_frame.attr,
121362 + NULL
121363 +};
121364 +
121365 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
121366 + .name = "statistics",
121367 + .attrs = fm_rx_port_dev_stats_attributes
121368 +};
121369 +
121370 +/* TODO: add particular OH ports statistics */
121371 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
121372 + &dev_attr_port_frame.attr,
121373 + &dev_attr_port_discard_frame.attr,
121374 + &dev_attr_port_dealloc_buf.attr,
121375 + &dev_attr_port_enq_total.attr,
121376 + /*TX*/ &dev_attr_port_length_err.attr,
121377 + &dev_attr_port_unsupprted_format.attr,
121378 + &dev_attr_port_deq_total.attr,
121379 + &dev_attr_port_deq_from_default.attr,
121380 + &dev_attr_port_deq_confirm.attr,
121381 + /* &dev_attr_port_rx_bad_frame.attr, */
121382 + /* &dev_attr_port_rx_large_frame.attr, */
121383 + &dev_attr_port_rx_out_of_buffers_discard.attr,
121384 + /*&dev_attr_port_rx_filter_frame.attr, */
121385 + NULL
121386 +};
121387 +
121388 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
121389 + .name = "statistics",
121390 + .attrs = fm_oh_port_dev_stats_attributes
121391 +};
121392 +
121393 +static ssize_t show_fm_port_regs(struct device *dev,
121394 + struct device_attribute *attr, char *buf)
121395 +{
121396 + unsigned long flags;
121397 + unsigned n = 0;
121398 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121399 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121400 +#endif
121401 + if (attr == NULL || buf == NULL || dev == NULL)
121402 + return -EINVAL;
121403 +
121404 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121405 + p_LnxWrpFmPortDev =
121406 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121407 +
121408 +
121409 + local_irq_save(flags);
121410 +
121411 + if (!p_LnxWrpFmPortDev->h_Dev) {
121412 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121413 + return n;
121414 + } else {
121415 + n = snprintf(buf, PAGE_SIZE,
121416 + "FM port driver registers dump.\n");
121417 + n = fm_port_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121418 + }
121419 +
121420 + local_irq_restore(flags);
121421 +
121422 + return n;
121423 +#else
121424 +
121425 + local_irq_save(flags);
121426 + n = snprintf(buf, PAGE_SIZE,
121427 + "Debug level is too low to dump registers!!!\n");
121428 + local_irq_restore(flags);
121429 +
121430 + return n;
121431 +#endif
121432 +}
121433 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
121434 +{
121435 + t_FmPort *p_FmPort;
121436 + t_Fm *p_Fm;
121437 + uint8_t hardwarePortId;
121438 + uint32_t *param_page;
121439 + t_ArCommonDesc *ArCommonDescPtr;
121440 + uint32_t *mem;
121441 + int i, n = nn;
121442 +
121443 + p_FmPort = (t_FmPort *)h_dev;
121444 + hardwarePortId = p_FmPort->hardwarePortId;
121445 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121446 +
121447 + if (!FM_PORT_IsInDsar(p_FmPort))
121448 + {
121449 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121450 + hardwarePortId);
121451 + return n;
121452 + }
121453 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
121454 + FM_DMP_LN(buf, n, "========================\n");
121455 +
121456 + /* do I need request_mem_region here? */
121457 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121458 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
121459 + mem = (uint32_t*)ArCommonDescPtr;
121460 + for (i = 0; i < 300; i+=4)
121461 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
121462 + iounmap(ArCommonDescPtr);
121463 + iounmap(param_page);
121464 + return n;
121465 +}
121466 +
121467 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
121468 +{
121469 + t_FmPort *p_FmPort;
121470 + t_Fm *p_Fm;
121471 + uint8_t hardwarePortId;
121472 + uint32_t *param_page;
121473 + t_ArCommonDesc *ArCommonDescPtr;
121474 + int i, n = nn;
121475 +
121476 + p_FmPort = (t_FmPort *)h_dev;
121477 + hardwarePortId = p_FmPort->hardwarePortId;
121478 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
121479 +
121480 + if (!FM_PORT_IsInDsar(p_FmPort))
121481 + {
121482 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
121483 + hardwarePortId);
121484 + return n;
121485 + }
121486 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
121487 + FM_DMP_LN(buf, n, "========================\n");
121488 +
121489 + /* do I need request_mem_region here? */
121490 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
121491 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
121492 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
121493 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
121494 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
121495 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
121496 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
121497 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
121498 + ArCommonDescPtr->macStationAddr[5]);
121499 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
121500 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
121501 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
121502 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
121503 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
121504 + if (ArCommonDescPtr->p_ArStats)
121505 + {
121506 + t_ArStatistics *arStatistics = (t_ArStatistics*)
121507 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
121508 + p_FmPort->fmMuramPhysBaseAddr,
121509 + sizeof (t_ArStatistics));
121510 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
121511 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
121512 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
121513 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
121514 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
121515 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
121516 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
121517 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
121518 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
121519 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
121520 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
121521 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
121522 +
121523 + iounmap(arStatistics);
121524 + }
121525 + if (ArCommonDescPtr->p_ArpDescriptor)
121526 + {
121527 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
121528 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
121529 + p_FmPort->fmMuramPhysBaseAddr,
121530 + sizeof (t_DsarArpDescriptor));
121531 + FM_DMP_LN(buf, n, "\nARP\n");
121532 + FM_DMP_LN(buf, n, "===\n");
121533 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
121534 + if (ArpDescriptor->numOfBindings)
121535 + {
121536 + char ip_str[100];
121537 + t_DsarArpBindingEntry* bindings = ioremap(
121538 + ioread32be(&ArpDescriptor->p_Bindings) +
121539 + p_FmPort->fmMuramPhysBaseAddr,
121540 + ArpDescriptor->numOfBindings *
121541 + sizeof(t_DsarArpBindingEntry));
121542 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121543 + FM_DMP_LN(buf, n, " ip vlan id\n");
121544 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
121545 + {
121546 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121547 + ip_addr[0], ip_addr[1],
121548 + ip_addr[2], ip_addr[3]);
121549 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121550 + ip_str, bindings->vlanId);
121551 + }
121552 + iounmap(bindings);
121553 + }
121554 + if (ArpDescriptor->p_Statistics)
121555 + {
121556 + t_DsarArpStatistics* arpStats = ioremap(
121557 + ioread32be(&ArpDescriptor->p_Statistics) +
121558 + p_FmPort->fmMuramPhysBaseAddr,
121559 + sizeof(t_DsarArpStatistics));
121560 + FM_DMP_LN(buf, n, "statistics\n");
121561 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
121562 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
121563 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
121564 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
121565 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
121566 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
121567 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
121568 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
121569 + iounmap(arpStats);
121570 + }
121571 +
121572 + iounmap(ArpDescriptor);
121573 + }
121574 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
121575 + {
121576 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
121577 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
121578 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
121579 + p_FmPort->fmMuramPhysBaseAddr,
121580 + sizeof (t_DsarIcmpV4Descriptor));
121581 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
121582 + FM_DMP_LN(buf, n, "===========\n");
121583 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
121584 + if (ICMPV4Descriptor->numOfBindings)
121585 + {
121586 + char ip_str[100];
121587 + t_DsarArpBindingEntry* bindings = ioremap(
121588 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
121589 + p_FmPort->fmMuramPhysBaseAddr,
121590 + ICMPV4Descriptor->numOfBindings *
121591 + sizeof(t_DsarArpBindingEntry));
121592 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
121593 + FM_DMP_LN(buf, n, " ip vlan id\n");
121594 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
121595 + {
121596 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121597 + ip_addr[0], ip_addr[1],
121598 + ip_addr[2], ip_addr[3]);
121599 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
121600 + ip_str, bindings->vlanId);
121601 + }
121602 + iounmap(bindings);
121603 + }
121604 + if (ICMPV4Descriptor->p_Statistics)
121605 + {
121606 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
121607 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
121608 + p_FmPort->fmMuramPhysBaseAddr,
121609 + sizeof(t_DsarIcmpV4Statistics));
121610 + FM_DMP_LN(buf, n, "statistics\n");
121611 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
121612 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
121613 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
121614 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
121615 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
121616 + iounmap(icmpv4Stats);
121617 + }
121618 + iounmap(ICMPV4Descriptor);
121619 + }
121620 + if (ArCommonDescPtr->p_NdDescriptor)
121621 + {
121622 + t_DsarNdDescriptor *NDDescriptor =
121623 + (t_DsarNdDescriptor*)ioremap(ioread32be(
121624 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
121625 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
121626 + FM_DMP_LN(buf, n, "\nNDP\n");
121627 + FM_DMP_LN(buf, n, "===\n");
121628 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
121629 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
121630 + if (NDDescriptor->numOfBindings)
121631 + {
121632 + char ip_str[100];
121633 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121634 + ioread32be(&NDDescriptor->p_Bindings) +
121635 + p_FmPort->fmMuramPhysBaseAddr,
121636 + NDDescriptor->numOfBindings *
121637 + sizeof(t_DsarIcmpV6BindingEntry));
121638 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121639 + FM_DMP_LN(buf, n, " ip vlan id\n");
121640 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
121641 + {
121642 + n += snprintf(ip_str, 100,
121643 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121644 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121645 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121646 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121647 + }
121648 + iounmap(bindings);
121649 + }
121650 + if (NDDescriptor->p_Statistics)
121651 + {
121652 + t_NdStatistics* ndStats = ioremap(
121653 + ioread32be(&NDDescriptor->p_Statistics) +
121654 + p_FmPort->fmMuramPhysBaseAddr,
121655 + sizeof(t_NdStatistics));
121656 + FM_DMP_LN(buf, n, "statistics\n");
121657 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
121658 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
121659 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
121660 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
121661 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
121662 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
121663 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
121664 + iounmap(ndStats);
121665 + }
121666 + iounmap(NDDescriptor);
121667 + }
121668 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
121669 + {
121670 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
121671 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
121672 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
121673 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
121674 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
121675 + FM_DMP_LN(buf, n, "===========\n");
121676 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
121677 + if (ICMPV6Descriptor->numOfBindings)
121678 + {
121679 + char ip_str[100];
121680 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
121681 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
121682 + p_FmPort->fmMuramPhysBaseAddr,
121683 + ICMPV6Descriptor->numOfBindings *
121684 + sizeof(t_DsarIcmpV6BindingEntry));
121685 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
121686 + FM_DMP_LN(buf, n, " ip vlan id\n");
121687 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
121688 + {
121689 + n += snprintf(ip_str, 100,
121690 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
121691 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
121692 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
121693 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
121694 + }
121695 + iounmap(bindings);
121696 + }
121697 + if (ICMPV6Descriptor->p_Statistics)
121698 + {
121699 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
121700 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
121701 + p_FmPort->fmMuramPhysBaseAddr,
121702 + sizeof(t_DsarIcmpV6Statistics));
121703 + FM_DMP_LN(buf, n, "statistics\n");
121704 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
121705 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
121706 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
121707 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
121708 + iounmap(icmpv6Stats);
121709 + }
121710 + iounmap(ICMPV6Descriptor);
121711 + }
121712 + if (ArCommonDescPtr->p_SnmpDescriptor)
121713 + {
121714 + t_DsarSnmpDescriptor *SnmpDescriptor =
121715 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
121716 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
121717 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
121718 + FM_DMP_LN(buf, n, "\nSNMP\n");
121719 + FM_DMP_LN(buf, n, "===========\n");
121720 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
121721 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
121722 + if (SnmpDescriptor->numOfIpv4Addresses)
121723 + {
121724 + char ip_str[100];
121725 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
121726 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
121727 + p_FmPort->fmMuramPhysBaseAddr,
121728 + SnmpDescriptor->numOfIpv4Addresses *
121729 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
121730 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
121731 + FM_DMP_LN(buf, n, " ip vlan id\n");
121732 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
121733 + {
121734 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
121735 + ip_addr[0], ip_addr[1],
121736 + ip_addr[2], ip_addr[3]);
121737 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
121738 + }
121739 + iounmap(addrs);
121740 + }
121741 + if (SnmpDescriptor->p_Statistics)
121742 + {
121743 + t_DsarSnmpStatistics* snmpStats = ioremap(
121744 + ioread32be(&SnmpDescriptor->p_Statistics) +
121745 + p_FmPort->fmMuramPhysBaseAddr,
121746 + sizeof(t_DsarSnmpStatistics));
121747 + FM_DMP_LN(buf, n, "statistics\n");
121748 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
121749 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
121750 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
121751 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
121752 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
121753 + iounmap(snmpStats);
121754 + }
121755 + iounmap(SnmpDescriptor);
121756 + }
121757 + iounmap(ArCommonDescPtr);
121758 + iounmap(param_page);
121759 + return n;
121760 +}
121761 +
121762 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
121763 + struct device_attribute *attr, char *buf)
121764 +{
121765 + unsigned long flags;
121766 + unsigned n = 0;
121767 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121768 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121769 +#endif
121770 + if (attr == NULL || buf == NULL || dev == NULL)
121771 + return -EINVAL;
121772 +
121773 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121774 + p_LnxWrpFmPortDev =
121775 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121776 +
121777 + local_irq_save(flags);
121778 +
121779 + if (!p_LnxWrpFmPortDev->h_Dev) {
121780 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121781 + return n;
121782 + } else {
121783 + n = snprintf(buf, PAGE_SIZE,
121784 + "FM port driver registers dump.\n");
121785 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
121786 + }
121787 +
121788 + local_irq_restore(flags);
121789 +
121790 + return n;
121791 +#else
121792 +
121793 + local_irq_save(flags);
121794 + n = snprintf(buf, PAGE_SIZE,
121795 + "Debug level is too low to dump registers!!!\n");
121796 + local_irq_restore(flags);
121797 +
121798 + return n;
121799 +#endif
121800 +}
121801 +
121802 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
121803 + struct device_attribute *attr, char *buf)
121804 +{
121805 + unsigned long flags;
121806 + unsigned n = 0;
121807 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121808 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121809 +#endif
121810 + if (attr == NULL || buf == NULL || dev == NULL)
121811 + return -EINVAL;
121812 +
121813 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121814 + p_LnxWrpFmPortDev =
121815 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121816 +
121817 + local_irq_save(flags);
121818 +
121819 + if (!p_LnxWrpFmPortDev->h_Dev) {
121820 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121821 + return n;
121822 + } else {
121823 + n = snprintf(buf, PAGE_SIZE,
121824 + "FM port driver registers dump.\n");
121825 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
121826 + }
121827 +
121828 + local_irq_restore(flags);
121829 +
121830 + return n;
121831 +#else
121832 +
121833 + local_irq_save(flags);
121834 + n = snprintf(buf, PAGE_SIZE,
121835 + "Debug level is too low to dump registers!!!\n");
121836 + local_irq_restore(flags);
121837 +
121838 + return n;
121839 +#endif
121840 +}
121841 +
121842 +#if (DPAA_VERSION >= 11)
121843 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
121844 + struct device_attribute *attr, char *buf)
121845 +{
121846 + unsigned long flags;
121847 + unsigned n = 0;
121848 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121849 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121850 +#endif
121851 +
121852 + if (attr == NULL || buf == NULL || dev == NULL)
121853 + return -EINVAL;
121854 +
121855 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121856 + p_LnxWrpFmPortDev =
121857 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121858 +
121859 + local_irq_save(flags);
121860 +
121861 + if (!p_LnxWrpFmPortDev->h_Dev) {
121862 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121863 + return n;
121864 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
121865 + == NULL) {
121866 + n = snprintf(buf, PAGE_SIZE,
121867 + "\tPort: FMan-controller params page not set\n");
121868 + return n;
121869 + } else {
121870 + n = snprintf(buf, PAGE_SIZE,
121871 + "Counter for fragmented pkt with IP header options\n");
121872 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
121873 + }
121874 +
121875 + local_irq_restore(flags);
121876 +
121877 + return n;
121878 +#else
121879 +
121880 + local_irq_save(flags);
121881 + n = snprintf(buf, PAGE_SIZE,
121882 + "Debug level is too low to dump registers!!!\n");
121883 + local_irq_restore(flags);
121884 +
121885 + return n;
121886 +#endif
121887 +}
121888 +
121889 +#endif
121890 +
121891 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
121892 + struct device_attribute *attr, char *buf)
121893 +{
121894 + unsigned long flags;
121895 + unsigned n = 0;
121896 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121897 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121898 +#endif
121899 +
121900 + if (attr == NULL || buf == NULL || dev == NULL)
121901 + return -EINVAL;
121902 +
121903 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121904 + p_LnxWrpFmPortDev =
121905 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121906 +
121907 + local_irq_save(flags);
121908 +
121909 + if (!p_LnxWrpFmPortDev->h_Dev) {
121910 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121911 + return n;
121912 + } else {
121913 + n = snprintf(buf, PAGE_SIZE,
121914 + "FM port driver registers dump.\n");
121915 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121916 + }
121917 +
121918 + local_irq_restore(flags);
121919 +
121920 + return n;
121921 +#else
121922 +
121923 + local_irq_save(flags);
121924 + n = snprintf(buf, PAGE_SIZE,
121925 + "Debug level is too low to dump registers!!!\n");
121926 + local_irq_restore(flags);
121927 +
121928 + return n;
121929 +#endif
121930 +}
121931 +
121932 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
121933 + struct device_attribute *attr, char *buf)
121934 +{
121935 + unsigned long flags;
121936 + unsigned n = 0;
121937 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121938 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121939 +#endif
121940 +
121941 + if (attr == NULL || buf == NULL || dev == NULL)
121942 + return -EINVAL;
121943 +
121944 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121945 + p_LnxWrpFmPortDev =
121946 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121947 +
121948 + local_irq_save(flags);
121949 +
121950 + if (!p_LnxWrpFmPortDev->h_Dev) {
121951 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
121952 + return n;
121953 + } else {
121954 + n = snprintf(buf, PAGE_SIZE,
121955 + "FM port driver registers dump.\n");
121956 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
121957 + }
121958 +
121959 + local_irq_restore(flags);
121960 +
121961 + return n;
121962 +#else
121963 +
121964 + local_irq_save(flags);
121965 + n = snprintf(buf, PAGE_SIZE,
121966 + "Debug level is too low to dump registers!!!\n");
121967 + local_irq_restore(flags);
121968 +
121969 + return n;
121970 +#endif
121971 +}
121972 +
121973 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
121974 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
121975 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
121976 +#if (DPAA_VERSION >= 11)
121977 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
121978 +#endif
121979 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
121980 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
121981 +
121982 +int fm_port_sysfs_create(struct device *dev)
121983 +{
121984 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
121985 +
121986 + if (dev == NULL)
121987 + return -EINVAL;
121988 +
121989 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
121990 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
121991 + return -EINVAL;
121992 +
121993 + /* store to remove them when module is disabled */
121994 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
121995 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
121996 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
121997 +#if (DPAA_VERSION >= 11)
121998 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
121999 +#endif
122000 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
122001 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
122002 + /* Registers dump entry - in future will be moved to debugfs */
122003 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
122004 + return -EIO;
122005 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
122006 + return -EIO;
122007 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
122008 + return -EIO;
122009 +#if (DPAA_VERSION >= 11)
122010 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
122011 + return -EIO;
122012 +#endif
122013 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
122014 + return -EIO;
122015 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
122016 + return -EIO;
122017 +
122018 + /* FM Ports statistics */
122019 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122020 + case e_FM_PORT_TYPE_TX:
122021 + case e_FM_PORT_TYPE_TX_10G:
122022 + if (sysfs_create_group
122023 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
122024 + return -EIO;
122025 + break;
122026 + case e_FM_PORT_TYPE_RX:
122027 + case e_FM_PORT_TYPE_RX_10G:
122028 + if (sysfs_create_group
122029 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
122030 + return -EIO;
122031 + break;
122032 + case e_FM_PORT_TYPE_DUMMY:
122033 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122034 + if (sysfs_create_group
122035 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
122036 + return -EIO;
122037 + break;
122038 + default:
122039 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122040 + __func__);
122041 + return -EINVAL;
122042 + break;
122043 + };
122044 +
122045 + return 0;
122046 +}
122047 +
122048 +void fm_port_sysfs_destroy(struct device *dev)
122049 +{
122050 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
122051 +
122052 + /* this function has never been tested !!! */
122053 +
122054 + if (WARN_ON(dev == NULL))
122055 + return;
122056 +
122057 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122058 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122059 + return;
122060 +
122061 + /* The name attribute will be freed also by these 2 functions? */
122062 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
122063 + case e_FM_PORT_TYPE_TX:
122064 + case e_FM_PORT_TYPE_TX_10G:
122065 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
122066 + break;
122067 + case e_FM_PORT_TYPE_RX:
122068 + case e_FM_PORT_TYPE_RX_10G:
122069 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
122070 + break;
122071 + case e_FM_PORT_TYPE_DUMMY:
122072 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
122073 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
122074 + break;
122075 + default:
122076 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
122077 + __func__);
122078 + break;
122079 + };
122080 +
122081 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
122082 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
122083 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
122084 +#if (DPAA_VERSION >= 11)
122085 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
122086 +#endif
122087 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
122088 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
122089 +}
122090 +
122091 +
122092 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
122093 +{
122094 + t_FmPort *p_FmPort;
122095 + t_Fm *p_Fm;
122096 + uint8_t hardwarePortId;
122097 + int n = nn;
122098 +
122099 + p_FmPort = (t_FmPort *)h_dev;
122100 + hardwarePortId = p_FmPort->hardwarePortId;
122101 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
122102 +
122103 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
122104 + "fmbm_pp for port %u", hardwarePortId);
122105 + FM_DMP_MEM_32(buf, n,
122106 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
122107 +
122108 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
122109 + "fmbm_pfs for port %u", hardwarePortId);
122110 + FM_DMP_MEM_32(buf, n,
122111 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
122112 +
122113 + FM_DMP_TITLE(buf, n,
122114 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
122115 + "fmbm_spliodn for port %u", hardwarePortId);
122116 + FM_DMP_MEM_32(buf, n,
122117 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
122118 +
122119 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
122120 + "fmfp_psfor port %u", hardwarePortId);
122121 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
122122 +
122123 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
122124 + "fmdmplrfor port %u", hardwarePortId);
122125 + FM_DMP_MEM_32(buf, n,
122126 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
122127 + return n;
122128 +}
122129 +
122130 +#if (DPAA_VERSION >= 11)
122131 +
122132 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
122133 +{
122134 + t_FmPort *p_FmPort;
122135 + int n = nn;
122136 +
122137 + p_FmPort = (t_FmPort *)h_dev;
122138 +
122139 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
122140 +
122141 + FM_DMP_SUBTITLE(buf, n, "\n");
122142 +
122143 + return n;
122144 +}
122145 +#endif
122146 +
122147 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
122148 +{
122149 + t_FmPort *p_FmPort;
122150 + u_FmPortBmiRegs *p_bmi;
122151 +
122152 + char arr[20];
122153 + uint8_t flag;
122154 + int i = 0;
122155 + int n = nn;
122156 +
122157 + p_FmPort = (t_FmPort *)h_dev;
122158 + p_bmi = p_FmPort->p_FmPortBmiRegs;
122159 +
122160 + memset(arr, 0, sizeof(arr));
122161 + switch (p_FmPort->portType) {
122162 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
122163 + strcpy(arr, "OFFLINE-PARSING");
122164 + flag = 0;
122165 + break;
122166 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
122167 + strcpy(arr, "HOST-COMMAND");
122168 + flag = 0;
122169 + break;
122170 + case (e_FM_PORT_TYPE_RX):
122171 + strcpy(arr, "RX");
122172 + flag = 1;
122173 + break;
122174 + case (e_FM_PORT_TYPE_RX_10G):
122175 + strcpy(arr, "RX-10G");
122176 + flag = 1;
122177 + break;
122178 + case (e_FM_PORT_TYPE_TX):
122179 + strcpy(arr, "TX");
122180 + flag = 2;
122181 + break;
122182 + case (e_FM_PORT_TYPE_TX_10G):
122183 + strcpy(arr, "TX-10G");
122184 + flag = 2;
122185 + break;
122186 + default:
122187 + return -EINVAL;
122188 + }
122189 +
122190 + FM_DMP_TITLE(buf, n, NULL,
122191 + "FMan-Port (%s #%d) registers:",
122192 + arr, p_FmPort->portId);
122193 +
122194 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
122195 +
122196 + switch (flag) {
122197 + case (0):
122198 + FM_DMP_SUBTITLE(buf, n, "\n");
122199 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
122200 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
122201 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
122202 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
122203 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
122204 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
122205 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
122206 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
122207 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
122208 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
122209 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
122210 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
122211 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
122212 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
122213 +
122214 + FM_DMP_TITLE(buf, n,
122215 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
122216 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122217 + FM_DMP_MEM_32(buf, n,
122218 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
122219 + }
122220 + FM_DMP_SUBTITLE(buf, n, "\n");
122221 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
122222 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
122223 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
122224 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
122225 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
122226 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
122227 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
122228 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
122229 + {
122230 +#ifndef FM_NO_OP_OBSERVED_POOLS
122231 + if (p_FmPort->fmRevInfo.majorRev == 4) {
122232 + FM_DMP_TITLE(buf, n,
122233 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
122234 + "fmbm_oebmpi");
122235 +
122236 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
122237 + FM_DMP_MEM_32(buf, n,
122238 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
122239 + }
122240 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
122241 + }
122242 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
122243 + }
122244 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
122245 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
122246 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
122247 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
122248 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
122249 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
122250 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
122251 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
122252 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
122253 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
122254 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
122255 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
122256 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
122257 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
122258 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
122259 + "fmbm_odcfg");
122260 + for (i = 0; i < 3; ++i) {
122261 + FM_DMP_MEM_32(buf, n,
122262 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
122263 + }
122264 + FM_DMP_SUBTITLE(buf, n, "\n");
122265 +
122266 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
122267 + break;
122268 + case (1):
122269 + FM_DMP_SUBTITLE(buf, n, "\n");
122270 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
122271 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
122272 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
122273 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
122274 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
122275 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
122276 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
122277 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
122278 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
122279 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
122280 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
122281 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
122282 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
122283 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
122284 + "fmbm_rprai");
122285 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
122286 + FM_DMP_MEM_32(buf, n,
122287 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
122288 + }
122289 + FM_DMP_SUBTITLE(buf, n, "\n");
122290 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
122291 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
122292 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
122293 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
122294 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
122295 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
122296 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
122297 + "fmbm_ebmpi");
122298 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122299 + FM_DMP_MEM_32(buf, n,
122300 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
122301 + }
122302 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
122303 + "fmbm_acnt");
122304 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
122305 + FM_DMP_MEM_32(buf, n,
122306 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
122307 + }
122308 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
122309 + "fmbm_rcgm");
122310 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
122311 + FM_DMP_MEM_32(buf, n,
122312 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
122313 + }
122314 +
122315 + FM_DMP_SUBTITLE(buf, n, "\n");
122316 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
122317 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
122318 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
122319 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
122320 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
122321 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
122322 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
122323 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
122324 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
122325 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
122326 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
122327 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
122328 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
122329 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
122330 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
122331 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
122332 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
122333 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
122334 + "fmbm_rdcfg");
122335 + for (i = 0; i < 3; ++i) {
122336 + FM_DMP_MEM_32(buf, n,
122337 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
122338 + }
122339 + FM_DMP_SUBTITLE(buf, n, "\n");
122340 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
122341 + break;
122342 + case (2):
122343 + FM_DMP_SUBTITLE(buf, n, "\n");
122344 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
122345 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
122346 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
122347 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
122348 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
122349 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
122350 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
122351 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
122352 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
122353 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
122354 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
122355 +#if (DPAA_VERSION >= 11)
122356 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
122357 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
122358 +#endif /* (DPAA_VERSION >= 11) */
122359 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
122360 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
122361 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
122362 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
122363 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
122364 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
122365 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
122366 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
122367 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
122368 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
122369 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
122370 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
122371 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
122372 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
122373 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
122374 + "fmbm_tdcfg");
122375 + for (i = 0; i < 3 ; ++i) {
122376 + FM_DMP_MEM_32(buf, n,
122377 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
122378 + }
122379 + FM_DMP_SUBTITLE(buf, n, "\n");
122380 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
122381 + break;
122382 + }
122383 +
122384 + FM_DMP_SUBTITLE(buf, n, "\n");
122385 +
122386 + return n;
122387 +}
122388 +
122389 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
122390 +{
122391 + t_FmPort *p_FmPort;
122392 + int n = nn;
122393 +
122394 + p_FmPort = (t_FmPort *)h_dev;
122395 +
122396 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
122397 +
122398 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
122399 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
122400 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
122401 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
122402 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
122403 + FM_DMP_V32(buf, n,
122404 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
122405 + FM_DMP_V32(buf, n,
122406 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
122407 + FM_DMP_V32(buf, n,
122408 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
122409 + FM_DMP_V32(buf, n,
122410 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
122411 + FM_DMP_V32(buf, n,
122412 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
122413 +
122414 + FM_DMP_SUBTITLE(buf, n, "\n");
122415 +
122416 + return n;
122417 +}
122418 +
122419 --- /dev/null
122420 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
122421 @@ -0,0 +1,56 @@
122422 +/*
122423 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122424 + *
122425 + * Redistribution and use in source and binary forms, with or without
122426 + * modification, are permitted provided that the following conditions are met:
122427 + * * Redistributions of source code must retain the above copyright
122428 + * notice, this list of conditions and the following disclaimer.
122429 + * * Redistributions in binary form must reproduce the above copyright
122430 + * notice, this list of conditions and the following disclaimer in the
122431 + * documentation and/or other materials provided with the distribution.
122432 + * * Neither the name of Freescale Semiconductor nor the
122433 + * names of its contributors may be used to endorse or promote products
122434 + * derived from this software without specific prior written permission.
122435 + *
122436 + *
122437 + * ALTERNATIVELY, this software may be distributed under the terms of the
122438 + * GNU General Public License ("GPL") as published by the Free Software
122439 + * Foundation, either version 2 of that License or (at your option) any
122440 + * later version.
122441 + *
122442 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122443 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122444 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122445 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122446 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122447 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122448 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122449 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122450 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122451 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122452 + */
122453 +
122454 +/*
122455 + @File lnxwrp_sysfs_fm_port.h
122456 +
122457 + @Description FM port sysfs functions.
122458 +
122459 +*/
122460 +
122461 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
122462 +#define LNXWRP_SYSFS_FM_PORT_H_
122463 +
122464 +#include "lnxwrp_sysfs.h"
122465 +
122466 +int fm_port_sysfs_create(struct device *dev);
122467 +void fm_port_sysfs_destroy(struct device *dev);
122468 +
122469 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
122470 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
122471 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
122472 +
122473 +#if (DPAA_VERSION >= 11)
122474 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
122475 +#endif
122476 +
122477 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
122478 --- /dev/null
122479 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
122480 @@ -0,0 +1,18 @@
122481 +#
122482 +# Makefile for the Freescale Ethernet controllers
122483 +#
122484 +ccflags-y += -DVERSION=\"\"
122485 +#
122486 +#Include netcomm SW specific definitions
122487 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
122488 +
122489 +obj-y += fsl-ncsw-xx.o
122490 +
122491 +ifneq ($(CONFIG_FMAN_ARM),y)
122492 +fsl-ncsw-xx-objs := xx_linux.o \
122493 + module_strings.o
122494 +else
122495 +fsl-ncsw-xx-objs := xx_arm_linux.o \
122496 + module_strings.o
122497 +endif
122498 +
122499 --- /dev/null
122500 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
122501 @@ -0,0 +1,46 @@
122502 +/*
122503 + * Copyright 2012 Freescale Semiconductor Inc.
122504 + *
122505 + * Redistribution and use in source and binary forms, with or without
122506 + * modification, are permitted provided that the following conditions are met:
122507 + * * Redistributions of source code must retain the above copyright
122508 + * notice, this list of conditions and the following disclaimer.
122509 + * * Redistributions in binary form must reproduce the above copyright
122510 + * notice, this list of conditions and the following disclaimer in the
122511 + * documentation and/or other materials provided with the distribution.
122512 + * * Neither the name of Freescale Semiconductor nor the
122513 + * names of its contributors may be used to endorse or promote products
122514 + * derived from this software without specific prior written permission.
122515 + *
122516 + *
122517 + * ALTERNATIVELY, this software may be distributed under the terms of the
122518 + * GNU General Public License ("GPL") as published by the Free Software
122519 + * Foundation, either version 2 of that License or (at your option) any
122520 + * later version.
122521 + *
122522 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122523 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122524 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122525 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122526 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122527 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122528 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122529 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122530 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122531 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122532 + */
122533 +
122534 +/* Module names for debug messages */
122535 +const char *moduleStrings[] =
122536 +{
122537 + "", /* MODULE_UNKNOWN */
122538 + "FM", /* MODULE_FM */
122539 + "FM-MURAM", /* MODULE_FM_MURAM */
122540 + "FM-PCD", /* MODULE_FM_PCD */
122541 + "FM-RTC", /* MODULE_FM_RTC */
122542 + "FM-MAC", /* MODULE_FM_MAC */
122543 + "FM-Port", /* MODULE_FM_PORT */
122544 + "MM", /* MODULE_MM */
122545 + "FM-SP", /* MODULE_FM_SP */
122546 + "FM-MACSEC" /* MODULE_FM_MACSEC */
122547 +};
122548 --- /dev/null
122549 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
122550 @@ -0,0 +1,905 @@
122551 +/*
122552 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122553 + *
122554 + * Redistribution and use in source and binary forms, with or without
122555 + * modification, are permitted provided that the following conditions are met:
122556 + * * Redistributions of source code must retain the above copyright
122557 + * notice, this list of conditions and the following disclaimer.
122558 + * * Redistributions in binary form must reproduce the above copyright
122559 + * notice, this list of conditions and the following disclaimer in the
122560 + * documentation and/or other materials provided with the distribution.
122561 + * * Neither the name of Freescale Semiconductor nor the
122562 + * names of its contributors may be used to endorse or promote products
122563 + * derived from this software without specific prior written permission.
122564 + *
122565 + *
122566 + * ALTERNATIVELY, this software may be distributed under the terms of the
122567 + * GNU General Public License ("GPL") as published by the Free Software
122568 + * Foundation, either version 2 of that License or (at your option) any
122569 + * later version.
122570 + *
122571 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122572 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122573 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122574 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122575 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122576 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122577 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122578 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122579 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122580 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122581 + */
122582 +
122583 +/**************************************************************************//**
122584 + @File xx_arm_linux.c
122585 +
122586 + @Description XX routines implementation for Linux.
122587 +*//***************************************************************************/
122588 +#include <linux/version.h>
122589 +
122590 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
122591 +#define MODVERSIONS
122592 +#endif
122593 +#ifdef MODVERSIONS
122594 +#include <config/modversions.h>
122595 +#endif /* MODVERSIONS */
122596 +
122597 +#include <linux/module.h>
122598 +#include <linux/kernel.h>
122599 +#include <linux/sched.h>
122600 +#include <linux/string.h>
122601 +#include <linux/ptrace.h>
122602 +#include <linux/errno.h>
122603 +#include <linux/ioport.h>
122604 +#include <linux/slab.h>
122605 +#include <linux/interrupt.h>
122606 +#include <linux/fs.h>
122607 +#include <linux/vmalloc.h>
122608 +#include <linux/init.h>
122609 +#include <linux/timer.h>
122610 +#include <linux/spinlock.h>
122611 +#include <linux/delay.h>
122612 +#include <linux/proc_fs.h>
122613 +#include <linux/smp.h>
122614 +#include <linux/of.h>
122615 +#include <linux/irqdomain.h>
122616 +
122617 +#include <linux/workqueue.h>
122618 +
122619 +#ifdef BIGPHYSAREA_ENABLE
122620 +#include <linux/bigphysarea.h>
122621 +#endif /* BIGPHYSAREA_ENABLE */
122622 +
122623 +//#include <sysdev/fsl_soc.h>
122624 +#include <asm/pgtable.h>
122625 +#include <asm/irq.h>
122626 +#include <asm/bitops.h>
122627 +#include <asm/uaccess.h>
122628 +#include <asm/io.h>
122629 +#include <asm/atomic.h>
122630 +#include <asm/string.h>
122631 +#include <asm/byteorder.h>
122632 +#include <asm/page.h>
122633 +
122634 +#include "error_ext.h"
122635 +#include "std_ext.h"
122636 +#include "list_ext.h"
122637 +#include "mm_ext.h"
122638 +#include "sys_io_ext.h"
122639 +#include "xx.h"
122640 +
122641 +
122642 +#define __ERR_MODULE__ MODULE_UNKNOWN
122643 +
122644 +#ifdef BIGPHYSAREA_ENABLE
122645 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
122646 +
122647 +
122648 +/* TODO: large allocations => use big phys area */
122649 +/******************************************************************************
122650 + * routine: get_nr_pages
122651 + *
122652 + * description:
122653 + * calculates the number of memory pages for a given size (in bytes)
122654 + *
122655 + * arguments:
122656 + * size - the number of bytes
122657 + *
122658 + * return code:
122659 + * The number of pages
122660 + *
122661 + *****************************************************************************/
122662 +static __inline__ uint32_t get_nr_pages (uint32_t size)
122663 +{
122664 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
122665 +}
122666 +
122667 +static bool in_big_phys_area (uint32_t addr)
122668 +{
122669 + uint32_t base, size;
122670 +
122671 + bigphysarea_get_details (&base, &size);
122672 + return ((addr >= base) && (addr < base + size));
122673 +}
122674 +#endif /* BIGPHYSAREA_ENABLE */
122675 +
122676 +void * xx_Malloc(uint32_t n)
122677 +{
122678 + void *a;
122679 + uint32_t flags;
122680 +
122681 + flags = XX_DisableAllIntr();
122682 +#ifdef BIGPHYSAREA_ENABLE
122683 + if (n >= MAX_ALLOCATION_SIZE)
122684 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
122685 + else
122686 +#endif /* BIGPHYSAREA_ENABLE */
122687 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
122688 + if (!a)
122689 + XX_Print("No memory for XX_Malloc\n");
122690 + XX_RestoreAllIntr(flags);
122691 +
122692 + return a;
122693 +}
122694 +
122695 +void xx_Free(void *p)
122696 +{
122697 +#ifdef BIGPHYSAREA_ENABLE
122698 + if (in_big_phys_area ((uint32_t)p))
122699 + bigphysarea_free_pages(p);
122700 + else
122701 +#endif /* BIGPHYSAREA_ENABLE */
122702 + kfree(p);
122703 +}
122704 +
122705 +void XX_Exit(int status)
122706 +{
122707 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
122708 +}
122709 +
122710 +#define BUF_SIZE 512
122711 +void XX_Print(char *str, ...)
122712 +{
122713 + va_list args;
122714 +#ifdef CONFIG_SMP
122715 + char buf[BUF_SIZE];
122716 +#endif /* CONFIG_SMP */
122717 +
122718 + va_start(args, str);
122719 +#ifdef CONFIG_SMP
122720 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122721 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122722 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
122723 +#else
122724 + vprintk(str, args);
122725 +#endif /* CONFIG_SMP */
122726 + va_end(args);
122727 +}
122728 +
122729 +void XX_Fprint(void *file, char *str, ...)
122730 +{
122731 + va_list args;
122732 +#ifdef CONFIG_SMP
122733 + char buf[BUF_SIZE];
122734 +#endif /* CONFIG_SMP */
122735 +
122736 + va_start(args, str);
122737 +#ifdef CONFIG_SMP
122738 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
122739 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
122740 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
122741 +
122742 +#else
122743 + vprintk(str, args);
122744 +#endif /* CONFIG_SMP */
122745 + va_end(args);
122746 +}
122747 +
122748 +#ifdef DEBUG_XX_MALLOC
122749 +typedef void (*t_ffn)(void *);
122750 +typedef struct {
122751 + t_ffn f_free;
122752 + void *mem;
122753 + char *fname;
122754 + int fline;
122755 + uint32_t size;
122756 + t_List node;
122757 +} t_MemDebug;
122758 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
122759 +
122760 +LIST(memDbgLst);
122761 +
122762 +
122763 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
122764 +{
122765 + void *mem;
122766 + t_MemDebug *p_MemDbg;
122767 +
122768 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
122769 + if (p_MemDbg == NULL)
122770 + return NULL;
122771 +
122772 + mem = xx_Malloc(size);
122773 + if (mem == NULL)
122774 + {
122775 + XX_Free(p_MemDbg);
122776 + return NULL;
122777 + }
122778 +
122779 + INIT_LIST(&p_MemDbg->node);
122780 + p_MemDbg->f_free = xx_Free;
122781 + p_MemDbg->mem = mem;
122782 + p_MemDbg->fname = fname;
122783 + p_MemDbg->fline = line;
122784 + p_MemDbg->size = size+sizeof(t_MemDebug);
122785 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122786 +
122787 + return mem;
122788 +}
122789 +
122790 +void * XX_MallocSmartDebug(uint32_t size,
122791 + int memPartitionId,
122792 + uint32_t align,
122793 + char *fname,
122794 + int line)
122795 +{
122796 + void *mem;
122797 + t_MemDebug *p_MemDbg;
122798 +
122799 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
122800 + if (p_MemDbg == NULL)
122801 + return NULL;
122802 +
122803 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
122804 + if (mem == NULL)
122805 + {
122806 + XX_Free(p_MemDbg);
122807 + return NULL;
122808 + }
122809 +
122810 + INIT_LIST(&p_MemDbg->node);
122811 + p_MemDbg->f_free = xx_FreeSmart;
122812 + p_MemDbg->mem = mem;
122813 + p_MemDbg->fname = fname;
122814 + p_MemDbg->fline = line;
122815 + p_MemDbg->size = size+sizeof(t_MemDebug);
122816 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
122817 +
122818 + return mem;
122819 +}
122820 +
122821 +static void debug_free(void *mem)
122822 +{
122823 + t_List *p_MemDbgLh = NULL;
122824 + t_MemDebug *p_MemDbg;
122825 + bool found = FALSE;
122826 +
122827 + if (LIST_IsEmpty(&memDbgLst))
122828 + {
122829 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
122830 + return;
122831 + }
122832 +
122833 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
122834 + {
122835 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
122836 + if (p_MemDbg->mem == mem)
122837 + {
122838 + found = TRUE;
122839 + break;
122840 + }
122841 + }
122842 +
122843 + if (!found)
122844 + {
122845 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
122846 + ("Attempt to free unallocated address (0x%08x)",mem));
122847 + dump_stack();
122848 + return;
122849 + }
122850 +
122851 + LIST_Del(p_MemDbgLh);
122852 + p_MemDbg->f_free(mem);
122853 + p_MemDbg->f_free(p_MemDbg);
122854 +}
122855 +
122856 +void XX_FreeSmart(void *p)
122857 +{
122858 + debug_free(p);
122859 +}
122860 +
122861 +
122862 +void XX_Free(void *p)
122863 +{
122864 + debug_free(p);
122865 +}
122866 +
122867 +#else /* not DEBUG_XX_MALLOC */
122868 +void * XX_Malloc(uint32_t size)
122869 +{
122870 + return xx_Malloc(size);
122871 +}
122872 +
122873 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
122874 +{
122875 + return xx_MallocSmart(size,memPartitionId, alignment);
122876 +}
122877 +
122878 +void XX_FreeSmart(void *p)
122879 +{
122880 + xx_FreeSmart(p);
122881 +}
122882 +
122883 +
122884 +void XX_Free(void *p)
122885 +{
122886 + xx_Free(p);
122887 +}
122888 +#endif /* not DEBUG_XX_MALLOC */
122889 +
122890 +
122891 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
122892 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
122893 +{
122894 + e_Event eventCode = (e_Event)event;
122895 +
122896 + UNUSED(eventCode);
122897 + UNUSED(appId);
122898 + UNUSED(flags);
122899 + UNUSED(msg);
122900 +}
122901 +#endif /* (defined(REPORT_EVENTS) && ... */
122902 +
122903 +
122904 +uint32_t XX_DisableAllIntr(void)
122905 +{
122906 + unsigned long flags;
122907 +
122908 +#ifdef local_irq_save_nort
122909 + local_irq_save_nort(flags);
122910 +#else
122911 + local_irq_save(flags);
122912 +#endif
122913 +
122914 + return (uint32_t)flags;
122915 +}
122916 +
122917 +void XX_RestoreAllIntr(uint32_t flags)
122918 +{
122919 +#ifdef local_irq_restore_nort
122920 + local_irq_restore_nort((unsigned long)flags);
122921 +#else
122922 + local_irq_restore((unsigned long)flags);
122923 +#endif
122924 +}
122925 +
122926 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
122927 +{
122928 + UNUSED(qid);
122929 + UNUSED(appId);
122930 + UNUSED(flags);
122931 +
122932 + return f(id);
122933 +}
122934 +
122935 +int XX_IsICacheEnable(void)
122936 +{
122937 + return TRUE;
122938 +}
122939 +
122940 +int XX_IsDCacheEnable(void)
122941 +{
122942 + return TRUE;
122943 +}
122944 +
122945 +
122946 +typedef struct {
122947 + t_Isr *f_Isr;
122948 + t_Handle handle;
122949 +} t_InterruptHandler;
122950 +
122951 +
122952 +t_Handle interruptHandlers[0x00010000];
122953 +
122954 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
122955 +{
122956 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
122957 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
122958 + return IRQ_HANDLED;
122959 +}
122960 +
122961 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
122962 +{
122963 + const char *device;
122964 + t_InterruptHandler *p_IntrHndl;
122965 +
122966 + device = GetDeviceName(irq);
122967 + if (device == NULL)
122968 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
122969 +
122970 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
122971 + if (p_IntrHndl == NULL)
122972 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
122973 + p_IntrHndl->f_Isr = f_Isr;
122974 + p_IntrHndl->handle = handle;
122975 + interruptHandlers[irq] = p_IntrHndl;
122976 +
122977 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
122978 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
122979 + disable_irq(GetDeviceIrqNum(irq));
122980 +
122981 + return E_OK;
122982 +}
122983 +
122984 +t_Error XX_FreeIntr(int irq)
122985 +{
122986 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
122987 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
122988 + XX_Free(p_IntrHndl);
122989 + interruptHandlers[irq] = 0;
122990 + return E_OK;
122991 +}
122992 +
122993 +t_Error XX_EnableIntr(int irq)
122994 +{
122995 + enable_irq(GetDeviceIrqNum(irq));
122996 + return E_OK;
122997 +}
122998 +
122999 +t_Error XX_DisableIntr(int irq)
123000 +{
123001 + disable_irq(GetDeviceIrqNum(irq));
123002 + return E_OK;
123003 +}
123004 +
123005 +
123006 +/*****************************************************************************/
123007 +/* Tasklet Service Routines */
123008 +/*****************************************************************************/
123009 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123010 +typedef struct
123011 +{
123012 + t_Handle h_Data;
123013 + void (*f_Callback) (void *);
123014 + struct delayed_work dwork;
123015 +} t_Tasklet;
123016 +
123017 +static void GenericTaskletCallback(struct work_struct *p_Work)
123018 +{
123019 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123020 +
123021 + p_Task->f_Callback(p_Task->h_Data);
123022 +}
123023 +#endif /* LINUX_VERSION_CODE */
123024 +
123025 +
123026 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123027 +{
123028 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123029 + struct work_struct *p_Task;
123030 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123031 + INIT_WORK(p_Task, routine, data);
123032 +#else
123033 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123034 + p_Task->h_Data = data;
123035 + p_Task->f_Callback = routine;
123036 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123037 +#endif /* LINUX_VERSION_CODE */
123038 +
123039 + return (t_TaskletHandle)p_Task;
123040 +}
123041 +
123042 +
123043 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123044 +{
123045 + if (h_Tasklet)
123046 + XX_Free(h_Tasklet);
123047 +}
123048 +
123049 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123050 +{
123051 + int ans;
123052 +
123053 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123054 + if (immediate)
123055 + ans = schedule_work(h_Tasklet);
123056 + else
123057 + ans = schedule_delayed_work(h_Tasklet, 1);
123058 +#else
123059 + if (immediate)
123060 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123061 + else
123062 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123063 +#endif /* LINUX_VERSION_CODE */
123064 +
123065 + return ans;
123066 +}
123067 +
123068 +void XX_FlushScheduledTasks(void)
123069 +{
123070 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123071 + flush_scheduled_tasks();
123072 +#else
123073 + flush_scheduled_work();
123074 +#endif /* LINUX_VERSION_CODE */
123075 +}
123076 +
123077 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123078 +{
123079 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123080 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123081 +#else
123082 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123083 +#endif /* LINUX_VERSION_CODE */
123084 +}
123085 +
123086 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
123087 +{
123088 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123089 + ((struct tq_struct *)h_Tasklet)->data = data;
123090 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123091 + ((struct work_struct *)h_Tasklet)->data = data;
123092 +#else
123093 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
123094 +#endif /* LINUX_VERSION_CODE */
123095 +}
123096 +
123097 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
123098 +{
123099 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123100 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
123101 +#else
123102 + return ((t_Tasklet *)h_Tasklet)->h_Data;
123103 +#endif /* LINUX_VERSION_CODE */
123104 +}
123105 +
123106 +
123107 +/*****************************************************************************/
123108 +/* Spinlock Service Routines */
123109 +/*****************************************************************************/
123110 +
123111 +t_Handle XX_InitSpinlock(void)
123112 +{
123113 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
123114 + if (!p_Spinlock)
123115 + return NULL;
123116 +
123117 + spin_lock_init(p_Spinlock);
123118 +
123119 + return (t_Handle)p_Spinlock;
123120 +}
123121 +
123122 +void XX_FreeSpinlock(t_Handle h_Spinlock)
123123 +{
123124 + if (h_Spinlock)
123125 + XX_Free(h_Spinlock);
123126 +}
123127 +
123128 +void XX_LockSpinlock(t_Handle h_Spinlock)
123129 +{
123130 + spin_lock((spinlock_t *)h_Spinlock);
123131 +}
123132 +
123133 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
123134 +{
123135 + spin_unlock((spinlock_t *)h_Spinlock);
123136 +}
123137 +
123138 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
123139 +{
123140 + unsigned long intrFlags;
123141 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
123142 + return intrFlags;
123143 +}
123144 +
123145 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
123146 +{
123147 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
123148 +}
123149 +
123150 +
123151 +/*****************************************************************************/
123152 +/* Timers Service Routines */
123153 +/*****************************************************************************/
123154 +/* The time now is in mili sec. resolution */
123155 +uint32_t XX_CurrentTime(void)
123156 +{
123157 + return (jiffies*1000)/HZ;
123158 +}
123159 +
123160 +
123161 +t_Handle XX_CreateTimer(void)
123162 +{
123163 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
123164 + if (p_Timer)
123165 + {
123166 + memset(p_Timer, 0, sizeof(struct timer_list));
123167 + init_timer(p_Timer);
123168 + }
123169 + return (t_Handle)p_Timer;
123170 +}
123171 +
123172 +void XX_FreeTimer(t_Handle h_Timer)
123173 +{
123174 + if (h_Timer)
123175 + XX_Free(h_Timer);
123176 +}
123177 +
123178 +void XX_StartTimer(t_Handle h_Timer,
123179 + uint32_t msecs,
123180 + bool periodic,
123181 + void (*f_TimerExpired)(t_Handle),
123182 + t_Handle h_Arg)
123183 +{
123184 + int tmp_jiffies = (msecs*HZ)/1000;
123185 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123186 +
123187 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
123188 +
123189 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
123190 + p_Timer->data = (unsigned long)h_Arg;
123191 + if ((msecs*HZ)%1000)
123192 + tmp_jiffies++;
123193 + p_Timer->expires = (jiffies + tmp_jiffies);
123194 +
123195 + add_timer((struct timer_list *)h_Timer);
123196 +}
123197 +
123198 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
123199 +{
123200 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123201 +
123202 + p_Timer->data = (unsigned long)data;
123203 +}
123204 +
123205 +t_Handle XX_GetTimerData(t_Handle h_Timer)
123206 +{
123207 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123208 +
123209 + return (t_Handle)p_Timer->data;
123210 +}
123211 +
123212 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
123213 +{
123214 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
123215 +
123216 + return (uint32_t)p_Timer->expires;
123217 +}
123218 +
123219 +void XX_StopTimer(t_Handle h_Timer)
123220 +{
123221 + del_timer((struct timer_list *)h_Timer);
123222 +}
123223 +
123224 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
123225 +{
123226 + int tmp_jiffies = (msecs*HZ)/1000;
123227 +
123228 + if ((msecs*HZ)%1000)
123229 + tmp_jiffies++;
123230 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
123231 +}
123232 +
123233 +int XX_TimerIsActive(t_Handle h_Timer)
123234 +{
123235 + return timer_pending((struct timer_list *)h_Timer);
123236 +}
123237 +
123238 +uint32_t XX_Sleep(uint32_t msecs)
123239 +{
123240 + int tmp_jiffies = (msecs*HZ)/1000;
123241 +
123242 + if ((msecs*HZ)%1000)
123243 + tmp_jiffies++;
123244 + return schedule_timeout(tmp_jiffies);
123245 +}
123246 +
123247 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
123248 +void XX_UDelay(uint32_t usecs)
123249 +{
123250 + udelay(usecs);
123251 +}
123252 +
123253 +/* TODO: verify that these are correct */
123254 +#define MSG_BODY_SIZE 512
123255 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
123256 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
123257 +t_Error XX_SendMessage(char *p_DestAddr,
123258 + uint32_t msgId,
123259 + uint8_t msgBody[MSG_BODY_SIZE],
123260 + t_MsgCompletionCB *f_CompletionCB,
123261 + t_Handle h_CBArg);
123262 +
123263 +typedef struct {
123264 + char *p_Addr;
123265 + t_MsgHandler *f_MsgHandlerCB;
123266 + t_Handle h_Mod;
123267 + t_List node;
123268 +} t_MsgHndlr;
123269 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
123270 +
123271 +LIST(msgHndlrList);
123272 +
123273 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
123274 +{
123275 + uint32_t intFlags;
123276 +
123277 + intFlags = XX_DisableAllIntr();
123278 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
123279 + XX_RestoreAllIntr(intFlags);
123280 +}
123281 +/* TODO: add this for multi-platform support
123282 +static t_MsgHndlr * DequeueMsgHndlr(void)
123283 +{
123284 + t_MsgHndlr *p_MsgHndlr = NULL;
123285 + uint32_t intFlags;
123286 +
123287 + intFlags = XX_DisableAllIntr();
123288 + if (!LIST_IsEmpty(&msgHndlrList))
123289 + {
123290 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
123291 + LIST_DelAndInit(&p_MsgHndlr->node);
123292 + }
123293 + XX_RestoreAllIntr(intFlags);
123294 +
123295 + return p_MsgHndlr;
123296 +}
123297 +*/
123298 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
123299 +{
123300 + t_MsgHndlr *p_MsgHndlr;
123301 + t_List *p_Pos;
123302 +
123303 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
123304 + {
123305 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
123306 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
123307 + return p_MsgHndlr;
123308 + }
123309 +
123310 + return NULL;
123311 +}
123312 +
123313 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
123314 +{
123315 + t_MsgHndlr *p_MsgHndlr;
123316 + uint32_t len;
123317 +
123318 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
123319 + if (!p_MsgHndlr)
123320 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
123321 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
123322 +
123323 + len = strlen(p_Addr);
123324 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
123325 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
123326 +
123327 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
123328 + p_MsgHndlr->h_Mod = h_Mod;
123329 + INIT_LIST(&p_MsgHndlr->node);
123330 + EnqueueMsgHndlr(p_MsgHndlr);
123331 +
123332 + return E_OK;
123333 +}
123334 +
123335 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
123336 +{
123337 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
123338 + if (!p_MsgHndlr)
123339 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123340 +
123341 + LIST_Del(&p_MsgHndlr->node);
123342 + XX_Free(p_MsgHndlr->p_Addr);
123343 + XX_Free(p_MsgHndlr);
123344 +
123345 + return E_OK;
123346 +}
123347 +
123348 +t_Error XX_SendMessage(char *p_DestAddr,
123349 + uint32_t msgId,
123350 + uint8_t msgBody[MSG_BODY_SIZE],
123351 + t_MsgCompletionCB *f_CompletionCB,
123352 + t_Handle h_CBArg)
123353 +{
123354 + t_Error ans;
123355 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
123356 + if (!p_MsgHndlr)
123357 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
123358 +
123359 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
123360 +
123361 + if (f_CompletionCB)
123362 + f_CompletionCB(h_CBArg, msgBody);
123363 +
123364 + return ans;
123365 +}
123366 +
123367 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123368 + t_IpcMsgHandler *f_MsgHandler,
123369 + t_Handle h_Module,
123370 + uint32_t replyLength)
123371 +{
123372 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
123373 + return E_OK;
123374 +}
123375 +
123376 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123377 +{
123378 + UNUSED(addr);
123379 + return E_OK;
123380 +}
123381 +
123382 +
123383 +t_Error XX_IpcSendMessage(t_Handle h_Session,
123384 + uint8_t *p_Msg,
123385 + uint32_t msgLength,
123386 + uint8_t *p_Reply,
123387 + uint32_t *p_ReplyLength,
123388 + t_IpcMsgCompletion *f_Completion,
123389 + t_Handle h_Arg)
123390 +{
123391 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
123392 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
123393 + return E_OK;
123394 +}
123395 +
123396 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
123397 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
123398 +{
123399 + UNUSED(destAddr); UNUSED(srcAddr);
123400 + return E_OK;
123401 +}
123402 +
123403 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
123404 +int GetDeviceIrqNum(int irq)
123405 +{
123406 + struct device_node *iPar;
123407 + struct irq_domain *irqHost;
123408 + uint32_t hwIrq;
123409 +
123410 + /* Get the interrupt controller */
123411 + iPar = of_find_node_by_name(NULL, "mpic");
123412 + hwIrq = 0;
123413 +
123414 + ASSERT_COND(iPar != NULL);
123415 + /* Get the irq host */
123416 + irqHost = irq_find_host(iPar);
123417 + of_node_put(iPar);
123418 +
123419 + /* Create irq mapping */
123420 + return irq_create_mapping(irqHost, hwIrq);
123421 +}
123422 +#else
123423 +#error "kernel not supported!!!"
123424 +#endif /* LINUX_VERSION_CODE */
123425 +
123426 +void * XX_PhysToVirt(physAddress_t addr)
123427 +{
123428 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
123429 +}
123430 +
123431 +physAddress_t XX_VirtToPhys(void * addr)
123432 +{
123433 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
123434 +}
123435 +
123436 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123437 +{
123438 + uintptr_t *returnCode, tmp;
123439 +
123440 + if (alignment < sizeof(uintptr_t))
123441 + alignment = sizeof(uintptr_t);
123442 + size += alignment + sizeof(returnCode);
123443 + tmp = (uintptr_t)xx_Malloc(size);
123444 + if (tmp == 0)
123445 + return NULL;
123446 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
123447 + *(returnCode - 1) = tmp;
123448 +
123449 + return (void*)returnCode;
123450 +}
123451 +
123452 +void xx_FreeSmart(void *p)
123453 +{
123454 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
123455 +}
123456 --- /dev/null
123457 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
123458 @@ -0,0 +1,918 @@
123459 +/*
123460 + * Copyright 2008-2012 Freescale Semiconductor Inc.
123461 + *
123462 + * Redistribution and use in source and binary forms, with or without
123463 + * modification, are permitted provided that the following conditions are met:
123464 + * * Redistributions of source code must retain the above copyright
123465 + * notice, this list of conditions and the following disclaimer.
123466 + * * Redistributions in binary form must reproduce the above copyright
123467 + * notice, this list of conditions and the following disclaimer in the
123468 + * documentation and/or other materials provided with the distribution.
123469 + * * Neither the name of Freescale Semiconductor nor the
123470 + * names of its contributors may be used to endorse or promote products
123471 + * derived from this software without specific prior written permission.
123472 + *
123473 + *
123474 + * ALTERNATIVELY, this software may be distributed under the terms of the
123475 + * GNU General Public License ("GPL") as published by the Free Software
123476 + * Foundation, either version 2 of that License or (at your option) any
123477 + * later version.
123478 + *
123479 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
123480 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
123481 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
123482 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
123483 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
123484 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
123485 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
123486 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
123487 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
123488 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
123489 + */
123490 +
123491 +/**************************************************************************//**
123492 + @File xx_linux.c
123493 +
123494 + @Description XX routines implementation for Linux.
123495 +*//***************************************************************************/
123496 +#include <linux/version.h>
123497 +
123498 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
123499 +#define MODVERSIONS
123500 +#endif
123501 +#ifdef MODVERSIONS
123502 +#include <config/modversions.h>
123503 +#endif /* MODVERSIONS */
123504 +
123505 +#include <linux/module.h>
123506 +#include <linux/kernel.h>
123507 +#include <linux/sched.h>
123508 +#include <linux/string.h>
123509 +#include <linux/ptrace.h>
123510 +#include <linux/errno.h>
123511 +#include <linux/ioport.h>
123512 +#include <linux/slab.h>
123513 +#include <linux/interrupt.h>
123514 +#include <linux/fs.h>
123515 +#include <linux/vmalloc.h>
123516 +#include <linux/init.h>
123517 +#include <linux/timer.h>
123518 +#include <linux/spinlock.h>
123519 +#include <linux/delay.h>
123520 +#include <linux/proc_fs.h>
123521 +#include <linux/smp.h>
123522 +#include <linux/of.h>
123523 +#ifdef CONFIG_FMAN_ARM
123524 +#include <linux/irqdomain.h>
123525 +#endif
123526 +
123527 +#include <linux/workqueue.h>
123528 +
123529 +#ifdef BIGPHYSAREA_ENABLE
123530 +#include <linux/bigphysarea.h>
123531 +#endif /* BIGPHYSAREA_ENABLE */
123532 +
123533 +#ifndef CONFIG_FMAN_ARM
123534 +#include <sysdev/fsl_soc.h>
123535 +#endif
123536 +#include <asm/pgtable.h>
123537 +#include <asm/irq.h>
123538 +#include <asm/bitops.h>
123539 +#include <asm/uaccess.h>
123540 +#include <asm/io.h>
123541 +#include <asm/atomic.h>
123542 +#include <asm/string.h>
123543 +#include <asm/byteorder.h>
123544 +#include <asm/page.h>
123545 +
123546 +#include "error_ext.h"
123547 +#include "std_ext.h"
123548 +#include "list_ext.h"
123549 +#include "mm_ext.h"
123550 +#include "sys_io_ext.h"
123551 +#include "xx.h"
123552 +
123553 +
123554 +#define __ERR_MODULE__ MODULE_UNKNOWN
123555 +
123556 +#ifdef BIGPHYSAREA_ENABLE
123557 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
123558 +
123559 +
123560 +/* TODO: large allocations => use big phys area */
123561 +/******************************************************************************
123562 + * routine: get_nr_pages
123563 + *
123564 + * description:
123565 + * calculates the number of memory pages for a given size (in bytes)
123566 + *
123567 + * arguments:
123568 + * size - the number of bytes
123569 + *
123570 + * return code:
123571 + * The number of pages
123572 + *
123573 + *****************************************************************************/
123574 +static __inline__ uint32_t get_nr_pages (uint32_t size)
123575 +{
123576 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
123577 +}
123578 +
123579 +static bool in_big_phys_area (uint32_t addr)
123580 +{
123581 + uint32_t base, size;
123582 +
123583 + bigphysarea_get_details (&base, &size);
123584 + return ((addr >= base) && (addr < base + size));
123585 +}
123586 +#endif /* BIGPHYSAREA_ENABLE */
123587 +
123588 +void * xx_Malloc(uint32_t n)
123589 +{
123590 + void *a;
123591 + uint32_t flags;
123592 +
123593 + flags = XX_DisableAllIntr();
123594 +#ifdef BIGPHYSAREA_ENABLE
123595 + if (n >= MAX_ALLOCATION_SIZE)
123596 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
123597 + else
123598 +#endif /* BIGPHYSAREA_ENABLE */
123599 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
123600 + if (!a)
123601 + XX_Print("No memory for XX_Malloc\n");
123602 + XX_RestoreAllIntr(flags);
123603 +
123604 + return a;
123605 +}
123606 +
123607 +void xx_Free(void *p)
123608 +{
123609 +#ifdef BIGPHYSAREA_ENABLE
123610 + if (in_big_phys_area ((uint32_t)p))
123611 + bigphysarea_free_pages(p);
123612 + else
123613 +#endif /* BIGPHYSAREA_ENABLE */
123614 + kfree(p);
123615 +}
123616 +
123617 +void XX_Exit(int status)
123618 +{
123619 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
123620 +}
123621 +
123622 +#define BUF_SIZE 512
123623 +void XX_Print(char *str, ...)
123624 +{
123625 + va_list args;
123626 +#ifdef CONFIG_SMP
123627 + char buf[BUF_SIZE];
123628 +#endif /* CONFIG_SMP */
123629 +
123630 + va_start(args, str);
123631 +#ifdef CONFIG_SMP
123632 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123633 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123634 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123635 +#else
123636 + vprintk(str, args);
123637 +#endif /* CONFIG_SMP */
123638 + va_end(args);
123639 +}
123640 +
123641 +void XX_Fprint(void *file, char *str, ...)
123642 +{
123643 + va_list args;
123644 +#ifdef CONFIG_SMP
123645 + char buf[BUF_SIZE];
123646 +#endif /* CONFIG_SMP */
123647 +
123648 + va_start(args, str);
123649 +#ifdef CONFIG_SMP
123650 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
123651 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
123652 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
123653 +
123654 +#else
123655 + vprintk(str, args);
123656 +#endif /* CONFIG_SMP */
123657 + va_end(args);
123658 +}
123659 +
123660 +#ifdef DEBUG_XX_MALLOC
123661 +typedef void (*t_ffn)(void *);
123662 +typedef struct {
123663 + t_ffn f_free;
123664 + void *mem;
123665 + char *fname;
123666 + int fline;
123667 + uint32_t size;
123668 + t_List node;
123669 +} t_MemDebug;
123670 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
123671 +
123672 +LIST(memDbgLst);
123673 +
123674 +
123675 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
123676 +{
123677 + void *mem;
123678 + t_MemDebug *p_MemDbg;
123679 +
123680 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
123681 + if (p_MemDbg == NULL)
123682 + return NULL;
123683 +
123684 + mem = xx_Malloc(size);
123685 + if (mem == NULL)
123686 + {
123687 + XX_Free(p_MemDbg);
123688 + return NULL;
123689 + }
123690 +
123691 + INIT_LIST(&p_MemDbg->node);
123692 + p_MemDbg->f_free = xx_Free;
123693 + p_MemDbg->mem = mem;
123694 + p_MemDbg->fname = fname;
123695 + p_MemDbg->fline = line;
123696 + p_MemDbg->size = size+sizeof(t_MemDebug);
123697 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123698 +
123699 + return mem;
123700 +}
123701 +
123702 +void * XX_MallocSmartDebug(uint32_t size,
123703 + int memPartitionId,
123704 + uint32_t align,
123705 + char *fname,
123706 + int line)
123707 +{
123708 + void *mem;
123709 + t_MemDebug *p_MemDbg;
123710 +
123711 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
123712 + if (p_MemDbg == NULL)
123713 + return NULL;
123714 +
123715 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
123716 + if (mem == NULL)
123717 + {
123718 + XX_Free(p_MemDbg);
123719 + return NULL;
123720 + }
123721 +
123722 + INIT_LIST(&p_MemDbg->node);
123723 + p_MemDbg->f_free = xx_FreeSmart;
123724 + p_MemDbg->mem = mem;
123725 + p_MemDbg->fname = fname;
123726 + p_MemDbg->fline = line;
123727 + p_MemDbg->size = size+sizeof(t_MemDebug);
123728 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
123729 +
123730 + return mem;
123731 +}
123732 +
123733 +static void debug_free(void *mem)
123734 +{
123735 + t_List *p_MemDbgLh = NULL;
123736 + t_MemDebug *p_MemDbg;
123737 + bool found = FALSE;
123738 +
123739 + if (LIST_IsEmpty(&memDbgLst))
123740 + {
123741 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
123742 + return;
123743 + }
123744 +
123745 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
123746 + {
123747 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
123748 + if (p_MemDbg->mem == mem)
123749 + {
123750 + found = TRUE;
123751 + break;
123752 + }
123753 + }
123754 +
123755 + if (!found)
123756 + {
123757 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
123758 + ("Attempt to free unallocated address (0x%08x)",mem));
123759 + dump_stack();
123760 + return;
123761 + }
123762 +
123763 + LIST_Del(p_MemDbgLh);
123764 + p_MemDbg->f_free(mem);
123765 + p_MemDbg->f_free(p_MemDbg);
123766 +}
123767 +
123768 +void XX_FreeSmart(void *p)
123769 +{
123770 + debug_free(p);
123771 +}
123772 +
123773 +
123774 +void XX_Free(void *p)
123775 +{
123776 + debug_free(p);
123777 +}
123778 +
123779 +#else /* not DEBUG_XX_MALLOC */
123780 +void * XX_Malloc(uint32_t size)
123781 +{
123782 + return xx_Malloc(size);
123783 +}
123784 +
123785 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
123786 +{
123787 + return xx_MallocSmart(size,memPartitionId, alignment);
123788 +}
123789 +
123790 +void XX_FreeSmart(void *p)
123791 +{
123792 + xx_FreeSmart(p);
123793 +}
123794 +
123795 +
123796 +void XX_Free(void *p)
123797 +{
123798 + xx_Free(p);
123799 +}
123800 +#endif /* not DEBUG_XX_MALLOC */
123801 +
123802 +
123803 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
123804 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
123805 +{
123806 + e_Event eventCode = (e_Event)event;
123807 +
123808 + UNUSED(eventCode);
123809 + UNUSED(appId);
123810 + UNUSED(flags);
123811 + UNUSED(msg);
123812 +}
123813 +#endif /* (defined(REPORT_EVENTS) && ... */
123814 +
123815 +
123816 +uint32_t XX_DisableAllIntr(void)
123817 +{
123818 + unsigned long flags;
123819 +
123820 +#ifdef local_irq_save_nort
123821 + local_irq_save_nort(flags);
123822 +#else
123823 + local_irq_save(flags);
123824 +#endif
123825 +
123826 + return (uint32_t)flags;
123827 +}
123828 +
123829 +void XX_RestoreAllIntr(uint32_t flags)
123830 +{
123831 +#ifdef local_irq_restore_nort
123832 + local_irq_restore_nort((unsigned long)flags);
123833 +#else
123834 + local_irq_restore((unsigned long)flags);
123835 +#endif
123836 +}
123837 +
123838 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
123839 +{
123840 + UNUSED(qid);
123841 + UNUSED(appId);
123842 + UNUSED(flags);
123843 +
123844 + return f(id);
123845 +}
123846 +
123847 +int XX_IsICacheEnable(void)
123848 +{
123849 + return TRUE;
123850 +}
123851 +
123852 +int XX_IsDCacheEnable(void)
123853 +{
123854 + return TRUE;
123855 +}
123856 +
123857 +
123858 +typedef struct {
123859 + t_Isr *f_Isr;
123860 + t_Handle handle;
123861 +} t_InterruptHandler;
123862 +
123863 +
123864 +t_Handle interruptHandlers[0x00010000];
123865 +
123866 +#ifdef CONFIG_FMAN_ARM
123867 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
123868 +{
123869 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
123870 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
123871 + return IRQ_HANDLED;
123872 +}
123873 +#endif
123874 +
123875 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
123876 +{
123877 +#ifdef CONFIG_FMAN_ARM
123878 + const char *device;
123879 + t_InterruptHandler *p_IntrHndl;
123880 +
123881 + device = GetDeviceName(irq);
123882 + if (device == NULL)
123883 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
123884 +
123885 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
123886 + if (p_IntrHndl == NULL)
123887 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
123888 + p_IntrHndl->f_Isr = f_Isr;
123889 + p_IntrHndl->handle = handle;
123890 + interruptHandlers[irq] = p_IntrHndl;
123891 +
123892 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
123893 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
123894 + disable_irq(GetDeviceIrqNum(irq));
123895 +#endif
123896 + return E_OK;
123897 +}
123898 +
123899 +t_Error XX_FreeIntr(int irq)
123900 +{
123901 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
123902 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
123903 + XX_Free(p_IntrHndl);
123904 + interruptHandlers[irq] = 0;
123905 + return E_OK;
123906 +}
123907 +
123908 +t_Error XX_EnableIntr(int irq)
123909 +{
123910 + enable_irq(GetDeviceIrqNum(irq));
123911 + return E_OK;
123912 +}
123913 +
123914 +t_Error XX_DisableIntr(int irq)
123915 +{
123916 + disable_irq(GetDeviceIrqNum(irq));
123917 + return E_OK;
123918 +}
123919 +
123920 +
123921 +/*****************************************************************************/
123922 +/* Tasklet Service Routines */
123923 +/*****************************************************************************/
123924 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
123925 +typedef struct
123926 +{
123927 + t_Handle h_Data;
123928 + void (*f_Callback) (void *);
123929 + struct delayed_work dwork;
123930 +} t_Tasklet;
123931 +
123932 +static void GenericTaskletCallback(struct work_struct *p_Work)
123933 +{
123934 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
123935 +
123936 + p_Task->f_Callback(p_Task->h_Data);
123937 +}
123938 +#endif /* LINUX_VERSION_CODE */
123939 +
123940 +
123941 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
123942 +{
123943 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123944 + struct work_struct *p_Task;
123945 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
123946 + INIT_WORK(p_Task, routine, data);
123947 +#else
123948 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
123949 + p_Task->h_Data = data;
123950 + p_Task->f_Callback = routine;
123951 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
123952 +#endif /* LINUX_VERSION_CODE */
123953 +
123954 + return (t_TaskletHandle)p_Task;
123955 +}
123956 +
123957 +
123958 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
123959 +{
123960 + if (h_Tasklet)
123961 + XX_Free(h_Tasklet);
123962 +}
123963 +
123964 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
123965 +{
123966 + int ans;
123967 +
123968 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123969 + if (immediate)
123970 + ans = schedule_work(h_Tasklet);
123971 + else
123972 + ans = schedule_delayed_work(h_Tasklet, 1);
123973 +#else
123974 + if (immediate)
123975 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
123976 + else
123977 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
123978 +#endif /* LINUX_VERSION_CODE */
123979 +
123980 + return ans;
123981 +}
123982 +
123983 +void XX_FlushScheduledTasks(void)
123984 +{
123985 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
123986 + flush_scheduled_tasks();
123987 +#else
123988 + flush_scheduled_work();
123989 +#endif /* LINUX_VERSION_CODE */
123990 +}
123991 +
123992 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
123993 +{
123994 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
123995 + return (int)(((struct work_struct *)h_Tasklet)->pending);
123996 +#else
123997 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
123998 +#endif /* LINUX_VERSION_CODE */
123999 +}
124000 +
124001 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
124002 +{
124003 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124004 + ((struct tq_struct *)h_Tasklet)->data = data;
124005 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124006 + ((struct work_struct *)h_Tasklet)->data = data;
124007 +#else
124008 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
124009 +#endif /* LINUX_VERSION_CODE */
124010 +}
124011 +
124012 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
124013 +{
124014 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124015 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
124016 +#else
124017 + return ((t_Tasklet *)h_Tasklet)->h_Data;
124018 +#endif /* LINUX_VERSION_CODE */
124019 +}
124020 +
124021 +
124022 +/*****************************************************************************/
124023 +/* Spinlock Service Routines */
124024 +/*****************************************************************************/
124025 +
124026 +t_Handle XX_InitSpinlock(void)
124027 +{
124028 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
124029 + if (!p_Spinlock)
124030 + return NULL;
124031 +
124032 + spin_lock_init(p_Spinlock);
124033 +
124034 + return (t_Handle)p_Spinlock;
124035 +}
124036 +
124037 +void XX_FreeSpinlock(t_Handle h_Spinlock)
124038 +{
124039 + if (h_Spinlock)
124040 + XX_Free(h_Spinlock);
124041 +}
124042 +
124043 +void XX_LockSpinlock(t_Handle h_Spinlock)
124044 +{
124045 + spin_lock((spinlock_t *)h_Spinlock);
124046 +}
124047 +
124048 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
124049 +{
124050 + spin_unlock((spinlock_t *)h_Spinlock);
124051 +}
124052 +
124053 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
124054 +{
124055 + unsigned long intrFlags;
124056 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
124057 + return intrFlags;
124058 +}
124059 +
124060 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
124061 +{
124062 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
124063 +}
124064 +
124065 +
124066 +/*****************************************************************************/
124067 +/* Timers Service Routines */
124068 +/*****************************************************************************/
124069 +/* The time now is in mili sec. resolution */
124070 +uint32_t XX_CurrentTime(void)
124071 +{
124072 + return (jiffies*1000)/HZ;
124073 +}
124074 +
124075 +
124076 +t_Handle XX_CreateTimer(void)
124077 +{
124078 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
124079 + if (p_Timer)
124080 + {
124081 + memset(p_Timer, 0, sizeof(struct timer_list));
124082 + init_timer(p_Timer);
124083 + }
124084 + return (t_Handle)p_Timer;
124085 +}
124086 +
124087 +void XX_FreeTimer(t_Handle h_Timer)
124088 +{
124089 + if (h_Timer)
124090 + XX_Free(h_Timer);
124091 +}
124092 +
124093 +void XX_StartTimer(t_Handle h_Timer,
124094 + uint32_t msecs,
124095 + bool periodic,
124096 + void (*f_TimerExpired)(t_Handle),
124097 + t_Handle h_Arg)
124098 +{
124099 + int tmp_jiffies = (msecs*HZ)/1000;
124100 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124101 +
124102 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
124103 +
124104 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
124105 + p_Timer->data = (unsigned long)h_Arg;
124106 + if ((msecs*HZ)%1000)
124107 + tmp_jiffies++;
124108 + p_Timer->expires = (jiffies + tmp_jiffies);
124109 +
124110 + add_timer((struct timer_list *)h_Timer);
124111 +}
124112 +
124113 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
124114 +{
124115 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124116 +
124117 + p_Timer->data = (unsigned long)data;
124118 +}
124119 +
124120 +t_Handle XX_GetTimerData(t_Handle h_Timer)
124121 +{
124122 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124123 +
124124 + return (t_Handle)p_Timer->data;
124125 +}
124126 +
124127 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
124128 +{
124129 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124130 +
124131 + return (uint32_t)p_Timer->expires;
124132 +}
124133 +
124134 +void XX_StopTimer(t_Handle h_Timer)
124135 +{
124136 + del_timer((struct timer_list *)h_Timer);
124137 +}
124138 +
124139 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
124140 +{
124141 + int tmp_jiffies = (msecs*HZ)/1000;
124142 +
124143 + if ((msecs*HZ)%1000)
124144 + tmp_jiffies++;
124145 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
124146 +}
124147 +
124148 +int XX_TimerIsActive(t_Handle h_Timer)
124149 +{
124150 + return timer_pending((struct timer_list *)h_Timer);
124151 +}
124152 +
124153 +uint32_t XX_Sleep(uint32_t msecs)
124154 +{
124155 + int tmp_jiffies = (msecs*HZ)/1000;
124156 +
124157 + if ((msecs*HZ)%1000)
124158 + tmp_jiffies++;
124159 + return schedule_timeout(tmp_jiffies);
124160 +}
124161 +
124162 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
124163 +void XX_UDelay(uint32_t usecs)
124164 +{
124165 + udelay(usecs);
124166 +}
124167 +
124168 +/* TODO: verify that these are correct */
124169 +#define MSG_BODY_SIZE 512
124170 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
124171 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
124172 +t_Error XX_SendMessage(char *p_DestAddr,
124173 + uint32_t msgId,
124174 + uint8_t msgBody[MSG_BODY_SIZE],
124175 + t_MsgCompletionCB *f_CompletionCB,
124176 + t_Handle h_CBArg);
124177 +
124178 +typedef struct {
124179 + char *p_Addr;
124180 + t_MsgHandler *f_MsgHandlerCB;
124181 + t_Handle h_Mod;
124182 + t_List node;
124183 +} t_MsgHndlr;
124184 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
124185 +
124186 +LIST(msgHndlrList);
124187 +
124188 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
124189 +{
124190 + uint32_t intFlags;
124191 +
124192 + intFlags = XX_DisableAllIntr();
124193 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
124194 + XX_RestoreAllIntr(intFlags);
124195 +}
124196 +/* TODO: add this for multi-platform support
124197 +static t_MsgHndlr * DequeueMsgHndlr(void)
124198 +{
124199 + t_MsgHndlr *p_MsgHndlr = NULL;
124200 + uint32_t intFlags;
124201 +
124202 + intFlags = XX_DisableAllIntr();
124203 + if (!LIST_IsEmpty(&msgHndlrList))
124204 + {
124205 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
124206 + LIST_DelAndInit(&p_MsgHndlr->node);
124207 + }
124208 + XX_RestoreAllIntr(intFlags);
124209 +
124210 + return p_MsgHndlr;
124211 +}
124212 +*/
124213 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
124214 +{
124215 + t_MsgHndlr *p_MsgHndlr;
124216 + t_List *p_Pos;
124217 +
124218 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
124219 + {
124220 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
124221 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
124222 + return p_MsgHndlr;
124223 + }
124224 +
124225 + return NULL;
124226 +}
124227 +
124228 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124229 +{
124230 + t_MsgHndlr *p_MsgHndlr;
124231 + uint32_t len;
124232 +
124233 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124234 + if (!p_MsgHndlr)
124235 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
124236 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
124237 +
124238 + len = strlen(p_Addr);
124239 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
124240 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
124241 +
124242 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
124243 + p_MsgHndlr->h_Mod = h_Mod;
124244 + INIT_LIST(&p_MsgHndlr->node);
124245 + EnqueueMsgHndlr(p_MsgHndlr);
124246 +
124247 + return E_OK;
124248 +}
124249 +
124250 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
124251 +{
124252 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
124253 + if (!p_MsgHndlr)
124254 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124255 +
124256 + LIST_Del(&p_MsgHndlr->node);
124257 + XX_Free(p_MsgHndlr->p_Addr);
124258 + XX_Free(p_MsgHndlr);
124259 +
124260 + return E_OK;
124261 +}
124262 +
124263 +t_Error XX_SendMessage(char *p_DestAddr,
124264 + uint32_t msgId,
124265 + uint8_t msgBody[MSG_BODY_SIZE],
124266 + t_MsgCompletionCB *f_CompletionCB,
124267 + t_Handle h_CBArg)
124268 +{
124269 + t_Error ans;
124270 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
124271 + if (!p_MsgHndlr)
124272 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
124273 +
124274 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
124275 +
124276 + if (f_CompletionCB)
124277 + f_CompletionCB(h_CBArg, msgBody);
124278 +
124279 + return ans;
124280 +}
124281 +
124282 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124283 + t_IpcMsgHandler *f_MsgHandler,
124284 + t_Handle h_Module,
124285 + uint32_t replyLength)
124286 +{
124287 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
124288 + return E_OK;
124289 +}
124290 +
124291 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124292 +{
124293 + UNUSED(addr);
124294 + return E_OK;
124295 +}
124296 +
124297 +
124298 +t_Error XX_IpcSendMessage(t_Handle h_Session,
124299 + uint8_t *p_Msg,
124300 + uint32_t msgLength,
124301 + uint8_t *p_Reply,
124302 + uint32_t *p_ReplyLength,
124303 + t_IpcMsgCompletion *f_Completion,
124304 + t_Handle h_Arg)
124305 +{
124306 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
124307 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
124308 + return E_OK;
124309 +}
124310 +
124311 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
124312 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
124313 +{
124314 + UNUSED(destAddr); UNUSED(srcAddr);
124315 + return E_OK;
124316 +}
124317 +
124318 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
124319 +uint32_t E500_GetId(void)
124320 +{
124321 + return raw_smp_processor_id();
124322 +}
124323 +
124324 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
124325 +int GetDeviceIrqNum(int irq)
124326 +{
124327 + struct device_node *iPar;
124328 + struct irq_domain *irqHost;
124329 + uint32_t hwIrq;
124330 +
124331 + /* Get the interrupt controller */
124332 + iPar = of_find_node_by_name(NULL, "mpic");
124333 + hwIrq = 0;
124334 +
124335 + ASSERT_COND(iPar != NULL);
124336 + /* Get the irq host */
124337 + irqHost = irq_find_host(iPar);
124338 + of_node_put(iPar);
124339 +
124340 + /* Create irq mapping */
124341 + return irq_create_mapping(irqHost, hwIrq);
124342 +}
124343 +#else
124344 +#error "kernel not supported!!!"
124345 +#endif /* LINUX_VERSION_CODE */
124346 +
124347 +void * XX_PhysToVirt(physAddress_t addr)
124348 +{
124349 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
124350 +}
124351 +
124352 +physAddress_t XX_VirtToPhys(void * addr)
124353 +{
124354 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
124355 +}
124356 +
124357 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124358 +{
124359 + uintptr_t *returnCode, tmp;
124360 +
124361 + if (alignment < sizeof(uintptr_t))
124362 + alignment = sizeof(uintptr_t);
124363 + size += alignment + sizeof(returnCode);
124364 + tmp = (uintptr_t)xx_Malloc(size);
124365 + if (tmp == 0)
124366 + return NULL;
124367 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
124368 + *(returnCode - 1) = tmp;
124369 +
124370 + return (void*)returnCode;
124371 +}
124372 +
124373 +void xx_FreeSmart(void *p)
124374 +{
124375 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
124376 +}
124377 --- /dev/null
124378 +++ b/drivers/staging/fsl_qbman/Kconfig
124379 @@ -0,0 +1,228 @@
124380 +config FSL_SDK_DPA
124381 + bool "Freescale Datapath Queue and Buffer management"
124382 + depends on !FSL_DPAA
124383 + select FSL_QMAN_FQ_LOOKUP if PPC64
124384 + select FSL_QMAN_FQ_LOOKUP if ARM64
124385 +
124386 +
124387 +menu "Freescale Datapath QMan/BMan options"
124388 + depends on FSL_SDK_DPA
124389 +
124390 +config FSL_DPA_CHECKING
124391 + bool "additional driver checking"
124392 + default n
124393 + ---help---
124394 + Compiles in additional checks to sanity-check the drivers and any
124395 + use of it by other code. Not recommended for performance.
124396 +
124397 +config FSL_DPA_CAN_WAIT
124398 + bool
124399 + default y
124400 +
124401 +config FSL_DPA_CAN_WAIT_SYNC
124402 + bool
124403 + default y
124404 +
124405 +config FSL_DPA_PIRQ_FAST
124406 + bool
124407 + default y
124408 +
124409 +config FSL_DPA_PIRQ_SLOW
124410 + bool
124411 + default y
124412 +
124413 +config FSL_DPA_PORTAL_SHARE
124414 + bool
124415 + default y
124416 +
124417 +config FSL_SDK_BMAN
124418 + bool "Freescale Buffer Manager (BMan) support"
124419 + default y
124420 +
124421 +if FSL_SDK_BMAN
124422 +
124423 +config FSL_BMAN_CONFIG
124424 + bool "BMan device management"
124425 + default y
124426 + ---help---
124427 + If this linux image is running natively, you need this option. If this
124428 + linux image is running as a guest OS under the hypervisor, only one
124429 + guest OS ("the control plane") needs this option.
124430 +
124431 +config FSL_BMAN_TEST
124432 + tristate "BMan self-tests"
124433 + default n
124434 + ---help---
124435 + This option compiles self-test code for BMan.
124436 +
124437 +config FSL_BMAN_TEST_HIGH
124438 + bool "BMan high-level self-test"
124439 + depends on FSL_BMAN_TEST
124440 + default y
124441 + ---help---
124442 + This requires the presence of cpu-affine portals, and performs
124443 + high-level API testing with them (whichever portal(s) are affine to
124444 + the cpu(s) the test executes on).
124445 +
124446 +config FSL_BMAN_TEST_THRESH
124447 + bool "BMan threshold test"
124448 + depends on FSL_BMAN_TEST
124449 + default y
124450 + ---help---
124451 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
124452 + before multiple threads (one per cpu) create pool objects to track
124453 + depletion state changes. The pool is then drained to empty by a
124454 + "drainer" thread, and the other threads that they observe exactly
124455 + the depletion state changes that are expected.
124456 +
124457 +config FSL_BMAN_DEBUGFS
124458 + tristate "BMan debugfs interface"
124459 + depends on DEBUG_FS
124460 + default y
124461 + ---help---
124462 + This option compiles debugfs code for BMan.
124463 +
124464 +endif # FSL_SDK_BMAN
124465 +
124466 +config FSL_SDK_QMAN
124467 + bool "Freescale Queue Manager (QMan) support"
124468 + default y
124469 +
124470 +if FSL_SDK_QMAN
124471 +
124472 +config FSL_QMAN_POLL_LIMIT
124473 + int
124474 + default 32
124475 +
124476 +config FSL_QMAN_CONFIG
124477 + bool "QMan device management"
124478 + default y
124479 + ---help---
124480 + If this linux image is running natively, you need this option. If this
124481 + linux image is running as a guest OS under the hypervisor, only one
124482 + guest OS ("the control plane") needs this option.
124483 +
124484 +config FSL_QMAN_TEST
124485 + tristate "QMan self-tests"
124486 + default n
124487 + ---help---
124488 + This option compiles self-test code for QMan.
124489 +
124490 +config FSL_QMAN_TEST_STASH_POTATO
124491 + bool "QMan 'hot potato' data-stashing self-test"
124492 + depends on FSL_QMAN_TEST
124493 + default y
124494 + ---help---
124495 + This performs a "hot potato" style test enqueuing/dequeuing a frame
124496 + across a series of FQs scheduled to different portals (and cpus), with
124497 + DQRR, data and context stashing always on.
124498 +
124499 +config FSL_QMAN_TEST_HIGH
124500 + bool "QMan high-level self-test"
124501 + depends on FSL_QMAN_TEST
124502 + default y
124503 + ---help---
124504 + This requires the presence of cpu-affine portals, and performs
124505 + high-level API testing with them (whichever portal(s) are affine to
124506 + the cpu(s) the test executes on).
124507 +
124508 +config FSL_QMAN_DEBUGFS
124509 + tristate "QMan debugfs interface"
124510 + depends on DEBUG_FS
124511 + default y
124512 + ---help---
124513 + This option compiles debugfs code for QMan.
124514 +
124515 +# H/w settings that can be hard-coded for now.
124516 +config FSL_QMAN_FQD_SZ
124517 + int "size of Frame Queue Descriptor region"
124518 + default 10
124519 + ---help---
124520 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
124521 + ex: 10 => PAGE_SIZE * (2^10)
124522 + Note: Default device-trees now require minimum Kconfig setting of 10.
124523 +
124524 +config FSL_QMAN_PFDR_SZ
124525 + int "size of the PFDR pool"
124526 + default 13
124527 + ---help---
124528 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
124529 + ex: 13 => PAGE_SIZE * (2^13)
124530 +
124531 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
124532 +# ability to snart. Stash priority is 3, other priorities are 2.
124533 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
124534 + int
124535 + depends on FSL_QMAN_CONFIG
124536 + default 4
124537 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
124538 + int
124539 + depends on FSL_QMAN_CONFIG
124540 + default 3
124541 +config FSL_QMAN_CI_SCHED_CFG_RW_W
124542 + int
124543 + depends on FSL_QMAN_CONFIG
124544 + default 2
124545 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
124546 + int
124547 + depends on FSL_QMAN_CONFIG
124548 + default 2
124549 +
124550 +# portal interrupt settings
124551 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
124552 + int
124553 + default 12
124554 +config FSL_QMAN_PIRQ_MR_ITHRESH
124555 + int
124556 + default 4
124557 +config FSL_QMAN_PIRQ_IPERIOD
124558 + int
124559 + default 100
124560 +
124561 +# 64 bit kernel support
124562 +config FSL_QMAN_FQ_LOOKUP
124563 + bool
124564 + default n
124565 +
124566 +config QMAN_CEETM_UPDATE_PERIOD
124567 + int "Token update period for shaping, in nanoseconds"
124568 + default 1000
124569 + ---help---
124570 + Traffic shaping works by performing token calculations (using
124571 + credits) on shaper instances periodically. This update period
124572 + sets the granularity for how often those token rate credit
124573 + updates are performed, and thus determines the accuracy and
124574 + range of traffic rates that can be configured by users. The
124575 + reference manual recommends a 1 microsecond period as providing
124576 + a good balance between granularity and range.
124577 +
124578 + Unless you know what you are doing, leave this value at its default.
124579 +
124580 +config FSL_QMAN_INIT_TIMEOUT
124581 + int "timeout for qman init stage, in seconds"
124582 + default 10
124583 + ---help---
124584 + The timeout setting to quit the initialization loop for non-control
124585 + partition in case the control partition fails to boot-up.
124586 +
124587 +endif # FSL_SDK_QMAN
124588 +
124589 +config FSL_USDPAA
124590 + bool "Freescale USDPAA process driver"
124591 + depends on FSL_SDK_DPA
124592 + default y
124593 + ---help---
124594 + This driver provides user-space access to kernel-managed
124595 + resource interfaces for USDPAA applications, on the assumption
124596 + that each process will open this device once. Specifically, this
124597 + device exposes functionality that would be awkward if exposed
124598 + via the portal devices - ie. this device exposes functionality
124599 + that is inherently process-wide rather than portal-specific.
124600 + This device is necessary for obtaining access to DMA memory and
124601 + for allocation of Qman and Bman resources. In short, if you wish
124602 + to use USDPAA applications, you need this.
124603 +
124604 + If unsure, say Y.
124605 +
124606 +
124607 +endmenu
124608 --- /dev/null
124609 +++ b/drivers/staging/fsl_qbman/Makefile
124610 @@ -0,0 +1,28 @@
124611 +subdir-ccflags-y := -Werror
124612 +
124613 +# Common
124614 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
124615 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
124616 +
124617 +# Bman
124618 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
124619 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
124620 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
124621 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
124622 +bman_tester-y = bman_test.o
124623 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
124624 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
124625 +bman_debugfs_interface-y = bman_debugfs.o
124626 +
124627 +# Qman
124628 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
124629 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
124630 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
124631 +qman_tester-y = qman_test.o
124632 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
124633 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
124634 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
124635 +qman_debugfs_interface-y = qman_debugfs.o
124636 +
124637 +# USDPAA
124638 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
124639 --- /dev/null
124640 +++ b/drivers/staging/fsl_qbman/bman_config.c
124641 @@ -0,0 +1,720 @@
124642 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
124643 + *
124644 + * Redistribution and use in source and binary forms, with or without
124645 + * modification, are permitted provided that the following conditions are met:
124646 + * * Redistributions of source code must retain the above copyright
124647 + * notice, this list of conditions and the following disclaimer.
124648 + * * Redistributions in binary form must reproduce the above copyright
124649 + * notice, this list of conditions and the following disclaimer in the
124650 + * documentation and/or other materials provided with the distribution.
124651 + * * Neither the name of Freescale Semiconductor nor the
124652 + * names of its contributors may be used to endorse or promote products
124653 + * derived from this software without specific prior written permission.
124654 + *
124655 + *
124656 + * ALTERNATIVELY, this software may be distributed under the terms of the
124657 + * GNU General Public License ("GPL") as published by the Free Software
124658 + * Foundation, either version 2 of that License or (at your option) any
124659 + * later version.
124660 + *
124661 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124662 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124663 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124664 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124665 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124666 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124667 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124668 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124669 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124670 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124671 + */
124672 +
124673 +#include <asm/cacheflush.h>
124674 +#include "bman_private.h"
124675 +#include <linux/of_reserved_mem.h>
124676 +
124677 +/* Last updated for v00.79 of the BG */
124678 +
124679 +struct bman;
124680 +
124681 +/* Register offsets */
124682 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
124683 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
124684 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
124685 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
124686 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
124687 +#define REG_FBPR_FPC 0x0800
124688 +#define REG_STATE_IDLE 0x960
124689 +#define REG_STATE_STOP 0x964
124690 +#define REG_ECSR 0x0a00
124691 +#define REG_ECIR 0x0a04
124692 +#define REG_EADR 0x0a08
124693 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
124694 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
124695 +#define REG_IP_REV_1 0x0bf8
124696 +#define REG_IP_REV_2 0x0bfc
124697 +#define REG_FBPR_BARE 0x0c00
124698 +#define REG_FBPR_BAR 0x0c04
124699 +#define REG_FBPR_AR 0x0c10
124700 +#define REG_SRCIDR 0x0d04
124701 +#define REG_LIODNR 0x0d08
124702 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
124703 +
124704 +/* Used by all error interrupt registers except 'inhibit' */
124705 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
124706 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
124707 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
124708 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
124709 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
124710 +
124711 +/* BMAN_ECIR valid error bit */
124712 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
124713 +
124714 +union bman_ecir {
124715 + u32 ecir_raw;
124716 + struct {
124717 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124718 + u32 __reserved1:4;
124719 + u32 portal_num:4;
124720 + u32 __reserved2:12;
124721 + u32 numb:4;
124722 + u32 __reserved3:2;
124723 + u32 pid:6;
124724 +#else
124725 + u32 pid:6;
124726 + u32 __reserved3:2;
124727 + u32 numb:4;
124728 + u32 __reserved2:12;
124729 + u32 portal_num:4;
124730 + u32 __reserved1:4;
124731 +#endif
124732 + } __packed info;
124733 +};
124734 +
124735 +union bman_eadr {
124736 + u32 eadr_raw;
124737 + struct {
124738 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
124739 + u32 __reserved1:5;
124740 + u32 memid:3;
124741 + u32 __reserved2:14;
124742 + u32 eadr:10;
124743 +#else
124744 + u32 eadr:10;
124745 + u32 __reserved2:14;
124746 + u32 memid:3;
124747 + u32 __reserved1:5;
124748 +#endif
124749 + } __packed info;
124750 +};
124751 +
124752 +struct bman_hwerr_txt {
124753 + u32 mask;
124754 + const char *txt;
124755 +};
124756 +
124757 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
124758 +
124759 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
124760 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
124761 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
124762 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
124763 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
124764 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
124765 +};
124766 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
124767 +
124768 +struct bman_error_info_mdata {
124769 + u16 addr_mask;
124770 + u16 bits;
124771 + const char *txt;
124772 +};
124773 +
124774 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
124775 +static const struct bman_error_info_mdata error_mdata[] = {
124776 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
124777 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
124778 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
124779 +};
124780 +#define BMAN_ERR_MDATA_COUNT \
124781 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
124782 +
124783 +/* Add this in Kconfig */
124784 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
124785 +
124786 +/**
124787 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
124788 + * @v: for accessors that write values, this is the 32-bit value
124789 + *
124790 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
124791 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
124792 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
124793 + * "write the enable register" rather than "enable the write register"!
124794 + */
124795 +#define bm_err_isr_status_read(bm) \
124796 + __bm_err_isr_read(bm, bm_isr_status)
124797 +#define bm_err_isr_status_clear(bm, m) \
124798 + __bm_err_isr_write(bm, bm_isr_status, m)
124799 +#define bm_err_isr_enable_read(bm) \
124800 + __bm_err_isr_read(bm, bm_isr_enable)
124801 +#define bm_err_isr_enable_write(bm, v) \
124802 + __bm_err_isr_write(bm, bm_isr_enable, v)
124803 +#define bm_err_isr_disable_read(bm) \
124804 + __bm_err_isr_read(bm, bm_isr_disable)
124805 +#define bm_err_isr_disable_write(bm, v) \
124806 + __bm_err_isr_write(bm, bm_isr_disable, v)
124807 +#define bm_err_isr_inhibit(bm) \
124808 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
124809 +#define bm_err_isr_uninhibit(bm) \
124810 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
124811 +
124812 +/*
124813 + * TODO: unimplemented registers
124814 + *
124815 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
124816 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
124817 + */
124818 +
124819 +/* Encapsulate "struct bman *" as a cast of the register space address. */
124820 +
124821 +static struct bman *bm_create(void *regs)
124822 +{
124823 + return (struct bman *)regs;
124824 +}
124825 +
124826 +static inline u32 __bm_in(struct bman *bm, u32 offset)
124827 +{
124828 + return in_be32((void *)bm + offset);
124829 +}
124830 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
124831 +{
124832 + out_be32((void *)bm + offset, val);
124833 +}
124834 +#define bm_in(reg) __bm_in(bm, REG_##reg)
124835 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
124836 +
124837 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
124838 +{
124839 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
124840 +}
124841 +
124842 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
124843 +{
124844 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
124845 +}
124846 +
124847 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
124848 +{
124849 + u32 v = bm_in(IP_REV_1);
124850 + *id = (v >> 16);
124851 + *major = (v >> 8) & 0xff;
124852 + *minor = v & 0xff;
124853 +}
124854 +
124855 +static u32 __generate_thresh(u32 val, int roundup)
124856 +{
124857 + u32 e = 0; /* co-efficient, exponent */
124858 + int oddbit = 0;
124859 + while (val > 0xff) {
124860 + oddbit = val & 1;
124861 + val >>= 1;
124862 + e++;
124863 + if (roundup && oddbit)
124864 + val++;
124865 + }
124866 + DPA_ASSERT(e < 0x10);
124867 + return val | (e << 8);
124868 +}
124869 +
124870 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
124871 + u32 hwdet, u32 hwdxt)
124872 +{
124873 + DPA_ASSERT(pool < bman_pool_max);
124874 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
124875 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
124876 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
124877 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
124878 +}
124879 +
124880 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
124881 +{
124882 + u32 exp = ilog2(size);
124883 + /* choke if size isn't within range */
124884 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
124885 + is_power_of_2(size));
124886 + /* choke if '[e]ba' has lower-alignment than 'size' */
124887 + DPA_ASSERT(!(ba & (size - 1)));
124888 + bm_out(FBPR_BARE, upper_32_bits(ba));
124889 + bm_out(FBPR_BAR, lower_32_bits(ba));
124890 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
124891 +}
124892 +
124893 +/*****************/
124894 +/* Config driver */
124895 +/*****************/
124896 +
124897 +/* TODO: Kconfig these? */
124898 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
124899 +
124900 +/* We support only one of these. */
124901 +static struct bman *bm;
124902 +static struct device_node *bm_node;
124903 +
124904 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
124905 + * during bman_init_ccsr(). */
124906 +static dma_addr_t fbpr_a;
124907 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
124908 +
124909 +static int bman_fbpr(struct reserved_mem *rmem)
124910 +{
124911 + fbpr_a = rmem->base;
124912 + fbpr_sz = rmem->size;
124913 +
124914 + WARN_ON(!(fbpr_a && fbpr_sz));
124915 +
124916 + return 0;
124917 +}
124918 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
124919 +
124920 +static int __init fsl_bman_init(struct device_node *node)
124921 +{
124922 + struct resource res;
124923 + u32 __iomem *regs;
124924 + const char *s;
124925 + int ret, standby = 0;
124926 + u16 id;
124927 + u8 major, minor;
124928 +
124929 + ret = of_address_to_resource(node, 0, &res);
124930 + if (ret) {
124931 + pr_err("Can't get %s property 'reg'\n",
124932 + node->full_name);
124933 + return ret;
124934 + }
124935 + s = of_get_property(node, "fsl,hv-claimable", &ret);
124936 + if (s && !strcmp(s, "standby"))
124937 + standby = 1;
124938 + /* Global configuration */
124939 + regs = ioremap(res.start, res.end - res.start + 1);
124940 + bm = bm_create(regs);
124941 + BUG_ON(!bm);
124942 + bm_node = node;
124943 + bm_get_version(bm, &id, &major, &minor);
124944 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
124945 + if ((major == 1) && (minor == 0)) {
124946 + bman_ip_rev = BMAN_REV10;
124947 + bman_pool_max = 64;
124948 + } else if ((major == 2) && (minor == 0)) {
124949 + bman_ip_rev = BMAN_REV20;
124950 + bman_pool_max = 8;
124951 + } else if ((major == 2) && (minor == 1)) {
124952 + bman_ip_rev = BMAN_REV21;
124953 + bman_pool_max = 64;
124954 + } else {
124955 + pr_warn("unknown Bman version, default to rev1.0\n");
124956 + }
124957 +
124958 + if (standby) {
124959 + pr_info(" -> in standby mode\n");
124960 + return 0;
124961 + }
124962 + return 0;
124963 +}
124964 +
124965 +int bman_have_ccsr(void)
124966 +{
124967 + return bm ? 1 : 0;
124968 +}
124969 +
124970 +int bm_pool_set(u32 bpid, const u32 *thresholds)
124971 +{
124972 + if (!bm)
124973 + return -ENODEV;
124974 + bm_set_pool(bm, bpid, thresholds[0],
124975 + thresholds[1], thresholds[2],
124976 + thresholds[3]);
124977 + return 0;
124978 +}
124979 +EXPORT_SYMBOL(bm_pool_set);
124980 +
124981 +__init int bman_init_early(void)
124982 +{
124983 + struct device_node *dn;
124984 + int ret;
124985 +
124986 + for_each_compatible_node(dn, NULL, "fsl,bman") {
124987 + if (bm)
124988 + pr_err("%s: only one 'fsl,bman' allowed\n",
124989 + dn->full_name);
124990 + else {
124991 + if (!of_device_is_available(dn))
124992 + continue;
124993 +
124994 + ret = fsl_bman_init(dn);
124995 + BUG_ON(ret);
124996 + }
124997 + }
124998 + return 0;
124999 +}
125000 +postcore_initcall_sync(bman_init_early);
125001 +
125002 +
125003 +static void log_edata_bits(u32 bit_count)
125004 +{
125005 + u32 i, j, mask = 0xffffffff;
125006 +
125007 + pr_warn("Bman ErrInt, EDATA:\n");
125008 + i = bit_count/32;
125009 + if (bit_count%32) {
125010 + i++;
125011 + mask = ~(mask << bit_count%32);
125012 + }
125013 + j = 16-i;
125014 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
125015 + j++;
125016 + for (; j < 16; j++)
125017 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
125018 +}
125019 +
125020 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
125021 +{
125022 + union bman_ecir ecir_val;
125023 + union bman_eadr eadr_val;
125024 +
125025 + ecir_val.ecir_raw = bm_in(ECIR);
125026 + /* Is portal info valid */
125027 + if (ecsr_val & PORTAL_ECSR_ERR) {
125028 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
125029 + ecir_val.info.portal_num, ecir_val.info.numb,
125030 + ecir_val.info.pid);
125031 + }
125032 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
125033 + eadr_val.eadr_raw = bm_in(EADR);
125034 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
125035 + error_mdata[eadr_val.info.memid].txt,
125036 + error_mdata[eadr_val.info.memid].addr_mask
125037 + & eadr_val.info.eadr);
125038 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
125039 + }
125040 +}
125041 +
125042 +/* Bman interrupt handler */
125043 +static irqreturn_t bman_isr(int irq, void *ptr)
125044 +{
125045 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
125046 +
125047 + ier_val = bm_err_isr_enable_read(bm);
125048 + isr_val = bm_err_isr_status_read(bm);
125049 + ecsr_val = bm_in(ECSR);
125050 + isr_mask = isr_val & ier_val;
125051 +
125052 + if (!isr_mask)
125053 + return IRQ_NONE;
125054 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
125055 + if (bman_hwerr_txts[i].mask & isr_mask) {
125056 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
125057 + if (bman_hwerr_txts[i].mask & ecsr_val) {
125058 + log_additional_error_info(isr_mask, ecsr_val);
125059 + /* Re-arm error capture registers */
125060 + bm_out(ECSR, ecsr_val);
125061 + }
125062 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
125063 + pr_devel("Bman un-enabling error 0x%x\n",
125064 + bman_hwerr_txts[i].mask);
125065 + ier_val &= ~bman_hwerr_txts[i].mask;
125066 + bm_err_isr_enable_write(bm, ier_val);
125067 + }
125068 + }
125069 + }
125070 + bm_err_isr_status_clear(bm, isr_val);
125071 + return IRQ_HANDLED;
125072 +}
125073 +
125074 +static int __bind_irq(void)
125075 +{
125076 + int ret, err_irq;
125077 +
125078 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
125079 + if (err_irq == 0) {
125080 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
125081 + "interrupts");
125082 + return -ENODEV;
125083 + }
125084 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
125085 + if (ret) {
125086 + pr_err("request_irq() failed %d for '%s'\n", ret,
125087 + bm_node->full_name);
125088 + return -ENODEV;
125089 + }
125090 + /* Disable Buffer Pool State Change */
125091 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
125092 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
125093 + * to resource allocation during driver init). */
125094 + bm_err_isr_status_clear(bm, 0xffffffff);
125095 + /* Enable Error Interrupts */
125096 + bm_err_isr_enable_write(bm, 0xffffffff);
125097 + return 0;
125098 +}
125099 +
125100 +int bman_init_ccsr(struct device_node *node)
125101 +{
125102 + int ret;
125103 + if (!bman_have_ccsr())
125104 + return 0;
125105 + if (node != bm_node)
125106 + return -EINVAL;
125107 + /* FBPR memory */
125108 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
125109 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
125110 +
125111 + ret = __bind_irq();
125112 + if (ret)
125113 + return ret;
125114 + return 0;
125115 +}
125116 +
125117 +u32 bm_pool_free_buffers(u32 bpid)
125118 +{
125119 + return bm_in(POOL_CONTENT(bpid));
125120 +}
125121 +
125122 +#ifdef CONFIG_SYSFS
125123 +
125124 +#define DRV_NAME "fsl-bman"
125125 +#define SBEC_MAX_ID 1
125126 +#define SBEC_MIN_ID 0
125127 +
125128 +static ssize_t show_fbpr_fpc(struct device *dev,
125129 + struct device_attribute *dev_attr, char *buf)
125130 +{
125131 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
125132 +};
125133 +
125134 +static ssize_t show_pool_count(struct device *dev,
125135 + struct device_attribute *dev_attr, char *buf)
125136 +{
125137 + u32 data;
125138 + int i;
125139 +
125140 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
125141 + return -EINVAL;
125142 + data = bm_in(POOL_CONTENT(i));
125143 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
125144 +};
125145 +
125146 +static ssize_t show_err_isr(struct device *dev,
125147 + struct device_attribute *dev_attr, char *buf)
125148 +{
125149 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
125150 +};
125151 +
125152 +static ssize_t show_sbec(struct device *dev,
125153 + struct device_attribute *dev_attr, char *buf)
125154 +{
125155 + int i;
125156 +
125157 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
125158 + return -EINVAL;
125159 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
125160 + return -EINVAL;
125161 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
125162 +};
125163 +
125164 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
125165 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
125166 +
125167 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
125168 + * Initialize them when needed. */
125169 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
125170 +static struct device_attribute *dev_attr_buffer_pool_count;
125171 +
125172 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
125173 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
125174 +
125175 +static struct attribute *bman_dev_attributes[] = {
125176 + &dev_attr_fbpr_fpc.attr,
125177 + &dev_attr_err_isr.attr,
125178 + NULL
125179 +};
125180 +
125181 +static struct attribute *bman_dev_ecr_attributes[] = {
125182 + &dev_attr_sbec_0.attr,
125183 + &dev_attr_sbec_1.attr,
125184 + NULL
125185 +};
125186 +
125187 +static struct attribute **bman_dev_pool_count_attributes;
125188 +
125189 +
125190 +/* root level */
125191 +static const struct attribute_group bman_dev_attr_grp = {
125192 + .name = NULL,
125193 + .attrs = bman_dev_attributes
125194 +};
125195 +static const struct attribute_group bman_dev_ecr_grp = {
125196 + .name = "error_capture",
125197 + .attrs = bman_dev_ecr_attributes
125198 +};
125199 +static struct attribute_group bman_dev_pool_countent_grp = {
125200 + .name = "pool_count",
125201 +};
125202 +
125203 +static int of_fsl_bman_remove(struct platform_device *ofdev)
125204 +{
125205 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125206 + return 0;
125207 +};
125208 +
125209 +static int of_fsl_bman_probe(struct platform_device *ofdev)
125210 +{
125211 + int ret, i;
125212 +
125213 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125214 + if (ret)
125215 + goto done;
125216 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125217 + if (ret)
125218 + goto del_group_0;
125219 +
125220 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
125221 + GFP_KERNEL);
125222 + if (!name_attrs_pool_count) {
125223 + pr_err("Can't alloc name_attrs_pool_count\n");
125224 + goto del_group_1;
125225 + }
125226 +
125227 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
125228 + bman_pool_max, GFP_KERNEL);
125229 + if (!dev_attr_buffer_pool_count) {
125230 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
125231 + goto del_group_2;
125232 + }
125233 +
125234 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
125235 + (bman_pool_max + 1), GFP_KERNEL);
125236 + if (!bman_dev_pool_count_attributes) {
125237 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
125238 + goto del_group_3;
125239 + }
125240 +
125241 + for (i = 0; i < bman_pool_max; i++) {
125242 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
125243 + if (!ret)
125244 + goto del_group_4;
125245 + dev_attr_buffer_pool_count[i].attr.name =
125246 + (name_attrs_pool_count + i * 3);
125247 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
125248 + dev_attr_buffer_pool_count[i].show = show_pool_count;
125249 + bman_dev_pool_count_attributes[i] =
125250 + &dev_attr_buffer_pool_count[i].attr;
125251 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
125252 + }
125253 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
125254 +
125255 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
125256 +
125257 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
125258 + if (ret)
125259 + goto del_group_4;
125260 +
125261 + goto done;
125262 +
125263 +del_group_4:
125264 + kfree(bman_dev_pool_count_attributes);
125265 +del_group_3:
125266 + kfree(dev_attr_buffer_pool_count);
125267 +del_group_2:
125268 + kfree(name_attrs_pool_count);
125269 +del_group_1:
125270 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
125271 +del_group_0:
125272 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
125273 +done:
125274 + if (ret)
125275 + dev_err(&ofdev->dev,
125276 + "Cannot create dev attributes ret=%d\n", ret);
125277 + return ret;
125278 +};
125279 +
125280 +static struct of_device_id of_fsl_bman_ids[] = {
125281 + {
125282 + .compatible = "fsl,bman",
125283 + },
125284 + {}
125285 +};
125286 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
125287 +
125288 +#ifdef CONFIG_SUSPEND
125289 +static u32 saved_isdr;
125290 +
125291 +static int bman_pm_suspend_noirq(struct device *dev)
125292 +{
125293 + uint32_t idle_state;
125294 +
125295 + suspend_unused_bportal();
125296 + /* save isdr, disable all, clear isr */
125297 + saved_isdr = bm_err_isr_disable_read(bm);
125298 + bm_err_isr_disable_write(bm, 0xffffffff);
125299 + bm_err_isr_status_clear(bm, 0xffffffff);
125300 +
125301 + if (bman_ip_rev < BMAN_REV21) {
125302 +#ifdef CONFIG_PM_DEBUG
125303 + pr_info("Bman version doesn't have STATE_IDLE\n");
125304 +#endif
125305 + return 0;
125306 + }
125307 + idle_state = bm_in(STATE_IDLE);
125308 + if (!(idle_state & 0x1)) {
125309 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
125310 + bm_err_isr_disable_write(bm, saved_isdr);
125311 + resume_unused_bportal();
125312 + return -EBUSY;
125313 + }
125314 +#ifdef CONFIG_PM_DEBUG
125315 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
125316 +#endif
125317 + return 0;
125318 +}
125319 +
125320 +static int bman_pm_resume_noirq(struct device *dev)
125321 +{
125322 + /* restore isdr */
125323 + bm_err_isr_disable_write(bm, saved_isdr);
125324 + resume_unused_bportal();
125325 + return 0;
125326 +}
125327 +#else
125328 +#define bman_pm_suspend_noirq NULL
125329 +#define bman_pm_resume_noirq NULL
125330 +#endif
125331 +
125332 +static const struct dev_pm_ops bman_pm_ops = {
125333 + .suspend_noirq = bman_pm_suspend_noirq,
125334 + .resume_noirq = bman_pm_resume_noirq,
125335 +};
125336 +
125337 +static struct platform_driver of_fsl_bman_driver = {
125338 + .driver = {
125339 + .owner = THIS_MODULE,
125340 + .name = DRV_NAME,
125341 + .of_match_table = of_fsl_bman_ids,
125342 + .pm = &bman_pm_ops,
125343 + },
125344 + .probe = of_fsl_bman_probe,
125345 + .remove = of_fsl_bman_remove,
125346 +};
125347 +
125348 +static int bman_ctrl_init(void)
125349 +{
125350 + return platform_driver_register(&of_fsl_bman_driver);
125351 +}
125352 +
125353 +static void bman_ctrl_exit(void)
125354 +{
125355 + platform_driver_unregister(&of_fsl_bman_driver);
125356 +}
125357 +
125358 +module_init(bman_ctrl_init);
125359 +module_exit(bman_ctrl_exit);
125360 +
125361 +#endif /* CONFIG_SYSFS */
125362 --- /dev/null
125363 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
125364 @@ -0,0 +1,119 @@
125365 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
125366 + *
125367 + * Redistribution and use in source and binary forms, with or without
125368 + * modification, are permitted provided that the following conditions are met:
125369 + * * Redistributions of source code must retain the above copyright
125370 + * notice, this list of conditions and the following disclaimer.
125371 + * * Redistributions in binary form must reproduce the above copyright
125372 + * notice, this list of conditions and the following disclaimer in the
125373 + * documentation and/or other materials provided with the distribution.
125374 + * * Neither the name of Freescale Semiconductor nor the
125375 + * names of its contributors may be used to endorse or promote products
125376 + * derived from this software without specific prior written permission.
125377 + *
125378 + *
125379 + * ALTERNATIVELY, this software may be distributed under the terms of the
125380 + * GNU General Public License ("GPL") as published by the Free Software
125381 + * Foundation, either version 2 of that License or (at your option) any
125382 + * later version.
125383 + *
125384 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125385 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125386 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125387 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125388 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125389 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125390 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125391 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125392 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125393 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125394 + */
125395 +#include <linux/module.h>
125396 +#include <linux/fsl_bman.h>
125397 +#include <linux/debugfs.h>
125398 +#include <linux/seq_file.h>
125399 +#include <linux/uaccess.h>
125400 +
125401 +static struct dentry *dfs_root; /* debugfs root directory */
125402 +
125403 +/*******************************************************************************
125404 + * Query Buffer Pool State
125405 + ******************************************************************************/
125406 +static int query_bp_state_show(struct seq_file *file, void *offset)
125407 +{
125408 + int ret;
125409 + struct bm_pool_state state;
125410 + int i, j;
125411 + u32 mask;
125412 +
125413 + memset(&state, 0, sizeof(struct bm_pool_state));
125414 + ret = bman_query_pools(&state);
125415 + if (ret) {
125416 + seq_printf(file, "Error %d\n", ret);
125417 + return 0;
125418 + }
125419 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
125420 + for (i = 0; i < 2; i++) {
125421 + mask = 0x80000000;
125422 + for (j = 0; j < 32; j++) {
125423 + seq_printf(file,
125424 + " %-2u %-3s %-3s\n",
125425 + (i*32)+j,
125426 + (state.as.state.__state[i] & mask) ? "no" : "yes",
125427 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
125428 + mask >>= 1;
125429 + }
125430 + }
125431 + return 0;
125432 +}
125433 +
125434 +static int query_bp_state_open(struct inode *inode, struct file *file)
125435 +{
125436 + return single_open(file, query_bp_state_show, NULL);
125437 +}
125438 +
125439 +static const struct file_operations query_bp_state_fops = {
125440 + .owner = THIS_MODULE,
125441 + .open = query_bp_state_open,
125442 + .read = seq_read,
125443 + .release = single_release,
125444 +};
125445 +
125446 +static int __init bman_debugfs_module_init(void)
125447 +{
125448 + int ret = 0;
125449 + struct dentry *d;
125450 +
125451 + dfs_root = debugfs_create_dir("bman", NULL);
125452 +
125453 + if (dfs_root == NULL) {
125454 + ret = -ENOMEM;
125455 + pr_err("Cannot create bman debugfs dir\n");
125456 + goto _return;
125457 + }
125458 + d = debugfs_create_file("query_bp_state",
125459 + S_IRUGO,
125460 + dfs_root,
125461 + NULL,
125462 + &query_bp_state_fops);
125463 + if (d == NULL) {
125464 + ret = -ENOMEM;
125465 + pr_err("Cannot create query_bp_state\n");
125466 + goto _return;
125467 + }
125468 + return 0;
125469 +
125470 +_return:
125471 + debugfs_remove_recursive(dfs_root);
125472 + return ret;
125473 +}
125474 +
125475 +static void __exit bman_debugfs_module_exit(void)
125476 +{
125477 + debugfs_remove_recursive(dfs_root);
125478 +}
125479 +
125480 +
125481 +module_init(bman_debugfs_module_init);
125482 +module_exit(bman_debugfs_module_exit);
125483 +MODULE_LICENSE("Dual BSD/GPL");
125484 --- /dev/null
125485 +++ b/drivers/staging/fsl_qbman/bman_driver.c
125486 @@ -0,0 +1,575 @@
125487 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
125488 + *
125489 + * Redistribution and use in source and binary forms, with or without
125490 + * modification, are permitted provided that the following conditions are met:
125491 + * * Redistributions of source code must retain the above copyright
125492 + * notice, this list of conditions and the following disclaimer.
125493 + * * Redistributions in binary form must reproduce the above copyright
125494 + * notice, this list of conditions and the following disclaimer in the
125495 + * documentation and/or other materials provided with the distribution.
125496 + * * Neither the name of Freescale Semiconductor nor the
125497 + * names of its contributors may be used to endorse or promote products
125498 + * derived from this software without specific prior written permission.
125499 + *
125500 + *
125501 + * ALTERNATIVELY, this software may be distributed under the terms of the
125502 + * GNU General Public License ("GPL") as published by the Free Software
125503 + * Foundation, either version 2 of that License or (at your option) any
125504 + * later version.
125505 + *
125506 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125507 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125508 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125509 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125510 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125511 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125512 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125513 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125514 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125515 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125516 + */
125517 +#include "bman_low.h"
125518 +#ifdef CONFIG_HOTPLUG_CPU
125519 +#include <linux/cpu.h>
125520 +#endif
125521 +/*
125522 + * Global variables of the max portal/pool number this bman version supported
125523 + */
125524 +u16 bman_ip_rev;
125525 +EXPORT_SYMBOL(bman_ip_rev);
125526 +u16 bman_pool_max;
125527 +EXPORT_SYMBOL(bman_pool_max);
125528 +static u16 bman_portal_max;
125529 +
125530 +/* After initialising cpus that own shared portal configs, we cache the
125531 + * resulting portals (ie. not just the configs) in this array. Then we
125532 + * initialise slave cpus that don't have their own portals, redirecting them to
125533 + * portals from this cache in a round-robin assignment. */
125534 +static struct bman_portal *shared_portals[NR_CPUS];
125535 +static int num_shared_portals;
125536 +static int shared_portals_idx;
125537 +static LIST_HEAD(unused_pcfgs);
125538 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
125539 +static void *affine_bportals[NR_CPUS];
125540 +
125541 +static int __init fsl_bpool_init(struct device_node *node)
125542 +{
125543 + int ret;
125544 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
125545 + if (!bpid || (ret != 4)) {
125546 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
125547 + return -ENODEV;
125548 + }
125549 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
125550 + if (thresh) {
125551 + if (ret != 16) {
125552 + pr_err("Invalid %s property '%s'\n",
125553 + node->full_name, "fsl,bpool-thresholds");
125554 + return -ENODEV;
125555 + }
125556 + }
125557 + if (thresh) {
125558 +#ifdef CONFIG_FSL_BMAN_CONFIG
125559 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
125560 + if (ret)
125561 + pr_err("No CCSR node for %s property '%s'\n",
125562 + node->full_name, "fsl,bpool-thresholds");
125563 + return ret;
125564 +#else
125565 + pr_err("Ignoring %s property '%s', no CCSR support\n",
125566 + node->full_name, "fsl,bpool-thresholds");
125567 +#endif
125568 + }
125569 + return 0;
125570 +}
125571 +
125572 +static int __init fsl_bpid_range_init(struct device_node *node)
125573 +{
125574 + int ret;
125575 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
125576 + if (!range) {
125577 + pr_err("No 'fsl,bpid-range' property in node %s\n",
125578 + node->full_name);
125579 + return -EINVAL;
125580 + }
125581 + if (ret != 8) {
125582 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
125583 + node->full_name);
125584 + return -EINVAL;
125585 + }
125586 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125587 + pr_info("Bman: BPID allocator includes range %d:%d\n",
125588 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
125589 + return 0;
125590 +}
125591 +
125592 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
125593 +{
125594 + struct bm_portal_config *pcfg;
125595 + const u32 *index;
125596 + int irq, ret;
125597 + resource_size_t len;
125598 +
125599 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
125600 + if (!pcfg) {
125601 + pr_err("can't allocate portal config");
125602 + return NULL;
125603 + }
125604 +
125605 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
125606 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
125607 + bman_ip_rev = BMAN_REV10;
125608 + bman_pool_max = 64;
125609 + bman_portal_max = 10;
125610 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
125611 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
125612 + bman_ip_rev = BMAN_REV20;
125613 + bman_pool_max = 8;
125614 + bman_portal_max = 3;
125615 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
125616 + bman_ip_rev = BMAN_REV21;
125617 + bman_pool_max = 64;
125618 + bman_portal_max = 50;
125619 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
125620 + bman_ip_rev = BMAN_REV21;
125621 + bman_pool_max = 64;
125622 + bman_portal_max = 25;
125623 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
125624 + bman_ip_rev = BMAN_REV21;
125625 + bman_pool_max = 64;
125626 + bman_portal_max = 18;
125627 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
125628 + bman_ip_rev = BMAN_REV21;
125629 + bman_pool_max = 64;
125630 + bman_portal_max = 10;
125631 + } else {
125632 + pr_warn("unknown BMan version in portal node,"
125633 + "default to rev1.0\n");
125634 + bman_ip_rev = BMAN_REV10;
125635 + bman_pool_max = 64;
125636 + bman_portal_max = 10;
125637 + }
125638 +
125639 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
125640 + &pcfg->addr_phys[DPA_PORTAL_CE]);
125641 + if (ret) {
125642 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
125643 + goto err;
125644 + }
125645 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
125646 + &pcfg->addr_phys[DPA_PORTAL_CI]);
125647 + if (ret) {
125648 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
125649 + goto err;
125650 + }
125651 +
125652 + index = of_get_property(node, "cell-index", &ret);
125653 + if (!index || (ret != 4)) {
125654 + pr_err("Can't get %s property '%s'\n", node->full_name,
125655 + "cell-index");
125656 + goto err;
125657 + }
125658 + if (be32_to_cpu(*index) >= bman_portal_max) {
125659 + pr_err("BMan portal cell index %d out of range, max %d\n",
125660 + be32_to_cpu(*index), bman_portal_max);
125661 + goto err;
125662 + }
125663 +
125664 + pcfg->public_cfg.cpu = -1;
125665 +
125666 + irq = irq_of_parse_and_map(node, 0);
125667 + if (irq == 0) {
125668 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
125669 + goto err;
125670 + }
125671 + pcfg->public_cfg.irq = irq;
125672 + pcfg->public_cfg.index = be32_to_cpu(*index);
125673 + bman_depletion_fill(&pcfg->public_cfg.mask);
125674 +
125675 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
125676 + if (len != (unsigned long)len)
125677 + goto err;
125678 +
125679 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
125680 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
125681 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125682 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
125683 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
125684 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125685 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
125686 +
125687 +#else
125688 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
125689 + pcfg->addr_phys[DPA_PORTAL_CE].start,
125690 + (unsigned long)len,
125691 + 0);
125692 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
125693 + pcfg->addr_phys[DPA_PORTAL_CI].start,
125694 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
125695 + _PAGE_GUARDED | _PAGE_NO_CACHE);
125696 +#endif
125697 + /* disable bp depletion */
125698 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
125699 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
125700 + return pcfg;
125701 +err:
125702 + kfree(pcfg);
125703 + return NULL;
125704 +}
125705 +
125706 +static struct bm_portal_config *get_pcfg(struct list_head *list)
125707 +{
125708 + struct bm_portal_config *pcfg;
125709 + if (list_empty(list))
125710 + return NULL;
125711 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
125712 + list_del(&pcfg->list);
125713 + return pcfg;
125714 +}
125715 +
125716 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
125717 + uint32_t idx)
125718 +{
125719 + struct bm_portal_config *pcfg;
125720 + if (list_empty(list))
125721 + return NULL;
125722 + list_for_each_entry(pcfg, list, list) {
125723 + if (pcfg->public_cfg.index == idx) {
125724 + list_del(&pcfg->list);
125725 + return pcfg;
125726 + }
125727 + }
125728 + return NULL;
125729 +}
125730 +
125731 +struct bm_portal_config *bm_get_unused_portal(void)
125732 +{
125733 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
125734 +}
125735 +
125736 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
125737 +{
125738 + struct bm_portal_config *ret;
125739 + spin_lock(&unused_pcfgs_lock);
125740 + if (idx == QBMAN_ANY_PORTAL_IDX)
125741 + ret = get_pcfg(&unused_pcfgs);
125742 + else
125743 + ret = get_pcfg_idx(&unused_pcfgs, idx);
125744 + spin_unlock(&unused_pcfgs_lock);
125745 + return ret;
125746 +}
125747 +
125748 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
125749 +{
125750 + spin_lock(&unused_pcfgs_lock);
125751 + list_add(&pcfg->list, &unused_pcfgs);
125752 + spin_unlock(&unused_pcfgs_lock);
125753 +}
125754 +
125755 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
125756 +{
125757 + struct bman_portal *p;
125758 + p = bman_create_affine_portal(pcfg);
125759 + if (p) {
125760 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
125761 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
125762 +#endif
125763 + pr_info("Bman portal %sinitialised, cpu %d\n",
125764 + pcfg->public_cfg.is_shared ? "(shared) " : "",
125765 + pcfg->public_cfg.cpu);
125766 + affine_bportals[pcfg->public_cfg.cpu] = p;
125767 + } else
125768 + pr_crit("Bman portal failure on cpu %d\n",
125769 + pcfg->public_cfg.cpu);
125770 + return p;
125771 +}
125772 +
125773 +static void init_slave(int cpu)
125774 +{
125775 + struct bman_portal *p;
125776 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
125777 + if (!p)
125778 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
125779 + else
125780 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
125781 + if (shared_portals_idx >= num_shared_portals)
125782 + shared_portals_idx = 0;
125783 + affine_bportals[cpu] = p;
125784 +}
125785 +
125786 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
125787 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
125788 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
125789 + * explicitly mark it or them for sharing.
125790 + * Eg;
125791 + * bportals=s0,1-3,s4
125792 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
125793 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
125794 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
125795 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
125796 + * 0's portal.) */
125797 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
125798 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
125799 +
125800 +static int __init parse_bportals(char *str)
125801 +{
125802 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
125803 + "bportals");
125804 +}
125805 +__setup("bportals=", parse_bportals);
125806 +
125807 +static int bman_offline_cpu(unsigned int cpu)
125808 +{
125809 + struct bman_portal *p;
125810 + const struct bm_portal_config *pcfg;
125811 + p = (struct bman_portal *)affine_bportals[cpu];
125812 + if (p) {
125813 + pcfg = bman_get_bm_portal_config(p);
125814 + if (pcfg)
125815 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
125816 + }
125817 + return 0;
125818 +}
125819 +
125820 +#ifdef CONFIG_HOTPLUG_CPU
125821 +static int bman_online_cpu(unsigned int cpu)
125822 +{
125823 + struct bman_portal *p;
125824 + const struct bm_portal_config *pcfg;
125825 + p = (struct bman_portal *)affine_bportals[cpu];
125826 + if (p) {
125827 + pcfg = bman_get_bm_portal_config(p);
125828 + if (pcfg)
125829 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
125830 + }
125831 + return 0;
125832 +}
125833 +static int bman_hotplug_cpu_callback(struct notifier_block *nfb,
125834 + unsigned long action, void *hcpu)
125835 +{
125836 + unsigned int cpu = (unsigned long)hcpu;
125837 +
125838 + switch (action) {
125839 + case CPU_ONLINE:
125840 + case CPU_ONLINE_FROZEN:
125841 + bman_online_cpu(cpu);
125842 + break;
125843 + case CPU_DOWN_PREPARE:
125844 + case CPU_DOWN_PREPARE_FROZEN:
125845 + bman_offline_cpu(cpu);
125846 + default:
125847 + break;
125848 + }
125849 + return NOTIFY_OK;
125850 +}
125851 +
125852 +static struct notifier_block bman_hotplug_cpu_notifier = {
125853 + .notifier_call = bman_hotplug_cpu_callback,
125854 +};
125855 +#endif /* CONFIG_HOTPLUG_CPU */
125856 +
125857 +/* Initialise the Bman driver. The meat of this function deals with portals. The
125858 + * following describes the flow of portal-handling, the code "steps" refer to
125859 + * this description;
125860 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
125861 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
125862 + * bound).
125863 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
125864 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
125865 + * them to cpus, placing them in the relevant list and setting ::cpu as
125866 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
125867 + * assign portals to all online cpus at the time of driver initialisation.
125868 + * Any failure to allocate portals (when parsing the "want" lists or when
125869 + * using default behaviour) will be silently tolerated (the "fixup" logic in
125870 + * step 3 will determine what happens in this case).
125871 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
125872 + * sharing and sharing is required (because not all cpus have been assigned
125873 + * portals), then one portal will marked for sharing. Conversely if no
125874 + * sharing is required, any portals marked for sharing will not be shared. It
125875 + * may be that sharing occurs when it wasn't expected, if portal allocation
125876 + * failed to honour all the requested assignments (including the default
125877 + * assignments if no bootarg is present).
125878 + * 4. Unshared portals are initialised on their respective cpus.
125879 + * 5. Shared portals are initialised on their respective cpus.
125880 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
125881 + * which are selected in a round-robin fashion.
125882 + * Any portal configs left unused are available for USDPAA allocation.
125883 + */
125884 +__init int bman_init(void)
125885 +{
125886 + struct cpumask slave_cpus;
125887 + struct cpumask unshared_cpus = *cpu_none_mask;
125888 + struct cpumask shared_cpus = *cpu_none_mask;
125889 + LIST_HEAD(unshared_pcfgs);
125890 + LIST_HEAD(shared_pcfgs);
125891 + struct device_node *dn;
125892 + struct bm_portal_config *pcfg;
125893 + struct bman_portal *p;
125894 + int cpu, ret;
125895 + struct cpumask offline_cpus;
125896 +
125897 + /* Initialise the Bman (CCSR) device */
125898 + for_each_compatible_node(dn, NULL, "fsl,bman") {
125899 + if (!bman_init_ccsr(dn))
125900 + pr_info("Bman err interrupt handler present\n");
125901 + else
125902 + pr_err("Bman CCSR setup failed\n");
125903 + }
125904 + /* Initialise any declared buffer pools */
125905 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
125906 + ret = fsl_bpool_init(dn);
125907 + if (ret)
125908 + return ret;
125909 + }
125910 + /* Step 1. See comments at the beginning of the file. */
125911 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
125912 + if (!of_device_is_available(dn))
125913 + continue;
125914 + pcfg = parse_pcfg(dn);
125915 + if (pcfg)
125916 + list_add_tail(&pcfg->list, &unused_pcfgs);
125917 + }
125918 + /* Step 2. */
125919 + for_each_possible_cpu(cpu) {
125920 + if (cpumask_test_cpu(cpu, &want_shared)) {
125921 + pcfg = get_pcfg(&unused_pcfgs);
125922 + if (!pcfg)
125923 + break;
125924 + pcfg->public_cfg.cpu = cpu;
125925 + list_add_tail(&pcfg->list, &shared_pcfgs);
125926 + cpumask_set_cpu(cpu, &shared_cpus);
125927 + }
125928 + if (cpumask_test_cpu(cpu, &want_unshared)) {
125929 + if (cpumask_test_cpu(cpu, &shared_cpus))
125930 + continue;
125931 + pcfg = get_pcfg(&unused_pcfgs);
125932 + if (!pcfg)
125933 + break;
125934 + pcfg->public_cfg.cpu = cpu;
125935 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125936 + cpumask_set_cpu(cpu, &unshared_cpus);
125937 + }
125938 + }
125939 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
125940 + /* Default, give an unshared portal to each online cpu */
125941 + for_each_online_cpu(cpu) {
125942 + pcfg = get_pcfg(&unused_pcfgs);
125943 + if (!pcfg)
125944 + break;
125945 + pcfg->public_cfg.cpu = cpu;
125946 + list_add_tail(&pcfg->list, &unshared_pcfgs);
125947 + cpumask_set_cpu(cpu, &unshared_cpus);
125948 + }
125949 + }
125950 + /* Step 3. */
125951 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
125952 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
125953 + if (cpumask_empty(&slave_cpus)) {
125954 + /* No sharing required */
125955 + if (!list_empty(&shared_pcfgs)) {
125956 + /* Migrate "shared" to "unshared" */
125957 + cpumask_or(&unshared_cpus, &unshared_cpus,
125958 + &shared_cpus);
125959 + cpumask_clear(&shared_cpus);
125960 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
125961 + INIT_LIST_HEAD(&shared_pcfgs);
125962 + }
125963 + } else {
125964 + /* Sharing required */
125965 + if (list_empty(&shared_pcfgs)) {
125966 + /* Migrate one "unshared" to "shared" */
125967 + pcfg = get_pcfg(&unshared_pcfgs);
125968 + if (!pcfg) {
125969 + pr_crit("No BMan portals available!\n");
125970 + return 0;
125971 + }
125972 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
125973 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
125974 + list_add_tail(&pcfg->list, &shared_pcfgs);
125975 + }
125976 + }
125977 + /* Step 4. */
125978 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
125979 + pcfg->public_cfg.is_shared = 0;
125980 + p = init_pcfg(pcfg);
125981 + if (!p) {
125982 + pr_crit("Unable to initialize bman portal\n");
125983 + return 0;
125984 + }
125985 + }
125986 + /* Step 5. */
125987 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
125988 + pcfg->public_cfg.is_shared = 1;
125989 + p = init_pcfg(pcfg);
125990 + if (p)
125991 + shared_portals[num_shared_portals++] = p;
125992 + }
125993 + /* Step 6. */
125994 + if (!cpumask_empty(&slave_cpus))
125995 + for_each_cpu(cpu, &slave_cpus)
125996 + init_slave(cpu);
125997 + pr_info("Bman portals initialised\n");
125998 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
125999 + for_each_cpu(cpu, &offline_cpus)
126000 + bman_offline_cpu(cpu);
126001 +#ifdef CONFIG_HOTPLUG_CPU
126002 + register_hotcpu_notifier(&bman_hotplug_cpu_notifier);
126003 +#endif
126004 + return 0;
126005 +}
126006 +
126007 +__init int bman_resource_init(void)
126008 +{
126009 + struct device_node *dn;
126010 + int ret;
126011 +
126012 + /* Initialise BPID allocation ranges */
126013 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
126014 + ret = fsl_bpid_range_init(dn);
126015 + if (ret)
126016 + return ret;
126017 + }
126018 + return 0;
126019 +}
126020 +
126021 +#ifdef CONFIG_SUSPEND
126022 +void suspend_unused_bportal(void)
126023 +{
126024 + struct bm_portal_config *pcfg;
126025 +
126026 + if (list_empty(&unused_pcfgs))
126027 + return;
126028 +
126029 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126030 +#ifdef CONFIG_PM_DEBUG
126031 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
126032 +#endif
126033 + /* save isdr, disable all via isdr, clear isr */
126034 + pcfg->saved_isdr =
126035 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126036 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126037 + 0xe08);
126038 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
126039 + 0xe00);
126040 + }
126041 + return;
126042 +}
126043 +
126044 +void resume_unused_bportal(void)
126045 +{
126046 + struct bm_portal_config *pcfg;
126047 +
126048 + if (list_empty(&unused_pcfgs))
126049 + return;
126050 +
126051 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
126052 +#ifdef CONFIG_PM_DEBUG
126053 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
126054 +#endif
126055 + /* restore isdr */
126056 + __raw_writel(pcfg->saved_isdr,
126057 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
126058 + }
126059 + return;
126060 +}
126061 +#endif
126062 --- /dev/null
126063 +++ b/drivers/staging/fsl_qbman/bman_high.c
126064 @@ -0,0 +1,1145 @@
126065 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
126066 + *
126067 + * Redistribution and use in source and binary forms, with or without
126068 + * modification, are permitted provided that the following conditions are met:
126069 + * * Redistributions of source code must retain the above copyright
126070 + * notice, this list of conditions and the following disclaimer.
126071 + * * Redistributions in binary form must reproduce the above copyright
126072 + * notice, this list of conditions and the following disclaimer in the
126073 + * documentation and/or other materials provided with the distribution.
126074 + * * Neither the name of Freescale Semiconductor nor the
126075 + * names of its contributors may be used to endorse or promote products
126076 + * derived from this software without specific prior written permission.
126077 + *
126078 + *
126079 + * ALTERNATIVELY, this software may be distributed under the terms of the
126080 + * GNU General Public License ("GPL") as published by the Free Software
126081 + * Foundation, either version 2 of that License or (at your option) any
126082 + * later version.
126083 + *
126084 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126085 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126086 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126087 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126088 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126089 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126090 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126091 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126092 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126093 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126094 + */
126095 +
126096 +#include "bman_low.h"
126097 +
126098 +/* Compilation constants */
126099 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
126100 +#define IRQNAME "BMan portal %d"
126101 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
126102 +
126103 +struct bman_portal {
126104 + struct bm_portal p;
126105 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
126106 + struct bman_depletion *pools;
126107 + int thresh_set;
126108 + unsigned long irq_sources;
126109 + u32 slowpoll; /* only used when interrupts are off */
126110 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126111 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
126112 +#endif
126113 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126114 + raw_spinlock_t sharing_lock; /* only used if is_shared */
126115 + int is_shared;
126116 + struct bman_portal *sharing_redirect;
126117 +#endif
126118 + /* When the cpu-affine portal is activated, this is non-NULL */
126119 + const struct bm_portal_config *config;
126120 + /* This is needed for power management */
126121 + struct platform_device *pdev;
126122 + /* 64-entry hash-table of pool objects that are tracking depletion
126123 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
126124 + * we're not fussy about cache-misses and so forth - whereas the above
126125 + * members should all fit in one cacheline.
126126 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
126127 + * you'll never guess the hash-function ... */
126128 + struct bman_pool *cb[64];
126129 + char irqname[MAX_IRQNAME];
126130 + /* Track if the portal was alloced by the driver */
126131 + u8 alloced;
126132 + /* power management data */
126133 + u32 save_isdr;
126134 +};
126135 +
126136 +/* For an explanation of the locking, redirection, or affine-portal logic,
126137 + * please consult the Qman driver for details. This is the same, only simpler
126138 + * (no fiddly Qman-specific bits.) */
126139 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126140 +#define PORTAL_IRQ_LOCK(p, irqflags) \
126141 + do { \
126142 + if ((p)->is_shared) \
126143 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
126144 + else \
126145 + local_irq_save(irqflags); \
126146 + } while (0)
126147 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
126148 + do { \
126149 + if ((p)->is_shared) \
126150 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
126151 + irqflags); \
126152 + else \
126153 + local_irq_restore(irqflags); \
126154 + } while (0)
126155 +#else
126156 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
126157 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
126158 +#endif
126159 +
126160 +static cpumask_t affine_mask;
126161 +static DEFINE_SPINLOCK(affine_mask_lock);
126162 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
126163 +static inline struct bman_portal *get_raw_affine_portal(void)
126164 +{
126165 + return &get_cpu_var(bman_affine_portal);
126166 +}
126167 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126168 +static inline struct bman_portal *get_affine_portal(void)
126169 +{
126170 + struct bman_portal *p = get_raw_affine_portal();
126171 + if (p->sharing_redirect)
126172 + return p->sharing_redirect;
126173 + return p;
126174 +}
126175 +#else
126176 +#define get_affine_portal() get_raw_affine_portal()
126177 +#endif
126178 +static inline void put_affine_portal(void)
126179 +{
126180 + put_cpu_var(bman_affine_portal);
126181 +}
126182 +static inline struct bman_portal *get_poll_portal(void)
126183 +{
126184 + return &get_cpu_var(bman_affine_portal);
126185 +}
126186 +#define put_poll_portal()
126187 +
126188 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
126189 + * more than one such object per Bman buffer pool, eg. if different users of the
126190 + * pool are operating via different portals. */
126191 +struct bman_pool {
126192 + struct bman_pool_params params;
126193 + /* Used for hash-table admin when using depletion notifications. */
126194 + struct bman_portal *portal;
126195 + struct bman_pool *next;
126196 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
126197 + struct bm_buffer *sp;
126198 + unsigned int sp_fill;
126199 +#ifdef CONFIG_FSL_DPA_CHECKING
126200 + atomic_t in_use;
126201 +#endif
126202 +};
126203 +
126204 +/* (De)Registration of depletion notification callbacks */
126205 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
126206 +{
126207 + __maybe_unused unsigned long irqflags;
126208 + pool->portal = portal;
126209 + PORTAL_IRQ_LOCK(portal, irqflags);
126210 + pool->next = portal->cb[pool->params.bpid];
126211 + portal->cb[pool->params.bpid] = pool;
126212 + if (!pool->next)
126213 + /* First object for that bpid on this portal, enable the BSCN
126214 + * mask bit. */
126215 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
126216 + PORTAL_IRQ_UNLOCK(portal, irqflags);
126217 +}
126218 +static void depletion_unlink(struct bman_pool *pool)
126219 +{
126220 + struct bman_pool *it, *last = NULL;
126221 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
126222 + __maybe_unused unsigned long irqflags;
126223 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
126224 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
126225 + while (it != pool) {
126226 + last = it;
126227 + it = it->next;
126228 + }
126229 + if (!last)
126230 + *base = pool->next;
126231 + else
126232 + last->next = pool->next;
126233 + if (!last && !pool->next) {
126234 + /* Last object for that bpid on this portal, disable the BSCN
126235 + * mask bit. */
126236 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
126237 + /* And "forget" that we last saw this pool as depleted */
126238 + bman_depletion_unset(&pool->portal->pools[1],
126239 + pool->params.bpid);
126240 + }
126241 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
126242 +}
126243 +
126244 +/* In the case that the application's core loop calls qman_poll() and
126245 + * bman_poll(), we ought to balance how often we incur the overheads of the
126246 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
126247 + * constant is used when the last slow-poll detected no work to do, and the busy
126248 + * decrementer constant when the last slow-poll had work to do. */
126249 +#define SLOW_POLL_IDLE 1000
126250 +#define SLOW_POLL_BUSY 10
126251 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
126252 +
126253 +/* Portal interrupt handler */
126254 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
126255 +{
126256 + struct bman_portal *p = ptr;
126257 + u32 clear = p->irq_sources;
126258 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
126259 + clear |= __poll_portal_slow(p, is);
126260 + bm_isr_status_clear(&p->p, clear);
126261 + return IRQ_HANDLED;
126262 +}
126263 +
126264 +#ifdef CONFIG_SUSPEND
126265 +static int _bman_portal_suspend_noirq(struct device *dev)
126266 +{
126267 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126268 +#ifdef CONFIG_PM_DEBUG
126269 + struct platform_device *pdev = to_platform_device(dev);
126270 +#endif
126271 + p->save_isdr = bm_isr_disable_read(&p->p);
126272 + bm_isr_disable_write(&p->p, 0xffffffff);
126273 + bm_isr_status_clear(&p->p, 0xffffffff);
126274 +#ifdef CONFIG_PM_DEBUG
126275 + pr_info("Suspend for %s\n", pdev->name);
126276 +#endif
126277 + return 0;
126278 +}
126279 +
126280 +static int _bman_portal_resume_noirq(struct device *dev)
126281 +{
126282 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
126283 +
126284 + /* restore isdr */
126285 + bm_isr_disable_write(&p->p, p->save_isdr);
126286 + return 0;
126287 +}
126288 +#else
126289 +#define _bman_portal_suspend_noirq NULL
126290 +#define _bman_portal_resume_noirq NULL
126291 +#endif
126292 +
126293 +struct dev_pm_domain bman_portal_device_pm_domain = {
126294 + .ops = {
126295 + USE_PLATFORM_PM_SLEEP_OPS
126296 + .suspend_noirq = _bman_portal_suspend_noirq,
126297 + .resume_noirq = _bman_portal_resume_noirq,
126298 + }
126299 +};
126300 +
126301 +struct bman_portal *bman_create_portal(
126302 + struct bman_portal *portal,
126303 + const struct bm_portal_config *config)
126304 +{
126305 + struct bm_portal *__p;
126306 + const struct bman_depletion *pools = &config->public_cfg.mask;
126307 + int ret;
126308 + u8 bpid = 0;
126309 + char buf[16];
126310 +
126311 + if (!portal) {
126312 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
126313 + if (!portal)
126314 + return portal;
126315 + portal->alloced = 1;
126316 + } else
126317 + portal->alloced = 0;
126318 +
126319 + __p = &portal->p;
126320 +
126321 + /* prep the low-level portal struct with the mapped addresses from the
126322 + * config, everything that follows depends on it and "config" is more
126323 + * for (de)reference... */
126324 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
126325 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
126326 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
126327 + pr_err("Bman RCR initialisation failed\n");
126328 + goto fail_rcr;
126329 + }
126330 + if (bm_mc_init(__p)) {
126331 + pr_err("Bman MC initialisation failed\n");
126332 + goto fail_mc;
126333 + }
126334 + if (bm_isr_init(__p)) {
126335 + pr_err("Bman ISR initialisation failed\n");
126336 + goto fail_isr;
126337 + }
126338 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
126339 + if (!portal->pools)
126340 + goto fail_pools;
126341 + portal->pools[0] = *pools;
126342 + bman_depletion_init(portal->pools + 1);
126343 + while (bpid < bman_pool_max) {
126344 + /* Default to all BPIDs disabled, we enable as required at
126345 + * run-time. */
126346 + bm_isr_bscn_mask(__p, bpid, 0);
126347 + bpid++;
126348 + }
126349 + portal->slowpoll = 0;
126350 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126351 + portal->rcri_owned = NULL;
126352 +#endif
126353 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126354 + raw_spin_lock_init(&portal->sharing_lock);
126355 + portal->is_shared = config->public_cfg.is_shared;
126356 + portal->sharing_redirect = NULL;
126357 +#endif
126358 + sprintf(buf, "bportal-%u", config->public_cfg.index);
126359 + portal->pdev = platform_device_alloc(buf, -1);
126360 + if (!portal->pdev)
126361 + goto fail_devalloc;
126362 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
126363 + portal->pdev->dev.platform_data = portal;
126364 + ret = platform_device_add(portal->pdev);
126365 + if (ret)
126366 + goto fail_devadd;
126367 + memset(&portal->cb, 0, sizeof(portal->cb));
126368 + /* Write-to-clear any stale interrupt status bits */
126369 + bm_isr_disable_write(__p, 0xffffffff);
126370 + portal->irq_sources = 0;
126371 + bm_isr_enable_write(__p, portal->irq_sources);
126372 + bm_isr_status_clear(__p, 0xffffffff);
126373 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
126374 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
126375 + portal)) {
126376 + pr_err("request_irq() failed\n");
126377 + goto fail_irq;
126378 + }
126379 + if ((config->public_cfg.cpu != -1) &&
126380 + irq_can_set_affinity(config->public_cfg.irq) &&
126381 + irq_set_affinity(config->public_cfg.irq,
126382 + cpumask_of(config->public_cfg.cpu))) {
126383 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
126384 + goto fail_affinity;
126385 + }
126386 +
126387 + /* Need RCR to be empty before continuing */
126388 + ret = bm_rcr_get_fill(__p);
126389 + if (ret) {
126390 + pr_err("Bman RCR unclean\n");
126391 + goto fail_rcr_empty;
126392 + }
126393 + /* Success */
126394 + portal->config = config;
126395 +
126396 + bm_isr_disable_write(__p, 0);
126397 + bm_isr_uninhibit(__p);
126398 + return portal;
126399 +fail_rcr_empty:
126400 +fail_affinity:
126401 + free_irq(config->public_cfg.irq, portal);
126402 +fail_irq:
126403 + platform_device_del(portal->pdev);
126404 +fail_devadd:
126405 + platform_device_put(portal->pdev);
126406 +fail_devalloc:
126407 + kfree(portal->pools);
126408 +fail_pools:
126409 + bm_isr_finish(__p);
126410 +fail_isr:
126411 + bm_mc_finish(__p);
126412 +fail_mc:
126413 + bm_rcr_finish(__p);
126414 +fail_rcr:
126415 + if (portal->alloced)
126416 + kfree(portal);
126417 + return NULL;
126418 +}
126419 +
126420 +struct bman_portal *bman_create_affine_portal(
126421 + const struct bm_portal_config *config)
126422 +{
126423 + struct bman_portal *portal;
126424 +
126425 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
126426 + portal = bman_create_portal(portal, config);
126427 + if (portal) {
126428 + spin_lock(&affine_mask_lock);
126429 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
126430 + spin_unlock(&affine_mask_lock);
126431 + }
126432 + return portal;
126433 +}
126434 +
126435 +
126436 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
126437 + int cpu)
126438 +{
126439 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126440 + struct bman_portal *p;
126441 + p = &per_cpu(bman_affine_portal, cpu);
126442 + BUG_ON(p->config);
126443 + BUG_ON(p->is_shared);
126444 + BUG_ON(!redirect->config->public_cfg.is_shared);
126445 + p->irq_sources = 0;
126446 + p->sharing_redirect = redirect;
126447 + return p;
126448 +#else
126449 + BUG();
126450 + return NULL;
126451 +#endif
126452 +}
126453 +
126454 +void bman_destroy_portal(struct bman_portal *bm)
126455 +{
126456 + const struct bm_portal_config *pcfg;
126457 + pcfg = bm->config;
126458 + bm_rcr_cce_update(&bm->p);
126459 + bm_rcr_cce_update(&bm->p);
126460 +
126461 + free_irq(pcfg->public_cfg.irq, bm);
126462 +
126463 + kfree(bm->pools);
126464 + bm_isr_finish(&bm->p);
126465 + bm_mc_finish(&bm->p);
126466 + bm_rcr_finish(&bm->p);
126467 + bm->config = NULL;
126468 + if (bm->alloced)
126469 + kfree(bm);
126470 +}
126471 +
126472 +const struct bm_portal_config *bman_destroy_affine_portal(void)
126473 +{
126474 + struct bman_portal *bm = get_raw_affine_portal();
126475 + const struct bm_portal_config *pcfg;
126476 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126477 + if (bm->sharing_redirect) {
126478 + bm->sharing_redirect = NULL;
126479 + put_affine_portal();
126480 + return NULL;
126481 + }
126482 + bm->is_shared = 0;
126483 +#endif
126484 + pcfg = bm->config;
126485 + bman_destroy_portal(bm);
126486 + spin_lock(&affine_mask_lock);
126487 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
126488 + spin_unlock(&affine_mask_lock);
126489 + put_affine_portal();
126490 + return pcfg;
126491 +}
126492 +
126493 +/* When release logic waits on available RCR space, we need a global waitqueue
126494 + * in the case of "affine" use (as the waits wake on different cpus which means
126495 + * different portals - so we can't wait on any per-portal waitqueue). */
126496 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
126497 +
126498 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
126499 +{
126500 + struct bman_depletion tmp;
126501 + u32 ret = is;
126502 +
126503 + /* There is a gotcha to be aware of. If we do the query before clearing
126504 + * the status register, we may miss state changes that occur between the
126505 + * two. If we write to clear the status register before the query, the
126506 + * cache-enabled query command may overtake the status register write
126507 + * unless we use a heavyweight sync (which we don't want). Instead, we
126508 + * write-to-clear the status register then *read it back* before doing
126509 + * the query, hence the odd while loop with the 'is' accumulation. */
126510 + if (is & BM_PIRQ_BSCN) {
126511 + struct bm_mc_result *mcr;
126512 + __maybe_unused unsigned long irqflags;
126513 + unsigned int i, j;
126514 + u32 __is;
126515 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126516 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
126517 + is |= __is;
126518 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
126519 + }
126520 + is &= ~BM_PIRQ_BSCN;
126521 + PORTAL_IRQ_LOCK(p, irqflags);
126522 + bm_mc_start(&p->p);
126523 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
126524 + while (!(mcr = bm_mc_result(&p->p)))
126525 + cpu_relax();
126526 + tmp = mcr->query.ds.state;
126527 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
126528 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
126529 + PORTAL_IRQ_UNLOCK(p, irqflags);
126530 + for (i = 0; i < 2; i++) {
126531 + int idx = i * 32;
126532 + /* tmp is a mask of currently-depleted pools.
126533 + * pools[0] is mask of those we care about.
126534 + * pools[1] is our previous view (we only want to
126535 + * be told about changes). */
126536 + tmp.__state[i] &= p->pools[0].__state[i];
126537 + if (tmp.__state[i] == p->pools[1].__state[i])
126538 + /* fast-path, nothing to see, move along */
126539 + continue;
126540 + for (j = 0; j <= 31; j++, idx++) {
126541 + struct bman_pool *pool = p->cb[idx];
126542 + int b4 = bman_depletion_get(&p->pools[1], idx);
126543 + int af = bman_depletion_get(&tmp, idx);
126544 + if (b4 == af)
126545 + continue;
126546 + while (pool) {
126547 + pool->params.cb(p, pool,
126548 + pool->params.cb_ctx, af);
126549 + pool = pool->next;
126550 + }
126551 + }
126552 + }
126553 + p->pools[1] = tmp;
126554 + }
126555 +
126556 + if (is & BM_PIRQ_RCRI) {
126557 + __maybe_unused unsigned long irqflags;
126558 + PORTAL_IRQ_LOCK(p, irqflags);
126559 + bm_rcr_cce_update(&p->p);
126560 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126561 + /* If waiting for sync, we only cancel the interrupt threshold
126562 + * when the ring utilisation hits zero. */
126563 + if (p->rcri_owned) {
126564 + if (!bm_rcr_get_fill(&p->p)) {
126565 + p->rcri_owned = NULL;
126566 + bm_rcr_set_ithresh(&p->p, 0);
126567 + }
126568 + } else
126569 +#endif
126570 + bm_rcr_set_ithresh(&p->p, 0);
126571 + PORTAL_IRQ_UNLOCK(p, irqflags);
126572 + wake_up(&affine_queue);
126573 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
126574 + is &= ~BM_PIRQ_RCRI;
126575 + }
126576 +
126577 + /* There should be no status register bits left undefined */
126578 + DPA_ASSERT(!is);
126579 + return ret;
126580 +}
126581 +
126582 +const struct bman_portal_config *bman_get_portal_config(void)
126583 +{
126584 + struct bman_portal *p = get_affine_portal();
126585 + const struct bman_portal_config *ret = &p->config->public_cfg;
126586 + put_affine_portal();
126587 + return ret;
126588 +}
126589 +EXPORT_SYMBOL(bman_get_portal_config);
126590 +
126591 +u32 bman_irqsource_get(void)
126592 +{
126593 + struct bman_portal *p = get_raw_affine_portal();
126594 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
126595 + put_affine_portal();
126596 + return ret;
126597 +}
126598 +EXPORT_SYMBOL(bman_irqsource_get);
126599 +
126600 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
126601 +{
126602 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126603 + if (p->sharing_redirect)
126604 + return -EINVAL;
126605 + else
126606 +#endif
126607 + {
126608 + __maybe_unused unsigned long irqflags;
126609 + PORTAL_IRQ_LOCK(p, irqflags);
126610 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
126611 + bm_isr_enable_write(&p->p, p->irq_sources);
126612 + PORTAL_IRQ_UNLOCK(p, irqflags);
126613 + }
126614 + return 0;
126615 +}
126616 +EXPORT_SYMBOL(bman_p_irqsource_add);
126617 +
126618 +int bman_irqsource_add(__maybe_unused u32 bits)
126619 +{
126620 + struct bman_portal *p = get_raw_affine_portal();
126621 + int ret = 0;
126622 + ret = bman_p_irqsource_add(p, bits);
126623 + put_affine_portal();
126624 + return ret;
126625 +}
126626 +EXPORT_SYMBOL(bman_irqsource_add);
126627 +
126628 +int bman_irqsource_remove(u32 bits)
126629 +{
126630 + struct bman_portal *p = get_raw_affine_portal();
126631 + __maybe_unused unsigned long irqflags;
126632 + u32 ier;
126633 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126634 + if (p->sharing_redirect) {
126635 + put_affine_portal();
126636 + return -EINVAL;
126637 + }
126638 +#endif
126639 + /* Our interrupt handler only processes+clears status register bits that
126640 + * are in p->irq_sources. As we're trimming that mask, if one of them
126641 + * were to assert in the status register just before we remove it from
126642 + * the enable register, there would be an interrupt-storm when we
126643 + * release the IRQ lock. So we wait for the enable register update to
126644 + * take effect in h/w (by reading it back) and then clear all other bits
126645 + * in the status register. Ie. we clear them from ISR once it's certain
126646 + * IER won't allow them to reassert. */
126647 + PORTAL_IRQ_LOCK(p, irqflags);
126648 + bits &= BM_PIRQ_VISIBLE;
126649 + clear_bits(bits, &p->irq_sources);
126650 + bm_isr_enable_write(&p->p, p->irq_sources);
126651 + ier = bm_isr_enable_read(&p->p);
126652 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
126653 + * data-dependency, ie. to protect against re-ordering. */
126654 + bm_isr_status_clear(&p->p, ~ier);
126655 + PORTAL_IRQ_UNLOCK(p, irqflags);
126656 + put_affine_portal();
126657 + return 0;
126658 +}
126659 +EXPORT_SYMBOL(bman_irqsource_remove);
126660 +
126661 +const cpumask_t *bman_affine_cpus(void)
126662 +{
126663 + return &affine_mask;
126664 +}
126665 +EXPORT_SYMBOL(bman_affine_cpus);
126666 +
126667 +u32 bman_poll_slow(void)
126668 +{
126669 + struct bman_portal *p = get_poll_portal();
126670 + u32 ret;
126671 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126672 + if (unlikely(p->sharing_redirect))
126673 + ret = (u32)-1;
126674 + else
126675 +#endif
126676 + {
126677 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126678 + ret = __poll_portal_slow(p, is);
126679 + bm_isr_status_clear(&p->p, ret);
126680 + }
126681 + put_poll_portal();
126682 + return ret;
126683 +}
126684 +EXPORT_SYMBOL(bman_poll_slow);
126685 +
126686 +/* Legacy wrapper */
126687 +void bman_poll(void)
126688 +{
126689 + struct bman_portal *p = get_poll_portal();
126690 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126691 + if (unlikely(p->sharing_redirect))
126692 + goto done;
126693 +#endif
126694 + if (!(p->slowpoll--)) {
126695 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
126696 + u32 active = __poll_portal_slow(p, is);
126697 + if (active)
126698 + p->slowpoll = SLOW_POLL_BUSY;
126699 + else
126700 + p->slowpoll = SLOW_POLL_IDLE;
126701 + }
126702 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
126703 +done:
126704 +#endif
126705 + put_poll_portal();
126706 +}
126707 +EXPORT_SYMBOL(bman_poll);
126708 +
126709 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
126710 +
126711 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
126712 +{
126713 + struct bman_pool *pool = NULL;
126714 + u32 bpid;
126715 +
126716 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
126717 + int ret = bman_alloc_bpid(&bpid);
126718 + if (ret)
126719 + return NULL;
126720 + } else {
126721 + if (params->bpid >= bman_pool_max)
126722 + return NULL;
126723 + bpid = params->bpid;
126724 + }
126725 +#ifdef CONFIG_FSL_BMAN_CONFIG
126726 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
126727 + int ret = bm_pool_set(bpid, params->thresholds);
126728 + if (ret)
126729 + goto err;
126730 + }
126731 +#else
126732 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126733 + goto err;
126734 +#endif
126735 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
126736 + if (!pool)
126737 + goto err;
126738 + pool->sp = NULL;
126739 + pool->sp_fill = 0;
126740 + pool->params = *params;
126741 +#ifdef CONFIG_FSL_DPA_CHECKING
126742 + atomic_set(&pool->in_use, 1);
126743 +#endif
126744 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126745 + pool->params.bpid = bpid;
126746 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
126747 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
126748 + GFP_KERNEL);
126749 + if (!pool->sp)
126750 + goto err;
126751 + }
126752 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
126753 + struct bman_portal *p = get_affine_portal();
126754 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
126755 + pr_err("Depletion events disabled for bpid %d\n", bpid);
126756 + goto err;
126757 + }
126758 + depletion_link(p, pool);
126759 + put_affine_portal();
126760 + }
126761 + return pool;
126762 +err:
126763 +#ifdef CONFIG_FSL_BMAN_CONFIG
126764 + if (params->flags & BMAN_POOL_FLAG_THRESH)
126765 + bm_pool_set(bpid, zero_thresholds);
126766 +#endif
126767 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126768 + bman_release_bpid(bpid);
126769 + if (pool) {
126770 + kfree(pool->sp);
126771 + kfree(pool);
126772 + }
126773 + return NULL;
126774 +}
126775 +EXPORT_SYMBOL(bman_new_pool);
126776 +
126777 +void bman_free_pool(struct bman_pool *pool)
126778 +{
126779 +#ifdef CONFIG_FSL_BMAN_CONFIG
126780 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
126781 + bm_pool_set(pool->params.bpid, zero_thresholds);
126782 +#endif
126783 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
126784 + depletion_unlink(pool);
126785 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
126786 + if (pool->sp_fill)
126787 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
126788 + pool->sp_fill, pool->params.bpid);
126789 + kfree(pool->sp);
126790 + pool->sp = NULL;
126791 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
126792 + }
126793 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
126794 + bman_release_bpid(pool->params.bpid);
126795 + kfree(pool);
126796 +}
126797 +EXPORT_SYMBOL(bman_free_pool);
126798 +
126799 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
126800 +{
126801 + return &pool->params;
126802 +}
126803 +EXPORT_SYMBOL(bman_get_params);
126804 +
126805 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
126806 +{
126807 + if (avail)
126808 + bm_rcr_cce_prefetch(&p->p);
126809 + else
126810 + bm_rcr_cce_update(&p->p);
126811 +}
126812 +
126813 +int bman_rcr_is_empty(void)
126814 +{
126815 + __maybe_unused unsigned long irqflags;
126816 + struct bman_portal *p = get_affine_portal();
126817 + u8 avail;
126818 +
126819 + PORTAL_IRQ_LOCK(p, irqflags);
126820 + update_rcr_ci(p, 0);
126821 + avail = bm_rcr_get_fill(&p->p);
126822 + PORTAL_IRQ_UNLOCK(p, irqflags);
126823 + put_affine_portal();
126824 + return avail == 0;
126825 +}
126826 +EXPORT_SYMBOL(bman_rcr_is_empty);
126827 +
126828 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
126829 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126830 + __maybe_unused struct bman_pool *pool,
126831 +#endif
126832 + __maybe_unused unsigned long *irqflags,
126833 + __maybe_unused u32 flags)
126834 +{
126835 + struct bm_rcr_entry *r;
126836 + u8 avail;
126837 +
126838 + *p = get_affine_portal();
126839 + PORTAL_IRQ_LOCK(*p, (*irqflags));
126840 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126841 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126842 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126843 + if ((*p)->rcri_owned) {
126844 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126845 + put_affine_portal();
126846 + return NULL;
126847 + }
126848 + (*p)->rcri_owned = pool;
126849 + }
126850 +#endif
126851 + avail = bm_rcr_get_avail(&(*p)->p);
126852 + if (avail < 2)
126853 + update_rcr_ci(*p, avail);
126854 + r = bm_rcr_start(&(*p)->p);
126855 + if (unlikely(!r)) {
126856 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126857 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126858 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
126859 + (*p)->rcri_owned = NULL;
126860 +#endif
126861 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
126862 + put_affine_portal();
126863 + }
126864 + return r;
126865 +}
126866 +
126867 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126868 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
126869 + struct bman_pool *pool,
126870 + __maybe_unused unsigned long *irqflags,
126871 + u32 flags)
126872 +{
126873 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
126874 + if (!rcr)
126875 + bm_rcr_set_ithresh(&(*p)->p, 1);
126876 + return rcr;
126877 +}
126878 +
126879 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
126880 + struct bman_pool *pool,
126881 + __maybe_unused unsigned long *irqflags,
126882 + u32 flags)
126883 +{
126884 + struct bm_rcr_entry *rcr;
126885 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126886 + pool = NULL;
126887 +#endif
126888 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126889 + /* NB: return NULL if signal occurs before completion. Signal
126890 + * can occur during return. Caller must check for signal */
126891 + wait_event_interruptible(affine_queue,
126892 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126893 + else
126894 + wait_event(affine_queue,
126895 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
126896 + return rcr;
126897 +}
126898 +#endif
126899 +
126900 +static inline int __bman_release(struct bman_pool *pool,
126901 + const struct bm_buffer *bufs, u8 num, u32 flags)
126902 +{
126903 + struct bman_portal *p;
126904 + struct bm_rcr_entry *r;
126905 + __maybe_unused unsigned long irqflags;
126906 + u32 i = num - 1;
126907 +
126908 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
126909 + if (flags & BMAN_RELEASE_FLAG_WAIT)
126910 + r = wait_rel_start(&p, pool, &irqflags, flags);
126911 + else
126912 + r = try_rel_start(&p, pool, &irqflags, flags);
126913 +#else
126914 + r = try_rel_start(&p, &irqflags, flags);
126915 +#endif
126916 + if (!r)
126917 + return -EBUSY;
126918 + /* We can copy all but the first entry, as this can trigger badness
126919 + * with the valid-bit. Use the overlay to mask the verb byte. */
126920 + r->bufs[0].opaque =
126921 + ((cpu_to_be64((bufs[0].opaque |
126922 + ((u64)pool->params.bpid<<48))
126923 + & 0x00ffffffffffffff)));
126924 + if (i) {
126925 + for (i = 1; i < num; i++)
126926 + r->bufs[i].opaque =
126927 + cpu_to_be64(bufs[i].opaque);
126928 + }
126929 +
126930 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
126931 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
126932 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126933 + /* if we wish to sync we need to set the threshold after h/w sees the
126934 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
126935 + * accesses, this requires a heavy-weight sync. */
126936 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126937 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126938 + hwsync();
126939 + bm_rcr_set_ithresh(&p->p, 1);
126940 + }
126941 +#endif
126942 + PORTAL_IRQ_UNLOCK(p, irqflags);
126943 + put_affine_portal();
126944 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
126945 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
126946 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
126947 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
126948 + /* NB: return success even if signal occurs before
126949 + * condition is true. pvb_commit guarantees success */
126950 + wait_event_interruptible(affine_queue,
126951 + (p->rcri_owned != pool));
126952 + else
126953 + wait_event(affine_queue, (p->rcri_owned != pool));
126954 + }
126955 +#endif
126956 + return 0;
126957 +}
126958 +
126959 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
126960 + u32 flags)
126961 +{
126962 + int ret;
126963 +#ifdef CONFIG_FSL_DPA_CHECKING
126964 + if (!num || (num > 8))
126965 + return -EINVAL;
126966 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
126967 + return -EINVAL;
126968 +#endif
126969 + /* Without stockpile, this API is a pass-through to the h/w operation */
126970 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
126971 + return __bman_release(pool, bufs, num, flags);
126972 +#ifdef CONFIG_FSL_DPA_CHECKING
126973 + if (!atomic_dec_and_test(&pool->in_use)) {
126974 + pr_crit("Parallel attempts to enter bman_released() detected.");
126975 + panic("only one instance of bman_released/acquired allowed");
126976 + }
126977 +#endif
126978 + /* Two movements of buffers are possible, and can occur in either order.
126979 + * A: moving buffers from the caller to the stockpile.
126980 + * B: moving buffers from the stockpile to hardware.
126981 + * Order 1: if there is already enough space in the stockpile for A
126982 + * then we want to do A first, and only do B if we trigger the
126983 + * stockpile-high threshold.
126984 + * Order 2: if there is not enough space in the stockpile for A, then
126985 + * we want to do B first, then do A if B had succeeded. However in this
126986 + * case B is dependent on how many buffers the user needs to release,
126987 + * not the stockpile-high threshold.
126988 + * Due to the different handling of B between the two cases, putting A
126989 + * and B in a while() loop would require quite obscure logic, so handle
126990 + * the different sequences explicitly. */
126991 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
126992 + /* Order 1: do A */
126993 + copy_words(pool->sp + pool->sp_fill, bufs,
126994 + sizeof(struct bm_buffer) * num);
126995 + pool->sp_fill += num;
126996 + /* do B relative to STOCKPILE_HIGH */
126997 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
126998 + ret = __bman_release(pool,
126999 + pool->sp + (pool->sp_fill - 8), 8,
127000 + flags);
127001 + if (ret >= 0)
127002 + pool->sp_fill -= 8;
127003 + }
127004 + } else {
127005 + /* Order 2: do B relative to 'num' */
127006 + do {
127007 + ret = __bman_release(pool,
127008 + pool->sp + (pool->sp_fill - 8), 8,
127009 + flags);
127010 + if (ret < 0)
127011 + /* failure */
127012 + goto release_done;
127013 + pool->sp_fill -= 8;
127014 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
127015 + /* do A */
127016 + copy_words(pool->sp + pool->sp_fill, bufs,
127017 + sizeof(struct bm_buffer) * num);
127018 + pool->sp_fill += num;
127019 + }
127020 + /* success */
127021 + ret = 0;
127022 +release_done:
127023 +#ifdef CONFIG_FSL_DPA_CHECKING
127024 + atomic_inc(&pool->in_use);
127025 +#endif
127026 + return ret;
127027 +}
127028 +EXPORT_SYMBOL(bman_release);
127029 +
127030 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
127031 + u8 num)
127032 +{
127033 + struct bman_portal *p = get_affine_portal();
127034 + struct bm_mc_command *mcc;
127035 + struct bm_mc_result *mcr;
127036 + __maybe_unused unsigned long irqflags;
127037 + int ret, i;
127038 +
127039 + PORTAL_IRQ_LOCK(p, irqflags);
127040 + mcc = bm_mc_start(&p->p);
127041 + mcc->acquire.bpid = pool->params.bpid;
127042 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
127043 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
127044 + while (!(mcr = bm_mc_result(&p->p)))
127045 + cpu_relax();
127046 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
127047 + if (bufs) {
127048 + for (i = 0; i < num; i++)
127049 + bufs[i].opaque =
127050 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
127051 + }
127052 + PORTAL_IRQ_UNLOCK(p, irqflags);
127053 + put_affine_portal();
127054 + if (ret != num)
127055 + ret = -ENOMEM;
127056 + return ret;
127057 +}
127058 +
127059 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
127060 + u32 flags)
127061 +{
127062 + int ret;
127063 +#ifdef CONFIG_FSL_DPA_CHECKING
127064 + if (!num || (num > 8))
127065 + return -EINVAL;
127066 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
127067 + return -EINVAL;
127068 +#endif
127069 + /* Without stockpile, this API is a pass-through to the h/w operation */
127070 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
127071 + return __bman_acquire(pool, bufs, num);
127072 +#ifdef CONFIG_FSL_DPA_CHECKING
127073 + if (!atomic_dec_and_test(&pool->in_use)) {
127074 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
127075 + panic("only one instance of bman_released/acquired allowed");
127076 + }
127077 +#endif
127078 + /* Two movements of buffers are possible, and can occur in either order.
127079 + * A: moving buffers from stockpile to the caller.
127080 + * B: moving buffers from hardware to the stockpile.
127081 + * Order 1: if there are already enough buffers in the stockpile for A
127082 + * then we want to do A first, and only do B if we trigger the
127083 + * stockpile-low threshold.
127084 + * Order 2: if there are not enough buffers in the stockpile for A,
127085 + * then we want to do B first, then do A if B had succeeded. However in
127086 + * this case B is dependent on how many buffers the user needs, not the
127087 + * stockpile-low threshold.
127088 + * Due to the different handling of B between the two cases, putting A
127089 + * and B in a while() loop would require quite obscure logic, so handle
127090 + * the different sequences explicitly. */
127091 + if (num <= pool->sp_fill) {
127092 + /* Order 1: do A */
127093 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127094 + sizeof(struct bm_buffer) * num);
127095 + pool->sp_fill -= num;
127096 + /* do B relative to STOCKPILE_LOW */
127097 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
127098 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127099 + if (ret < 0)
127100 + ret = __bman_acquire(pool,
127101 + pool->sp + pool->sp_fill, 1);
127102 + if (ret < 0)
127103 + break;
127104 + pool->sp_fill += ret;
127105 + }
127106 + } else {
127107 + /* Order 2: do B relative to 'num' */
127108 + do {
127109 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
127110 + if (ret < 0)
127111 + ret = __bman_acquire(pool,
127112 + pool->sp + pool->sp_fill, 1);
127113 + if (ret < 0)
127114 + /* failure */
127115 + goto acquire_done;
127116 + pool->sp_fill += ret;
127117 + } while (pool->sp_fill < num);
127118 + /* do A */
127119 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
127120 + sizeof(struct bm_buffer) * num);
127121 + pool->sp_fill -= num;
127122 + }
127123 + /* success */
127124 + ret = num;
127125 +acquire_done:
127126 +#ifdef CONFIG_FSL_DPA_CHECKING
127127 + atomic_inc(&pool->in_use);
127128 +#endif
127129 + return ret;
127130 +}
127131 +EXPORT_SYMBOL(bman_acquire);
127132 +
127133 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
127134 +{
127135 + u8 num;
127136 + int ret;
127137 +
127138 + while (pool->sp_fill) {
127139 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
127140 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
127141 + num, flags);
127142 + if (ret)
127143 + return ret;
127144 + pool->sp_fill -= num;
127145 + }
127146 + return 0;
127147 +}
127148 +EXPORT_SYMBOL(bman_flush_stockpile);
127149 +
127150 +int bman_query_pools(struct bm_pool_state *state)
127151 +{
127152 + struct bman_portal *p = get_affine_portal();
127153 + struct bm_mc_result *mcr;
127154 + __maybe_unused unsigned long irqflags;
127155 +
127156 + PORTAL_IRQ_LOCK(p, irqflags);
127157 + bm_mc_start(&p->p);
127158 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
127159 + while (!(mcr = bm_mc_result(&p->p)))
127160 + cpu_relax();
127161 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
127162 + *state = mcr->query;
127163 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
127164 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
127165 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
127166 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
127167 + PORTAL_IRQ_UNLOCK(p, irqflags);
127168 + put_affine_portal();
127169 + return 0;
127170 +}
127171 +EXPORT_SYMBOL(bman_query_pools);
127172 +
127173 +#ifdef CONFIG_FSL_BMAN_CONFIG
127174 +u32 bman_query_free_buffers(struct bman_pool *pool)
127175 +{
127176 + return bm_pool_free_buffers(pool->params.bpid);
127177 +}
127178 +EXPORT_SYMBOL(bman_query_free_buffers);
127179 +
127180 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
127181 +{
127182 + u32 bpid;
127183 +
127184 + bpid = bman_get_params(pool)->bpid;
127185 +
127186 + return bm_pool_set(bpid, thresholds);
127187 +}
127188 +EXPORT_SYMBOL(bman_update_pool_thresholds);
127189 +#endif
127190 +
127191 +int bman_shutdown_pool(u32 bpid)
127192 +{
127193 + struct bman_portal *p = get_affine_portal();
127194 + __maybe_unused unsigned long irqflags;
127195 + int ret;
127196 +
127197 + PORTAL_IRQ_LOCK(p, irqflags);
127198 + ret = bm_shutdown_pool(&p->p, bpid);
127199 + PORTAL_IRQ_UNLOCK(p, irqflags);
127200 + put_affine_portal();
127201 + return ret;
127202 +}
127203 +EXPORT_SYMBOL(bman_shutdown_pool);
127204 +
127205 +const struct bm_portal_config *bman_get_bm_portal_config(
127206 + struct bman_portal *portal)
127207 +{
127208 + return portal->sharing_redirect ? NULL : portal->config;
127209 +}
127210 --- /dev/null
127211 +++ b/drivers/staging/fsl_qbman/bman_low.h
127212 @@ -0,0 +1,565 @@
127213 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127214 + *
127215 + * Redistribution and use in source and binary forms, with or without
127216 + * modification, are permitted provided that the following conditions are met:
127217 + * * Redistributions of source code must retain the above copyright
127218 + * notice, this list of conditions and the following disclaimer.
127219 + * * Redistributions in binary form must reproduce the above copyright
127220 + * notice, this list of conditions and the following disclaimer in the
127221 + * documentation and/or other materials provided with the distribution.
127222 + * * Neither the name of Freescale Semiconductor nor the
127223 + * names of its contributors may be used to endorse or promote products
127224 + * derived from this software without specific prior written permission.
127225 + *
127226 + *
127227 + * ALTERNATIVELY, this software may be distributed under the terms of the
127228 + * GNU General Public License ("GPL") as published by the Free Software
127229 + * Foundation, either version 2 of that License or (at your option) any
127230 + * later version.
127231 + *
127232 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127233 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127234 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127235 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127236 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127237 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127238 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127239 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127240 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127241 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127242 + */
127243 +
127244 +#include "bman_private.h"
127245 +
127246 +/***************************/
127247 +/* Portal register assists */
127248 +/***************************/
127249 +
127250 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127251 +
127252 +/* Cache-inhibited register offsets */
127253 +#define BM_REG_RCR_PI_CINH 0x0000
127254 +#define BM_REG_RCR_CI_CINH 0x0004
127255 +#define BM_REG_RCR_ITR 0x0008
127256 +#define BM_REG_CFG 0x0100
127257 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
127258 +#define BM_REG_ISR 0x0e00
127259 +#define BM_REG_IIR 0x0e0c
127260 +
127261 +/* Cache-enabled register offsets */
127262 +#define BM_CL_CR 0x0000
127263 +#define BM_CL_RR0 0x0100
127264 +#define BM_CL_RR1 0x0140
127265 +#define BM_CL_RCR 0x1000
127266 +#define BM_CL_RCR_PI_CENA 0x3000
127267 +#define BM_CL_RCR_CI_CENA 0x3100
127268 +
127269 +#endif
127270 +
127271 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127272 +
127273 +/* Cache-inhibited register offsets */
127274 +#define BM_REG_RCR_PI_CINH 0x3000
127275 +#define BM_REG_RCR_CI_CINH 0x3100
127276 +#define BM_REG_RCR_ITR 0x3200
127277 +#define BM_REG_CFG 0x3300
127278 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
127279 +#define BM_REG_ISR 0x3e00
127280 +#define BM_REG_IIR 0x3ec0
127281 +
127282 +/* Cache-enabled register offsets */
127283 +#define BM_CL_CR 0x0000
127284 +#define BM_CL_RR0 0x0100
127285 +#define BM_CL_RR1 0x0140
127286 +#define BM_CL_RCR 0x1000
127287 +#define BM_CL_RCR_PI_CENA 0x3000
127288 +#define BM_CL_RCR_CI_CENA 0x3100
127289 +
127290 +#endif
127291 +
127292 +/* BTW, the drivers (and h/w programming model) already obtain the required
127293 + * synchronisation for portal accesses via lwsync(), hwsync(), and
127294 + * data-dependencies. Use of barrier()s or other order-preserving primitives
127295 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
127296 + * simply ensure that the compiler treats the portal registers as volatile (ie.
127297 + * non-coherent). */
127298 +
127299 +/* Cache-inhibited register access. */
127300 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
127301 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
127302 + (bm)->addr_ci + (o));
127303 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
127304 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
127305 +
127306 +/* Cache-enabled (index) register access */
127307 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
127308 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
127309 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
127310 +#define __bm_cl_out(bm, o, val) \
127311 + do { \
127312 + u32 *__tmpclout = (bm)->addr_ce + (o); \
127313 + __raw_writel(cpu_to_be32(val), __tmpclout); \
127314 + dcbf(__tmpclout); \
127315 + } while (0)
127316 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
127317 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
127318 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
127319 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
127320 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
127321 +#define bm_cl_invalidate(reg)\
127322 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
127323 +
127324 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
127325 + * analysis, look at using the "extra" bit in the ring index registers to avoid
127326 + * cyclic issues. */
127327 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
127328 +{
127329 + /* 'first' is included, 'last' is excluded */
127330 + if (first <= last)
127331 + return last - first;
127332 + return ringsize + last - first;
127333 +}
127334 +
127335 +/* Portal modes.
127336 + * Enum types;
127337 + * pmode == production mode
127338 + * cmode == consumption mode,
127339 + * Enum values use 3 letter codes. First letter matches the portal mode,
127340 + * remaining two letters indicate;
127341 + * ci == cache-inhibited portal register
127342 + * ce == cache-enabled portal register
127343 + * vb == in-band valid-bit (cache-enabled)
127344 + */
127345 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
127346 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
127347 + bm_rcr_pce = 1, /* PI index, cache-enabled */
127348 + bm_rcr_pvb = 2 /* valid-bit */
127349 +};
127350 +enum bm_rcr_cmode { /* s/w-only */
127351 + bm_rcr_cci, /* CI index, cache-inhibited */
127352 + bm_rcr_cce /* CI index, cache-enabled */
127353 +};
127354 +
127355 +
127356 +/* ------------------------- */
127357 +/* --- Portal structures --- */
127358 +
127359 +#define BM_RCR_SIZE 8
127360 +
127361 +struct bm_rcr {
127362 + struct bm_rcr_entry *ring, *cursor;
127363 + u8 ci, available, ithresh, vbit;
127364 +#ifdef CONFIG_FSL_DPA_CHECKING
127365 + u32 busy;
127366 + enum bm_rcr_pmode pmode;
127367 + enum bm_rcr_cmode cmode;
127368 +#endif
127369 +};
127370 +
127371 +struct bm_mc {
127372 + struct bm_mc_command *cr;
127373 + struct bm_mc_result *rr;
127374 + u8 rridx, vbit;
127375 +#ifdef CONFIG_FSL_DPA_CHECKING
127376 + enum {
127377 + /* Can only be _mc_start()ed */
127378 + mc_idle,
127379 + /* Can only be _mc_commit()ed or _mc_abort()ed */
127380 + mc_user,
127381 + /* Can only be _mc_retry()ed */
127382 + mc_hw
127383 + } state;
127384 +#endif
127385 +};
127386 +
127387 +struct bm_addr {
127388 + void __iomem *addr_ce; /* cache-enabled */
127389 + void __iomem *addr_ci; /* cache-inhibited */
127390 +};
127391 +
127392 +struct bm_portal {
127393 + struct bm_addr addr;
127394 + struct bm_rcr rcr;
127395 + struct bm_mc mc;
127396 + struct bm_portal_config config;
127397 +} ____cacheline_aligned;
127398 +
127399 +
127400 +/* --------------- */
127401 +/* --- RCR API --- */
127402 +
127403 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
127404 +#define RCR_CARRYCLEAR(p) \
127405 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
127406 +
127407 +/* Bit-wise logic to convert a ring pointer to a ring index */
127408 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
127409 +{
127410 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
127411 +}
127412 +
127413 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
127414 +static inline void RCR_INC(struct bm_rcr *rcr)
127415 +{
127416 + /* NB: this is odd-looking, but experiments show that it generates
127417 + * fast code with essentially no branching overheads. We increment to
127418 + * the next RCR pointer and handle overflow and 'vbit'. */
127419 + struct bm_rcr_entry *partial = rcr->cursor + 1;
127420 + rcr->cursor = RCR_CARRYCLEAR(partial);
127421 + if (partial != rcr->cursor)
127422 + rcr->vbit ^= BM_RCR_VERB_VBIT;
127423 +}
127424 +
127425 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
127426 + __maybe_unused enum bm_rcr_cmode cmode)
127427 +{
127428 + /* This use of 'register', as well as all other occurrences, is because
127429 + * it has been observed to generate much faster code with gcc than is
127430 + * otherwise the case. */
127431 + register struct bm_rcr *rcr = &portal->rcr;
127432 + u32 cfg;
127433 + u8 pi;
127434 +
127435 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
127436 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127437 +
127438 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127439 + rcr->cursor = rcr->ring + pi;
127440 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
127441 + rcr->available = BM_RCR_SIZE - 1
127442 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
127443 + rcr->ithresh = bm_in(RCR_ITR);
127444 +#ifdef CONFIG_FSL_DPA_CHECKING
127445 + rcr->busy = 0;
127446 + rcr->pmode = pmode;
127447 + rcr->cmode = cmode;
127448 +#endif
127449 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
127450 + bm_out(CFG, cfg);
127451 + return 0;
127452 +}
127453 +
127454 +static inline void bm_rcr_finish(struct bm_portal *portal)
127455 +{
127456 + register struct bm_rcr *rcr = &portal->rcr;
127457 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
127458 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127459 + DPA_ASSERT(!rcr->busy);
127460 + if (pi != RCR_PTR2IDX(rcr->cursor))
127461 + pr_crit("losing uncommited RCR entries\n");
127462 + if (ci != rcr->ci)
127463 + pr_crit("missing existing RCR completions\n");
127464 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
127465 + pr_crit("RCR destroyed unquiesced\n");
127466 +}
127467 +
127468 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
127469 +{
127470 + register struct bm_rcr *rcr = &portal->rcr;
127471 + DPA_ASSERT(!rcr->busy);
127472 + if (!rcr->available)
127473 + return NULL;
127474 +#ifdef CONFIG_FSL_DPA_CHECKING
127475 + rcr->busy = 1;
127476 +#endif
127477 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127478 + dcbz_64(rcr->cursor);
127479 +#endif
127480 + return rcr->cursor;
127481 +}
127482 +
127483 +static inline void bm_rcr_abort(struct bm_portal *portal)
127484 +{
127485 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127486 + DPA_ASSERT(rcr->busy);
127487 +#ifdef CONFIG_FSL_DPA_CHECKING
127488 + rcr->busy = 0;
127489 +#endif
127490 +}
127491 +
127492 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
127493 + struct bm_portal *portal, u8 myverb)
127494 +{
127495 + register struct bm_rcr *rcr = &portal->rcr;
127496 + DPA_ASSERT(rcr->busy);
127497 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
127498 + if (rcr->available == 1)
127499 + return NULL;
127500 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127501 + dcbf_64(rcr->cursor);
127502 + RCR_INC(rcr);
127503 + rcr->available--;
127504 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127505 + dcbz_64(rcr->cursor);
127506 +#endif
127507 + return rcr->cursor;
127508 +}
127509 +
127510 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
127511 +{
127512 + register struct bm_rcr *rcr = &portal->rcr;
127513 + DPA_ASSERT(rcr->busy);
127514 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
127515 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127516 + RCR_INC(rcr);
127517 + rcr->available--;
127518 + hwsync();
127519 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
127520 +#ifdef CONFIG_FSL_DPA_CHECKING
127521 + rcr->busy = 0;
127522 +#endif
127523 +}
127524 +
127525 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
127526 +{
127527 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127528 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127529 + bm_cl_invalidate(RCR_PI);
127530 + bm_cl_touch_rw(RCR_PI);
127531 +}
127532 +
127533 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
127534 +{
127535 + register struct bm_rcr *rcr = &portal->rcr;
127536 + DPA_ASSERT(rcr->busy);
127537 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
127538 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
127539 + RCR_INC(rcr);
127540 + rcr->available--;
127541 + lwsync();
127542 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
127543 +#ifdef CONFIG_FSL_DPA_CHECKING
127544 + rcr->busy = 0;
127545 +#endif
127546 +}
127547 +
127548 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
127549 +{
127550 + register struct bm_rcr *rcr = &portal->rcr;
127551 + struct bm_rcr_entry *rcursor;
127552 + DPA_ASSERT(rcr->busy);
127553 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
127554 + lwsync();
127555 + rcursor = rcr->cursor;
127556 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
127557 + dcbf_64(rcursor);
127558 + RCR_INC(rcr);
127559 + rcr->available--;
127560 +#ifdef CONFIG_FSL_DPA_CHECKING
127561 + rcr->busy = 0;
127562 +#endif
127563 +}
127564 +
127565 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
127566 +{
127567 + register struct bm_rcr *rcr = &portal->rcr;
127568 + u8 diff, old_ci = rcr->ci;
127569 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
127570 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
127571 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127572 + rcr->available += diff;
127573 + return diff;
127574 +}
127575 +
127576 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
127577 +{
127578 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
127579 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127580 + bm_cl_touch_ro(RCR_CI);
127581 +}
127582 +
127583 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
127584 +{
127585 + register struct bm_rcr *rcr = &portal->rcr;
127586 + u8 diff, old_ci = rcr->ci;
127587 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
127588 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
127589 + bm_cl_invalidate(RCR_CI);
127590 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
127591 + rcr->available += diff;
127592 + return diff;
127593 +}
127594 +
127595 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
127596 +{
127597 + register struct bm_rcr *rcr = &portal->rcr;
127598 + return rcr->ithresh;
127599 +}
127600 +
127601 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
127602 +{
127603 + register struct bm_rcr *rcr = &portal->rcr;
127604 + rcr->ithresh = ithresh;
127605 + bm_out(RCR_ITR, ithresh);
127606 +}
127607 +
127608 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
127609 +{
127610 + register struct bm_rcr *rcr = &portal->rcr;
127611 + return rcr->available;
127612 +}
127613 +
127614 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
127615 +{
127616 + register struct bm_rcr *rcr = &portal->rcr;
127617 + return BM_RCR_SIZE - 1 - rcr->available;
127618 +}
127619 +
127620 +
127621 +/* ------------------------------ */
127622 +/* --- Management command API --- */
127623 +
127624 +static inline int bm_mc_init(struct bm_portal *portal)
127625 +{
127626 + register struct bm_mc *mc = &portal->mc;
127627 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
127628 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
127629 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
127630 + BM_MCC_VERB_VBIT) ? 0 : 1;
127631 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
127632 +#ifdef CONFIG_FSL_DPA_CHECKING
127633 + mc->state = mc_idle;
127634 +#endif
127635 + return 0;
127636 +}
127637 +
127638 +static inline void bm_mc_finish(struct bm_portal *portal)
127639 +{
127640 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127641 + DPA_ASSERT(mc->state == mc_idle);
127642 +#ifdef CONFIG_FSL_DPA_CHECKING
127643 + if (mc->state != mc_idle)
127644 + pr_crit("Losing incomplete MC command\n");
127645 +#endif
127646 +}
127647 +
127648 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
127649 +{
127650 + register struct bm_mc *mc = &portal->mc;
127651 + DPA_ASSERT(mc->state == mc_idle);
127652 +#ifdef CONFIG_FSL_DPA_CHECKING
127653 + mc->state = mc_user;
127654 +#endif
127655 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
127656 + dcbz_64(mc->cr);
127657 +#endif
127658 + return mc->cr;
127659 +}
127660 +
127661 +static inline void bm_mc_abort(struct bm_portal *portal)
127662 +{
127663 + __maybe_unused register struct bm_mc *mc = &portal->mc;
127664 + DPA_ASSERT(mc->state == mc_user);
127665 +#ifdef CONFIG_FSL_DPA_CHECKING
127666 + mc->state = mc_idle;
127667 +#endif
127668 +}
127669 +
127670 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
127671 +{
127672 + register struct bm_mc *mc = &portal->mc;
127673 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127674 + DPA_ASSERT(mc->state == mc_user);
127675 + lwsync();
127676 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
127677 + dcbf(mc->cr);
127678 + dcbit_ro(rr);
127679 +#ifdef CONFIG_FSL_DPA_CHECKING
127680 + mc->state = mc_hw;
127681 +#endif
127682 +}
127683 +
127684 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
127685 +{
127686 + register struct bm_mc *mc = &portal->mc;
127687 + struct bm_mc_result *rr = mc->rr + mc->rridx;
127688 + DPA_ASSERT(mc->state == mc_hw);
127689 + /* The inactive response register's verb byte always returns zero until
127690 + * its command is submitted and completed. This includes the valid-bit,
127691 + * in case you were wondering... */
127692 + if (!__raw_readb(&rr->verb)) {
127693 + dcbit_ro(rr);
127694 + return NULL;
127695 + }
127696 + mc->rridx ^= 1;
127697 + mc->vbit ^= BM_MCC_VERB_VBIT;
127698 +#ifdef CONFIG_FSL_DPA_CHECKING
127699 + mc->state = mc_idle;
127700 +#endif
127701 + return rr;
127702 +}
127703 +
127704 +
127705 +/* ------------------------------------- */
127706 +/* --- Portal interrupt register API --- */
127707 +
127708 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
127709 +{
127710 + return 0;
127711 +}
127712 +
127713 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
127714 +{
127715 +}
127716 +
127717 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
127718 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
127719 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
127720 + int enable)
127721 +{
127722 + u32 val;
127723 + DPA_ASSERT(bpid < bman_pool_max);
127724 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
127725 + val = __bm_in(&portal->addr, SCN_REG(bpid));
127726 + if (enable)
127727 + val |= SCN_BIT(bpid);
127728 + else
127729 + val &= ~SCN_BIT(bpid);
127730 + __bm_out(&portal->addr, SCN_REG(bpid), val);
127731 +}
127732 +
127733 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
127734 +{
127735 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127736 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
127737 +#else
127738 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
127739 +#endif
127740 +}
127741 +
127742 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
127743 + u32 val)
127744 +{
127745 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127746 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
127747 +#else
127748 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
127749 +#endif
127750 +}
127751 +
127752 +/* Buffer Pool Cleanup */
127753 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
127754 +{
127755 + struct bm_mc_command *bm_cmd;
127756 + struct bm_mc_result *bm_res;
127757 +
127758 + int aq_count = 0;
127759 + bool stop = false;
127760 + while (!stop) {
127761 + /* Acquire buffers until empty */
127762 + bm_cmd = bm_mc_start(p);
127763 + bm_cmd->acquire.bpid = bpid;
127764 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
127765 + while (!(bm_res = bm_mc_result(p)))
127766 + cpu_relax();
127767 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
127768 + /* Pool is empty */
127769 + /* TBD : Should we do a few extra iterations in
127770 + case some other some blocks keep buffers 'on deck',
127771 + which may also be problematic */
127772 + stop = true;
127773 + } else
127774 + ++aq_count;
127775 + }
127776 + return 0;
127777 +}
127778 --- /dev/null
127779 +++ b/drivers/staging/fsl_qbman/bman_private.h
127780 @@ -0,0 +1,166 @@
127781 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127782 + *
127783 + * Redistribution and use in source and binary forms, with or without
127784 + * modification, are permitted provided that the following conditions are met:
127785 + * * Redistributions of source code must retain the above copyright
127786 + * notice, this list of conditions and the following disclaimer.
127787 + * * Redistributions in binary form must reproduce the above copyright
127788 + * notice, this list of conditions and the following disclaimer in the
127789 + * documentation and/or other materials provided with the distribution.
127790 + * * Neither the name of Freescale Semiconductor nor the
127791 + * names of its contributors may be used to endorse or promote products
127792 + * derived from this software without specific prior written permission.
127793 + *
127794 + *
127795 + * ALTERNATIVELY, this software may be distributed under the terms of the
127796 + * GNU General Public License ("GPL") as published by the Free Software
127797 + * Foundation, either version 2 of that License or (at your option) any
127798 + * later version.
127799 + *
127800 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127801 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127802 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127803 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127804 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127805 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127806 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127807 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127808 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127809 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127810 + */
127811 +
127812 +#include "dpa_sys.h"
127813 +#include <linux/fsl_bman.h>
127814 +
127815 +/* Revision info (for errata and feature handling) */
127816 +#define BMAN_REV10 0x0100
127817 +#define BMAN_REV20 0x0200
127818 +#define BMAN_REV21 0x0201
127819 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
127820 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
127821 +
127822 +/*
127823 + * Global variables of the max portal/pool number this bman version supported
127824 + */
127825 +extern u16 bman_pool_max;
127826 +
127827 +/* used by CCSR and portal interrupt code */
127828 +enum bm_isr_reg {
127829 + bm_isr_status = 0,
127830 + bm_isr_enable = 1,
127831 + bm_isr_disable = 2,
127832 + bm_isr_inhibit = 3
127833 +};
127834 +
127835 +struct bm_portal_config {
127836 + /* Corenet portal addresses;
127837 + * [0]==cache-enabled, [1]==cache-inhibited. */
127838 + __iomem void *addr_virt[2];
127839 + struct resource addr_phys[2];
127840 + /* Allow these to be joined in lists */
127841 + struct list_head list;
127842 + /* User-visible portal configuration settings */
127843 + struct bman_portal_config public_cfg;
127844 + /* power management saved data */
127845 + u32 saved_isdr;
127846 +};
127847 +
127848 +#ifdef CONFIG_FSL_BMAN_CONFIG
127849 +/* Hooks from bman_driver.c to bman_config.c */
127850 +int bman_init_ccsr(struct device_node *node);
127851 +#endif
127852 +
127853 +/* Hooks from bman_driver.c in to bman_high.c */
127854 +struct bman_portal *bman_create_portal(
127855 + struct bman_portal *portal,
127856 + const struct bm_portal_config *config);
127857 +struct bman_portal *bman_create_affine_portal(
127858 + const struct bm_portal_config *config);
127859 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
127860 + int cpu);
127861 +void bman_destroy_portal(struct bman_portal *bm);
127862 +
127863 +const struct bm_portal_config *bman_destroy_affine_portal(void);
127864 +
127865 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
127866 +struct bm_portal_config *bm_get_unused_portal(void);
127867 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
127868 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
127869 +void bm_set_liodns(struct bm_portal_config *pcfg);
127870 +
127871 +/* Pool logic in the portal driver, during initialisation, needs to know if
127872 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
127873 +#ifdef CONFIG_FSL_BMAN_CONFIG
127874 +int bman_have_ccsr(void);
127875 +#else
127876 +#define bman_have_ccsr() 0
127877 +#endif
127878 +
127879 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
127880 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
127881 + * might fail (if the buffer pool is depleted). So this value provides some
127882 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
127883 + * are requested at once or if h/w has been tested a couple of times without
127884 + * luck. The _HIGH value: when bman_release() is called and the stockpile
127885 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
127886 + * the release ring is full). So this value provides some "stagger" so that
127887 + * ring-access is retried a couple of times prior to the API returning a
127888 + * failure. The following *must* be true;
127889 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
127890 + * (to avoid thrashing)
127891 + * BMAN_STOCKPILE_SZ >= 16
127892 + * (as the release logic expects to either send 8 buffers to hw prior to
127893 + * adding the given buffers to the stockpile or add the buffers to the
127894 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
127895 + * success/fail.)
127896 + */
127897 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
127898 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
127899 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
127900 +
127901 +/*************************************************/
127902 +/* BMan s/w corenet portal, low-level i/face */
127903 +/*************************************************/
127904 +
127905 +/* Used by all portal interrupt registers except 'inhibit'
127906 + * This mask contains all the "irqsource" bits visible to API users
127907 + */
127908 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
127909 +
127910 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
127911 + * the disable register" rather than "disable the ability to write". */
127912 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
127913 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
127914 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
127915 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
127916 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
127917 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
127918 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
127919 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
127920 +
127921 +#ifdef CONFIG_FSL_BMAN_CONFIG
127922 +/* Set depletion thresholds associated with a buffer pool. Requires that the
127923 + * operating system have access to Bman CCSR (ie. compiled in support and
127924 + * run-time access courtesy of the device-tree). */
127925 +int bm_pool_set(u32 bpid, const u32 *thresholds);
127926 +#define BM_POOL_THRESH_SW_ENTER 0
127927 +#define BM_POOL_THRESH_SW_EXIT 1
127928 +#define BM_POOL_THRESH_HW_ENTER 2
127929 +#define BM_POOL_THRESH_HW_EXIT 3
127930 +
127931 +/* Read the free buffer count for a given buffer */
127932 +u32 bm_pool_free_buffers(u32 bpid);
127933 +
127934 +__init int bman_init(void);
127935 +__init int bman_resource_init(void);
127936 +
127937 +const struct bm_portal_config *bman_get_bm_portal_config(
127938 + struct bman_portal *portal);
127939 +
127940 +/* power management */
127941 +#ifdef CONFIG_SUSPEND
127942 +void suspend_unused_bportal(void);
127943 +void resume_unused_bportal(void);
127944 +#endif
127945 +
127946 +#endif /* CONFIG_FSL_BMAN_CONFIG */
127947 --- /dev/null
127948 +++ b/drivers/staging/fsl_qbman/bman_test.c
127949 @@ -0,0 +1,56 @@
127950 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
127951 + *
127952 + * Redistribution and use in source and binary forms, with or without
127953 + * modification, are permitted provided that the following conditions are met:
127954 + * * Redistributions of source code must retain the above copyright
127955 + * notice, this list of conditions and the following disclaimer.
127956 + * * Redistributions in binary form must reproduce the above copyright
127957 + * notice, this list of conditions and the following disclaimer in the
127958 + * documentation and/or other materials provided with the distribution.
127959 + * * Neither the name of Freescale Semiconductor nor the
127960 + * names of its contributors may be used to endorse or promote products
127961 + * derived from this software without specific prior written permission.
127962 + *
127963 + *
127964 + * ALTERNATIVELY, this software may be distributed under the terms of the
127965 + * GNU General Public License ("GPL") as published by the Free Software
127966 + * Foundation, either version 2 of that License or (at your option) any
127967 + * later version.
127968 + *
127969 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127970 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127971 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127972 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127973 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127974 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127975 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127976 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127977 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127978 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127979 + */
127980 +
127981 +#include "bman_test.h"
127982 +
127983 +MODULE_AUTHOR("Geoff Thorpe");
127984 +MODULE_LICENSE("Dual BSD/GPL");
127985 +MODULE_DESCRIPTION("Bman testing");
127986 +
127987 +static int test_init(void)
127988 +{
127989 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
127990 + int loop = 1;
127991 + while (loop--)
127992 + bman_test_high();
127993 +#endif
127994 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
127995 + bman_test_thresh();
127996 +#endif
127997 + return 0;
127998 +}
127999 +
128000 +static void test_exit(void)
128001 +{
128002 +}
128003 +
128004 +module_init(test_init);
128005 +module_exit(test_exit);
128006 --- /dev/null
128007 +++ b/drivers/staging/fsl_qbman/bman_test.h
128008 @@ -0,0 +1,44 @@
128009 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128010 + *
128011 + * Redistribution and use in source and binary forms, with or without
128012 + * modification, are permitted provided that the following conditions are met:
128013 + * * Redistributions of source code must retain the above copyright
128014 + * notice, this list of conditions and the following disclaimer.
128015 + * * Redistributions in binary form must reproduce the above copyright
128016 + * notice, this list of conditions and the following disclaimer in the
128017 + * documentation and/or other materials provided with the distribution.
128018 + * * Neither the name of Freescale Semiconductor nor the
128019 + * names of its contributors may be used to endorse or promote products
128020 + * derived from this software without specific prior written permission.
128021 + *
128022 + *
128023 + * ALTERNATIVELY, this software may be distributed under the terms of the
128024 + * GNU General Public License ("GPL") as published by the Free Software
128025 + * Foundation, either version 2 of that License or (at your option) any
128026 + * later version.
128027 + *
128028 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128029 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128030 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128031 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128032 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128033 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128034 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128035 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128036 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128037 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128038 + */
128039 +
128040 +#include <linux/kernel.h>
128041 +#include <linux/errno.h>
128042 +#include <linux/io.h>
128043 +#include <linux/slab.h>
128044 +#include <linux/module.h>
128045 +#include <linux/interrupt.h>
128046 +#include <linux/delay.h>
128047 +#include <linux/kthread.h>
128048 +
128049 +#include <linux/fsl_bman.h>
128050 +
128051 +void bman_test_high(void);
128052 +void bman_test_thresh(void);
128053 --- /dev/null
128054 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
128055 @@ -0,0 +1,183 @@
128056 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128057 + *
128058 + * Redistribution and use in source and binary forms, with or without
128059 + * modification, are permitted provided that the following conditions are met:
128060 + * * Redistributions of source code must retain the above copyright
128061 + * notice, this list of conditions and the following disclaimer.
128062 + * * Redistributions in binary form must reproduce the above copyright
128063 + * notice, this list of conditions and the following disclaimer in the
128064 + * documentation and/or other materials provided with the distribution.
128065 + * * Neither the name of Freescale Semiconductor nor the
128066 + * names of its contributors may be used to endorse or promote products
128067 + * derived from this software without specific prior written permission.
128068 + *
128069 + *
128070 + * ALTERNATIVELY, this software may be distributed under the terms of the
128071 + * GNU General Public License ("GPL") as published by the Free Software
128072 + * Foundation, either version 2 of that License or (at your option) any
128073 + * later version.
128074 + *
128075 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128076 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128077 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128078 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128079 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128080 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128081 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128082 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128083 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128084 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128085 + */
128086 +
128087 +#include "bman_test.h"
128088 +#include "bman_private.h"
128089 +
128090 +/*************/
128091 +/* constants */
128092 +/*************/
128093 +
128094 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
128095 +#define POOL_OPAQUE ((void *)0xdeadabba)
128096 +#define NUM_BUFS 93
128097 +#define LOOPS 3
128098 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
128099 +
128100 +/***************/
128101 +/* global vars */
128102 +/***************/
128103 +
128104 +static struct bman_pool *pool;
128105 +static int depleted;
128106 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
128107 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
128108 +static int bufs_received;
128109 +
128110 +/* Predeclare the callback so we can instantiate pool parameters */
128111 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
128112 +
128113 +/**********************/
128114 +/* internal functions */
128115 +/**********************/
128116 +
128117 +static void bufs_init(void)
128118 +{
128119 + int i;
128120 + for (i = 0; i < NUM_BUFS; i++)
128121 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
128122 + bufs_received = 0;
128123 +}
128124 +
128125 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
128126 +{
128127 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
128128 +
128129 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
128130 + * LS-bits of buffer addresses, masking off the upper 8-bits on
128131 + * release commands. The API provides for 48-bit addresses
128132 + * because some SoCs support all 48-bits. When generating
128133 + * garbage addresses for testing, we either need to zero the
128134 + * upper 8-bits when releasing to Bman (otherwise we'll be
128135 + * disappointed when the buffers we acquire back from Bman
128136 + * don't match), or we need to mask the upper 8-bits off when
128137 + * comparing. We do the latter.
128138 + */
128139 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128140 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128141 + return -1;
128142 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
128143 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
128144 + return 1;
128145 + } else {
128146 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
128147 + return -1;
128148 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
128149 + return 1;
128150 + }
128151 +
128152 + return 0;
128153 +}
128154 +
128155 +static void bufs_confirm(void)
128156 +{
128157 + int i, j;
128158 + for (i = 0; i < NUM_BUFS; i++) {
128159 + int matches = 0;
128160 + for (j = 0; j < NUM_BUFS; j++)
128161 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
128162 + matches++;
128163 + BUG_ON(matches != 1);
128164 + }
128165 +}
128166 +
128167 +/********/
128168 +/* test */
128169 +/********/
128170 +
128171 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
128172 + void *pool_ctx, int __depleted)
128173 +{
128174 + BUG_ON(__pool != pool);
128175 + BUG_ON(pool_ctx != POOL_OPAQUE);
128176 + depleted = __depleted;
128177 +}
128178 +
128179 +void bman_test_high(void)
128180 +{
128181 + struct bman_pool_params pparams = {
128182 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
128183 + .cb = depletion_cb,
128184 + .cb_ctx = POOL_OPAQUE,
128185 + };
128186 + int i, loops = LOOPS;
128187 + struct bm_buffer tmp_buf;
128188 +
128189 + bufs_init();
128190 +
128191 + pr_info("BMAN: --- starting high-level test ---\n");
128192 +
128193 + pool = bman_new_pool(&pparams);
128194 + BUG_ON(!pool);
128195 +
128196 + /*******************/
128197 + /* Release buffers */
128198 + /*******************/
128199 +do_loop:
128200 + i = 0;
128201 + while (i < NUM_BUFS) {
128202 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
128203 + int num = 8;
128204 + if ((i + num) > NUM_BUFS)
128205 + num = NUM_BUFS - i;
128206 + if ((i + num) == NUM_BUFS)
128207 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
128208 + if (bman_release(pool, bufs_in + i, num, flags))
128209 + panic("bman_release() failed\n");
128210 + i += num;
128211 + }
128212 +
128213 + /*******************/
128214 + /* Acquire buffers */
128215 + /*******************/
128216 + while (i > 0) {
128217 + int tmp, num = 8;
128218 + if (num > i)
128219 + num = i;
128220 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
128221 + BUG_ON(tmp != num);
128222 + i -= num;
128223 + }
128224 +
128225 + i = bman_acquire(pool, &tmp_buf, 1, 0);
128226 + BUG_ON(i > 0);
128227 +
128228 + bufs_confirm();
128229 +
128230 + if (--loops)
128231 + goto do_loop;
128232 +
128233 + /************/
128234 + /* Clean up */
128235 + /************/
128236 + bman_free_pool(pool);
128237 + pr_info("BMAN: --- finished high-level test ---\n");
128238 +}
128239 --- /dev/null
128240 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
128241 @@ -0,0 +1,196 @@
128242 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
128243 + *
128244 + * Redistribution and use in source and binary forms, with or without
128245 + * modification, are permitted provided that the following conditions are met:
128246 + * * Redistributions of source code must retain the above copyright
128247 + * notice, this list of conditions and the following disclaimer.
128248 + * * Redistributions in binary form must reproduce the above copyright
128249 + * notice, this list of conditions and the following disclaimer in the
128250 + * documentation and/or other materials provided with the distribution.
128251 + * * Neither the name of Freescale Semiconductor nor the
128252 + * names of its contributors may be used to endorse or promote products
128253 + * derived from this software without specific prior written permission.
128254 + *
128255 + *
128256 + * ALTERNATIVELY, this software may be distributed under the terms of the
128257 + * GNU General Public License ("GPL") as published by the Free Software
128258 + * Foundation, either version 2 of that License or (at your option) any
128259 + * later version.
128260 + *
128261 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128262 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128263 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128264 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128265 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128266 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128267 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128268 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128269 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128270 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128271 + */
128272 +
128273 +#include "bman_test.h"
128274 +
128275 +/* Test constants */
128276 +#define TEST_NUMBUFS 129728
128277 +#define TEST_EXIT 129536
128278 +#define TEST_ENTRY 129024
128279 +
128280 +struct affine_test_data {
128281 + struct task_struct *t;
128282 + int cpu;
128283 + int expect_affinity;
128284 + int drain;
128285 + int num_enter;
128286 + int num_exit;
128287 + struct list_head node;
128288 + struct completion wakethread;
128289 + struct completion wakeparent;
128290 +};
128291 +
128292 +static void cb_depletion(struct bman_portal *portal,
128293 + struct bman_pool *pool,
128294 + void *opaque,
128295 + int depleted)
128296 +{
128297 + struct affine_test_data *data = opaque;
128298 + int c = smp_processor_id();
128299 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
128300 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
128301 + /* We should be executing on the CPU of the thread that owns the pool if
128302 + * and that CPU has an affine portal (ie. it isn't slaved). */
128303 + BUG_ON((c != data->cpu) && data->expect_affinity);
128304 + BUG_ON((c == data->cpu) && !data->expect_affinity);
128305 + if (depleted)
128306 + data->num_enter++;
128307 + else
128308 + data->num_exit++;
128309 +}
128310 +
128311 +/* Params used to set up a pool, this also dynamically allocates a BPID */
128312 +static const struct bman_pool_params params_nocb = {
128313 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
128314 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
128315 +};
128316 +
128317 +/* Params used to set up each cpu's pool with callbacks enabled */
128318 +static struct bman_pool_params params_cb = {
128319 + .bpid = 0, /* will be replaced to match pool_nocb */
128320 + .flags = BMAN_POOL_FLAG_DEPLETION,
128321 + .cb = cb_depletion
128322 +};
128323 +
128324 +static struct bman_pool *pool_nocb;
128325 +static LIST_HEAD(threads);
128326 +
128327 +static int affine_test(void *__data)
128328 +{
128329 + struct bman_pool *pool;
128330 + struct affine_test_data *data = __data;
128331 + struct bman_pool_params my_params = params_cb;
128332 +
128333 + pr_info("thread %d: starting\n", data->cpu);
128334 + /* create the pool */
128335 + my_params.cb_ctx = data;
128336 + pool = bman_new_pool(&my_params);
128337 + BUG_ON(!pool);
128338 + complete(&data->wakeparent);
128339 + wait_for_completion(&data->wakethread);
128340 + init_completion(&data->wakethread);
128341 +
128342 + /* if we're the drainer, we get signalled for that */
128343 + if (data->drain) {
128344 + struct bm_buffer buf;
128345 + int ret;
128346 + pr_info("thread %d: draining...\n", data->cpu);
128347 + do {
128348 + ret = bman_acquire(pool, &buf, 1, 0);
128349 + } while (ret > 0);
128350 + pr_info("thread %d: draining done.\n", data->cpu);
128351 + complete(&data->wakeparent);
128352 + wait_for_completion(&data->wakethread);
128353 + init_completion(&data->wakethread);
128354 + }
128355 +
128356 + /* cleanup */
128357 + bman_free_pool(pool);
128358 + while (!kthread_should_stop())
128359 + cpu_relax();
128360 + pr_info("thread %d: exiting\n", data->cpu);
128361 + return 0;
128362 +}
128363 +
128364 +static struct affine_test_data *start_affine_test(int cpu, int drain)
128365 +{
128366 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
128367 +
128368 + if (!data)
128369 + return NULL;
128370 + data->cpu = cpu;
128371 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
128372 + data->drain = drain;
128373 + data->num_enter = 0;
128374 + data->num_exit = 0;
128375 + init_completion(&data->wakethread);
128376 + init_completion(&data->wakeparent);
128377 + list_add_tail(&data->node, &threads);
128378 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
128379 + BUG_ON(IS_ERR(data->t));
128380 + kthread_bind(data->t, cpu);
128381 + wake_up_process(data->t);
128382 + return data;
128383 +}
128384 +
128385 +void bman_test_thresh(void)
128386 +{
128387 + int loop = TEST_NUMBUFS;
128388 + int ret, num_cpus = 0;
128389 + struct affine_test_data *data, *drainer = NULL;
128390 +
128391 + pr_info("bman_test_thresh: start\n");
128392 +
128393 + /* allocate a BPID and seed it */
128394 + pool_nocb = bman_new_pool(&params_nocb);
128395 + BUG_ON(!pool_nocb);
128396 + while (loop--) {
128397 + struct bm_buffer buf;
128398 + bm_buffer_set64(&buf, 0x0badbeef + loop);
128399 + ret = bman_release(pool_nocb, &buf, 1,
128400 + BMAN_RELEASE_FLAG_WAIT);
128401 + BUG_ON(ret);
128402 + }
128403 + while (!bman_rcr_is_empty())
128404 + cpu_relax();
128405 + pr_info("bman_test_thresh: buffers are in\n");
128406 +
128407 + /* create threads and wait for them to create pools */
128408 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
128409 + for_each_cpu(loop, cpu_online_mask) {
128410 + data = start_affine_test(loop, drainer ? 0 : 1);
128411 + BUG_ON(!data);
128412 + if (!drainer)
128413 + drainer = data;
128414 + num_cpus++;
128415 + wait_for_completion(&data->wakeparent);
128416 + }
128417 +
128418 + /* signal the drainer to start draining */
128419 + complete(&drainer->wakethread);
128420 + wait_for_completion(&drainer->wakeparent);
128421 + init_completion(&drainer->wakeparent);
128422 +
128423 + /* tear down */
128424 + list_for_each_entry_safe(data, drainer, &threads, node) {
128425 + complete(&data->wakethread);
128426 + ret = kthread_stop(data->t);
128427 + BUG_ON(ret);
128428 + list_del(&data->node);
128429 + /* check that we get the expected callbacks (and no others) */
128430 + BUG_ON(data->num_enter != 1);
128431 + BUG_ON(data->num_exit != 0);
128432 + kfree(data);
128433 + }
128434 + bman_free_pool(pool_nocb);
128435 +
128436 + pr_info("bman_test_thresh: done\n");
128437 +}
128438 --- /dev/null
128439 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
128440 @@ -0,0 +1,706 @@
128441 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
128442 + *
128443 + * Redistribution and use in source and binary forms, with or without
128444 + * modification, are permitted provided that the following conditions are met:
128445 + * * Redistributions of source code must retain the above copyright
128446 + * notice, this list of conditions and the following disclaimer.
128447 + * * Redistributions in binary form must reproduce the above copyright
128448 + * notice, this list of conditions and the following disclaimer in the
128449 + * documentation and/or other materials provided with the distribution.
128450 + * * Neither the name of Freescale Semiconductor nor the
128451 + * names of its contributors may be used to endorse or promote products
128452 + * derived from this software without specific prior written permission.
128453 + *
128454 + *
128455 + * ALTERNATIVELY, this software may be distributed under the terms of the
128456 + * GNU General Public License ("GPL") as published by the Free Software
128457 + * Foundation, either version 2 of that License or (at your option) any
128458 + * later version.
128459 + *
128460 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128461 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128462 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128463 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128464 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128465 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128466 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128467 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128468 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128469 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128470 + */
128471 +
128472 +#include "dpa_sys.h"
128473 +#include <linux/fsl_qman.h>
128474 +#include <linux/fsl_bman.h>
128475 +
128476 +/* Qman and Bman APIs are front-ends to the common code; */
128477 +
128478 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
128479 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
128480 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
128481 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
128482 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
128483 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
128484 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
128485 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
128486 +
128487 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
128488 + * FQIDs (probably from user-space), it can filter out those that aren't in the
128489 + * OOS state (better to leak a h/w resource than to crash). This function
128490 + * returns the number of invalid IDs that were not released. */
128491 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
128492 + int (*is_valid)(u32 id))
128493 +{
128494 + int valid_mode = 0;
128495 + u32 loop = id, total_invalid = 0;
128496 + while (loop < (id + count)) {
128497 + int isvalid = is_valid ? is_valid(loop) : 1;
128498 + if (!valid_mode) {
128499 + /* We're looking for a valid ID to terminate an invalid
128500 + * range */
128501 + if (isvalid) {
128502 + /* We finished a range of invalid IDs, a valid
128503 + * range is now underway */
128504 + valid_mode = 1;
128505 + count -= (loop - id);
128506 + id = loop;
128507 + } else
128508 + total_invalid++;
128509 + } else {
128510 + /* We're looking for an invalid ID to terminate a
128511 + * valid range */
128512 + if (!isvalid) {
128513 + /* Release the range of valid IDs, an unvalid
128514 + * range is now underway */
128515 + if (loop > id)
128516 + dpa_alloc_free(alloc, id, loop - id);
128517 + valid_mode = 0;
128518 + }
128519 + }
128520 + loop++;
128521 + }
128522 + /* Release any unterminated range of valid IDs */
128523 + if (valid_mode && count)
128524 + dpa_alloc_free(alloc, id, count);
128525 + return total_invalid;
128526 +}
128527 +
128528 +/* BPID allocator front-end */
128529 +
128530 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
128531 +{
128532 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
128533 +}
128534 +EXPORT_SYMBOL(bman_alloc_bpid_range);
128535 +
128536 +static int bp_cleanup(u32 bpid)
128537 +{
128538 + return bman_shutdown_pool(bpid) == 0;
128539 +}
128540 +void bman_release_bpid_range(u32 bpid, u32 count)
128541 +{
128542 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
128543 + if (total_invalid)
128544 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
128545 + bpid, bpid + count - 1, count, total_invalid);
128546 +}
128547 +EXPORT_SYMBOL(bman_release_bpid_range);
128548 +
128549 +void bman_seed_bpid_range(u32 bpid, u32 count)
128550 +{
128551 + dpa_alloc_seed(&bpalloc, bpid, count);
128552 +}
128553 +EXPORT_SYMBOL(bman_seed_bpid_range);
128554 +
128555 +int bman_reserve_bpid_range(u32 bpid, u32 count)
128556 +{
128557 + return dpa_alloc_reserve(&bpalloc, bpid, count);
128558 +}
128559 +EXPORT_SYMBOL(bman_reserve_bpid_range);
128560 +
128561 +
128562 +/* FQID allocator front-end */
128563 +
128564 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
128565 +{
128566 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
128567 +}
128568 +EXPORT_SYMBOL(qman_alloc_fqid_range);
128569 +
128570 +static int fq_cleanup(u32 fqid)
128571 +{
128572 + return qman_shutdown_fq(fqid) == 0;
128573 +}
128574 +void qman_release_fqid_range(u32 fqid, u32 count)
128575 +{
128576 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
128577 + if (total_invalid)
128578 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
128579 + fqid, fqid + count - 1, count, total_invalid);
128580 +}
128581 +EXPORT_SYMBOL(qman_release_fqid_range);
128582 +
128583 +int qman_reserve_fqid_range(u32 fqid, u32 count)
128584 +{
128585 + return dpa_alloc_reserve(&fqalloc, fqid, count);
128586 +}
128587 +EXPORT_SYMBOL(qman_reserve_fqid_range);
128588 +
128589 +void qman_seed_fqid_range(u32 fqid, u32 count)
128590 +{
128591 + dpa_alloc_seed(&fqalloc, fqid, count);
128592 +}
128593 +EXPORT_SYMBOL(qman_seed_fqid_range);
128594 +
128595 +/* Pool-channel allocator front-end */
128596 +
128597 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
128598 +{
128599 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
128600 +}
128601 +EXPORT_SYMBOL(qman_alloc_pool_range);
128602 +
128603 +static int qpool_cleanup(u32 qp)
128604 +{
128605 + /* We query all FQDs starting from
128606 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128607 + * whose destination channel is the pool-channel being released.
128608 + * When a non-OOS FQD is found we attempt to clean it up */
128609 + struct qman_fq fq = {
128610 + .fqid = 1
128611 + };
128612 + int err;
128613 + do {
128614 + struct qm_mcr_queryfq_np np;
128615 + err = qman_query_fq_np(&fq, &np);
128616 + if (err)
128617 + /* FQID range exceeded, found no problems */
128618 + return 1;
128619 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128620 + struct qm_fqd fqd;
128621 + err = qman_query_fq(&fq, &fqd);
128622 + BUG_ON(err);
128623 + if (fqd.dest.channel == qp) {
128624 + /* The channel is the FQ's target, clean it */
128625 + if (qman_shutdown_fq(fq.fqid) != 0)
128626 + /* Couldn't shut down the FQ
128627 + so the pool must be leaked */
128628 + return 0;
128629 + }
128630 + }
128631 + /* Move to the next FQID */
128632 + fq.fqid++;
128633 + } while (1);
128634 +}
128635 +void qman_release_pool_range(u32 qp, u32 count)
128636 +{
128637 + u32 total_invalid = release_id_range(&qpalloc, qp,
128638 + count, qpool_cleanup);
128639 + if (total_invalid) {
128640 + /* Pool channels are almost always used individually */
128641 + if (count == 1)
128642 + pr_err("Pool channel 0x%x had %d leaks\n",
128643 + qp, total_invalid);
128644 + else
128645 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
128646 + qp, qp + count - 1, count, total_invalid);
128647 + }
128648 +}
128649 +EXPORT_SYMBOL(qman_release_pool_range);
128650 +
128651 +
128652 +void qman_seed_pool_range(u32 poolid, u32 count)
128653 +{
128654 + dpa_alloc_seed(&qpalloc, poolid, count);
128655 +
128656 +}
128657 +EXPORT_SYMBOL(qman_seed_pool_range);
128658 +
128659 +int qman_reserve_pool_range(u32 poolid, u32 count)
128660 +{
128661 + return dpa_alloc_reserve(&qpalloc, poolid, count);
128662 +}
128663 +EXPORT_SYMBOL(qman_reserve_pool_range);
128664 +
128665 +
128666 +/* CGR ID allocator front-end */
128667 +
128668 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
128669 +{
128670 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
128671 +}
128672 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
128673 +
128674 +static int cqr_cleanup(u32 cgrid)
128675 +{
128676 + /* We query all FQDs starting from
128677 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
128678 + * whose CGR is the CGR being released.
128679 + */
128680 + struct qman_fq fq = {
128681 + .fqid = 1
128682 + };
128683 + int err;
128684 + do {
128685 + struct qm_mcr_queryfq_np np;
128686 + err = qman_query_fq_np(&fq, &np);
128687 + if (err)
128688 + /* FQID range exceeded, found no problems */
128689 + return 1;
128690 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
128691 + struct qm_fqd fqd;
128692 + err = qman_query_fq(&fq, &fqd);
128693 + BUG_ON(err);
128694 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
128695 + (fqd.cgid == cgrid)) {
128696 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
128697 + " CGR will be leaked\n",
128698 + cgrid, fq.fqid);
128699 + return 1;
128700 + }
128701 + }
128702 + /* Move to the next FQID */
128703 + fq.fqid++;
128704 + } while (1);
128705 +}
128706 +
128707 +void qman_release_cgrid_range(u32 cgrid, u32 count)
128708 +{
128709 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
128710 + count, cqr_cleanup);
128711 + if (total_invalid)
128712 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
128713 + cgrid, cgrid + count - 1, count, total_invalid);
128714 +}
128715 +EXPORT_SYMBOL(qman_release_cgrid_range);
128716 +
128717 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
128718 +{
128719 + dpa_alloc_seed(&cgralloc, cgrid, count);
128720 +
128721 +}
128722 +EXPORT_SYMBOL(qman_seed_cgrid_range);
128723 +
128724 +/* CEETM CHANNEL ID allocator front-end */
128725 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
128726 + int partial)
128727 +{
128728 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
128729 +}
128730 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
128731 +
128732 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
128733 + int partial)
128734 +{
128735 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
128736 +}
128737 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
128738 +
128739 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
128740 +{
128741 + u32 total_invalid;
128742 +
128743 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
128744 + NULL);
128745 + if (total_invalid)
128746 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128747 + channelid, channelid + count - 1, count, total_invalid);
128748 +}
128749 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
128750 +
128751 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
128752 +{
128753 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
128754 +
128755 +}
128756 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
128757 +
128758 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
128759 +{
128760 + u32 total_invalid;
128761 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
128762 + NULL);
128763 + if (total_invalid)
128764 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
128765 + channelid, channelid + count - 1, count, total_invalid);
128766 +}
128767 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
128768 +
128769 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
128770 +{
128771 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
128772 +
128773 +}
128774 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
128775 +
128776 +/* CEETM LFQID allocator front-end */
128777 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
128778 + int partial)
128779 +{
128780 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
128781 +}
128782 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
128783 +
128784 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
128785 + int partial)
128786 +{
128787 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
128788 +}
128789 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
128790 +
128791 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
128792 +{
128793 + u32 total_invalid;
128794 +
128795 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
128796 + NULL);
128797 + if (total_invalid)
128798 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128799 + lfqid, lfqid + count - 1, count, total_invalid);
128800 +}
128801 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
128802 +
128803 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
128804 +{
128805 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
128806 +
128807 +}
128808 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
128809 +
128810 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
128811 +{
128812 + u32 total_invalid;
128813 +
128814 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
128815 + NULL);
128816 + if (total_invalid)
128817 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
128818 + lfqid, lfqid + count - 1, count, total_invalid);
128819 +}
128820 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
128821 +
128822 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
128823 +{
128824 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
128825 +
128826 +}
128827 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
128828 +
128829 +
128830 +/* Everything else is the common backend to all the allocators */
128831 +
128832 +/* The allocator is a (possibly-empty) list of these; */
128833 +struct alloc_node {
128834 + struct list_head list;
128835 + u32 base;
128836 + u32 num;
128837 + /* refcount and is_alloced are only set
128838 + when the node is in the used list */
128839 + unsigned int refcount;
128840 + int is_alloced;
128841 +};
128842 +
128843 +/* #define DPA_ALLOC_DEBUG */
128844 +
128845 +#ifdef DPA_ALLOC_DEBUG
128846 +#define DPRINT pr_info
128847 +static void DUMP(struct dpa_alloc *alloc)
128848 +{
128849 + int off = 0;
128850 + char buf[256];
128851 + struct alloc_node *p;
128852 + pr_info("Free Nodes\n");
128853 + list_for_each_entry(p, &alloc->free, list) {
128854 + if (off < 255)
128855 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128856 + p->base, p->base + p->num - 1);
128857 + }
128858 + pr_info("%s\n", buf);
128859 +
128860 + off = 0;
128861 + pr_info("Used Nodes\n");
128862 + list_for_each_entry(p, &alloc->used, list) {
128863 + if (off < 255)
128864 + off += snprintf(buf + off, 255-off, "{%d,%d}",
128865 + p->base, p->base + p->num - 1);
128866 + }
128867 + pr_info("%s\n", buf);
128868 +
128869 +
128870 +
128871 +}
128872 +#else
128873 +#define DPRINT(x...)
128874 +#define DUMP(a)
128875 +#endif
128876 +
128877 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
128878 + int partial)
128879 +{
128880 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
128881 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
128882 + struct alloc_node *margin_left, *margin_right;
128883 +
128884 + *result = (u32)-1;
128885 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
128886 + DUMP(alloc);
128887 + /* If 'align' is 0, it should behave as though it was 1 */
128888 + if (!align)
128889 + align = 1;
128890 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
128891 + if (!margin_left)
128892 + goto err;
128893 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
128894 + if (!margin_right) {
128895 + kfree(margin_left);
128896 + goto err;
128897 + }
128898 + spin_lock_irq(&alloc->lock);
128899 + list_for_each_entry(i, &alloc->free, list) {
128900 + base = (i->base + align - 1) / align;
128901 + base *= align;
128902 + if ((base - i->base) >= i->num)
128903 + /* alignment is impossible, regardless of count */
128904 + continue;
128905 + num = i->num - (base - i->base);
128906 + if (num >= count) {
128907 + /* this one will do nicely */
128908 + num = count;
128909 + goto done;
128910 + }
128911 + if (num > next_best_num) {
128912 + next_best = i;
128913 + next_best_base = base;
128914 + next_best_num = num;
128915 + }
128916 + }
128917 + if (partial && next_best) {
128918 + i = next_best;
128919 + base = next_best_base;
128920 + num = next_best_num;
128921 + } else
128922 + i = NULL;
128923 +done:
128924 + if (i) {
128925 + if (base != i->base) {
128926 + margin_left->base = i->base;
128927 + margin_left->num = base - i->base;
128928 + list_add_tail(&margin_left->list, &i->list);
128929 + } else
128930 + kfree(margin_left);
128931 + if ((base + num) < (i->base + i->num)) {
128932 + margin_right->base = base + num;
128933 + margin_right->num = (i->base + i->num) -
128934 + (base + num);
128935 + list_add(&margin_right->list, &i->list);
128936 + } else
128937 + kfree(margin_right);
128938 + list_del(&i->list);
128939 + kfree(i);
128940 + *result = base;
128941 + } else {
128942 + spin_unlock_irq(&alloc->lock);
128943 + kfree(margin_left);
128944 + kfree(margin_right);
128945 + }
128946 +
128947 +err:
128948 + DPRINT("returning %d\n", i ? num : -ENOMEM);
128949 + DUMP(alloc);
128950 + if (!i)
128951 + return -ENOMEM;
128952 +
128953 + /* Add the allocation to the used list with a refcount of 1 */
128954 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
128955 + if (!used_node) {
128956 + spin_unlock_irq(&alloc->lock);
128957 + return -ENOMEM;
128958 + }
128959 + used_node->base = *result;
128960 + used_node->num = num;
128961 + used_node->refcount = 1;
128962 + used_node->is_alloced = 1;
128963 + list_add_tail(&used_node->list, &alloc->used);
128964 + spin_unlock_irq(&alloc->lock);
128965 + return (int)num;
128966 +}
128967 +
128968 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
128969 + * forcing error-handling on to users in the deallocation path. */
128970 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
128971 +{
128972 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
128973 + BUG_ON(!node);
128974 + DPRINT("release_range(%d,%d)\n", base_id, count);
128975 + DUMP(alloc);
128976 + BUG_ON(!count);
128977 + spin_lock_irq(&alloc->lock);
128978 +
128979 +
128980 + node->base = base_id;
128981 + node->num = count;
128982 + list_for_each_entry(i, &alloc->free, list) {
128983 + if (i->base >= node->base) {
128984 + /* BUG_ON(any overlapping) */
128985 + BUG_ON(i->base < (node->base + node->num));
128986 + list_add_tail(&node->list, &i->list);
128987 + goto done;
128988 + }
128989 + }
128990 + list_add_tail(&node->list, &alloc->free);
128991 +done:
128992 + /* Merge to the left */
128993 + i = list_entry(node->list.prev, struct alloc_node, list);
128994 + if (node->list.prev != &alloc->free) {
128995 + BUG_ON((i->base + i->num) > node->base);
128996 + if ((i->base + i->num) == node->base) {
128997 + node->base = i->base;
128998 + node->num += i->num;
128999 + list_del(&i->list);
129000 + kfree(i);
129001 + }
129002 + }
129003 + /* Merge to the right */
129004 + i = list_entry(node->list.next, struct alloc_node, list);
129005 + if (node->list.next != &alloc->free) {
129006 + BUG_ON((node->base + node->num) > i->base);
129007 + if ((node->base + node->num) == i->base) {
129008 + node->num += i->num;
129009 + list_del(&i->list);
129010 + kfree(i);
129011 + }
129012 + }
129013 + spin_unlock_irq(&alloc->lock);
129014 + DUMP(alloc);
129015 +}
129016 +
129017 +
129018 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
129019 +{
129020 + struct alloc_node *i = NULL;
129021 + spin_lock_irq(&alloc->lock);
129022 +
129023 + /* First find the node in the used list and decrement its ref count */
129024 + list_for_each_entry(i, &alloc->used, list) {
129025 + if (i->base == base_id && i->num == count) {
129026 + --i->refcount;
129027 + if (i->refcount == 0) {
129028 + list_del(&i->list);
129029 + spin_unlock_irq(&alloc->lock);
129030 + if (i->is_alloced)
129031 + _dpa_alloc_free(alloc, base_id, count);
129032 + kfree(i);
129033 + return;
129034 + }
129035 + spin_unlock_irq(&alloc->lock);
129036 + return;
129037 + }
129038 + }
129039 + /* Couldn't find the allocation */
129040 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
129041 + base_id, count);
129042 + spin_unlock_irq(&alloc->lock);
129043 +}
129044 +
129045 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
129046 +{
129047 + /* Same as free but no previous allocation checking is needed */
129048 + _dpa_alloc_free(alloc, base_id, count);
129049 +}
129050 +
129051 +
129052 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
129053 +{
129054 + struct alloc_node *i = NULL, *used_node;
129055 +
129056 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
129057 + DUMP(alloc);
129058 +
129059 + spin_lock_irq(&alloc->lock);
129060 +
129061 + /* Check for the node in the used list.
129062 + If found, increase it's refcount */
129063 + list_for_each_entry(i, &alloc->used, list) {
129064 + if ((i->base == base) && (i->num == num)) {
129065 + ++i->refcount;
129066 + spin_unlock_irq(&alloc->lock);
129067 + return 0;
129068 + }
129069 + if ((base >= i->base) && (base < (i->base + i->num))) {
129070 + /* This is an attempt to reserve a region that was
129071 + already reserved or alloced with a different
129072 + base or num */
129073 + pr_err("Cannot reserve %d - %d, it overlaps with"
129074 + " existing reservation from %d - %d\n",
129075 + base, base + num - 1, i->base,
129076 + i->base + i->num - 1);
129077 + spin_unlock_irq(&alloc->lock);
129078 + return -1;
129079 + }
129080 + }
129081 + /* Check to make sure this ID isn't in the free list */
129082 + list_for_each_entry(i, &alloc->free, list) {
129083 + if ((base >= i->base) && (base < (i->base + i->num))) {
129084 + /* yep, the reservation is within this node */
129085 + pr_err("Cannot reserve %d - %d, it overlaps with"
129086 + " free range %d - %d and must be alloced\n",
129087 + base, base + num - 1,
129088 + i->base, i->base + i->num - 1);
129089 + spin_unlock_irq(&alloc->lock);
129090 + return -1;
129091 + }
129092 + }
129093 + /* Add the allocation to the used list with a refcount of 1 */
129094 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
129095 + if (!used_node) {
129096 + spin_unlock_irq(&alloc->lock);
129097 + return -ENOMEM;
129098 +
129099 + }
129100 + used_node->base = base;
129101 + used_node->num = num;
129102 + used_node->refcount = 1;
129103 + used_node->is_alloced = 0;
129104 + list_add_tail(&used_node->list, &alloc->used);
129105 + spin_unlock_irq(&alloc->lock);
129106 + return 0;
129107 +}
129108 +
129109 +
129110 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
129111 +{
129112 + struct alloc_node *i = NULL;
129113 + DPRINT("alloc_pop()\n");
129114 + DUMP(alloc);
129115 + spin_lock_irq(&alloc->lock);
129116 + if (!list_empty(&alloc->free)) {
129117 + i = list_entry(alloc->free.next, struct alloc_node, list);
129118 + list_del(&i->list);
129119 + }
129120 + spin_unlock_irq(&alloc->lock);
129121 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
129122 + DUMP(alloc);
129123 + if (!i)
129124 + return -ENOMEM;
129125 + *result = i->base;
129126 + *count = i->num;
129127 + kfree(i);
129128 + return 0;
129129 +}
129130 +
129131 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
129132 +{
129133 + struct alloc_node *i = NULL;
129134 + int res = 0;
129135 + DPRINT("alloc_check()\n");
129136 + spin_lock_irq(&list_head->lock);
129137 +
129138 + list_for_each_entry(i, &list_head->free, list) {
129139 + if ((item >= i->base) && (item < (i->base + i->num))) {
129140 + res = 1;
129141 + break;
129142 + }
129143 + }
129144 + spin_unlock_irq(&list_head->lock);
129145 + return res;
129146 +}
129147 --- /dev/null
129148 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
129149 @@ -0,0 +1,259 @@
129150 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
129151 + *
129152 + * Redistribution and use in source and binary forms, with or without
129153 + * modification, are permitted provided that the following conditions are met:
129154 + * * Redistributions of source code must retain the above copyright
129155 + * notice, this list of conditions and the following disclaimer.
129156 + * * Redistributions in binary form must reproduce the above copyright
129157 + * notice, this list of conditions and the following disclaimer in the
129158 + * documentation and/or other materials provided with the distribution.
129159 + * * Neither the name of Freescale Semiconductor nor the
129160 + * names of its contributors may be used to endorse or promote products
129161 + * derived from this software without specific prior written permission.
129162 + *
129163 + *
129164 + * ALTERNATIVELY, this software may be distributed under the terms of the
129165 + * GNU General Public License ("GPL") as published by the Free Software
129166 + * Foundation, either version 2 of that License or (at your option) any
129167 + * later version.
129168 + *
129169 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129170 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129171 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129172 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129173 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129174 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129175 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129176 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129177 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129178 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129179 + */
129180 +
129181 +#ifndef DPA_SYS_H
129182 +#define DPA_SYS_H
129183 +
129184 +#include <linux/kernel.h>
129185 +#include <linux/errno.h>
129186 +#include <linux/io.h>
129187 +#include <linux/dma-mapping.h>
129188 +#include <linux/bootmem.h>
129189 +#include <linux/slab.h>
129190 +#include <linux/module.h>
129191 +#include <linux/init.h>
129192 +#include <linux/interrupt.h>
129193 +#include <linux/delay.h>
129194 +#include <linux/of_platform.h>
129195 +#include <linux/of_address.h>
129196 +#include <linux/of_irq.h>
129197 +#include <linux/kthread.h>
129198 +#include <linux/memblock.h>
129199 +#include <linux/completion.h>
129200 +#include <linux/log2.h>
129201 +#include <linux/types.h>
129202 +#include <linux/ioctl.h>
129203 +#include <linux/miscdevice.h>
129204 +#include <linux/uaccess.h>
129205 +#include <linux/debugfs.h>
129206 +#include <linux/seq_file.h>
129207 +#include <linux/device.h>
129208 +#include <linux/uio_driver.h>
129209 +#include <linux/smp.h>
129210 +#include <linux/fsl_hypervisor.h>
129211 +#include <linux/vmalloc.h>
129212 +#include <linux/ctype.h>
129213 +#include <linux/math64.h>
129214 +#include <linux/bitops.h>
129215 +
129216 +#include <linux/fsl_usdpaa.h>
129217 +
129218 +/* When copying aligned words or shorts, try to avoid memcpy() */
129219 +#define CONFIG_TRY_BETTER_MEMCPY
129220 +
129221 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
129222 +#define DPA_PORTAL_CE 0
129223 +#define DPA_PORTAL_CI 1
129224 +
129225 +/***********************/
129226 +/* Misc inline assists */
129227 +/***********************/
129228 +
129229 +#if defined CONFIG_PPC32
129230 +#include "dpa_sys_ppc32.h"
129231 +#elif defined CONFIG_PPC64
129232 +#include "dpa_sys_ppc64.h"
129233 +#elif defined CONFIG_ARM
129234 +#include "dpa_sys_arm.h"
129235 +#elif defined CONFIG_ARM64
129236 +#include "dpa_sys_arm64.h"
129237 +#endif
129238 +
129239 +
129240 +#ifdef CONFIG_FSL_DPA_CHECKING
129241 +#define DPA_ASSERT(x) \
129242 + do { \
129243 + if (!(x)) { \
129244 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
129245 + __stringify_1(x)); \
129246 + dump_stack(); \
129247 + panic("assertion failure"); \
129248 + } \
129249 + } while (0)
129250 +#else
129251 +#define DPA_ASSERT(x)
129252 +#endif
129253 +
129254 +/* memcpy() stuff - when you know alignments in advance */
129255 +#ifdef CONFIG_TRY_BETTER_MEMCPY
129256 +static inline void copy_words(void *dest, const void *src, size_t sz)
129257 +{
129258 + u32 *__dest = dest;
129259 + const u32 *__src = src;
129260 + size_t __sz = sz >> 2;
129261 + BUG_ON((unsigned long)dest & 0x3);
129262 + BUG_ON((unsigned long)src & 0x3);
129263 + BUG_ON(sz & 0x3);
129264 + while (__sz--)
129265 + *(__dest++) = *(__src++);
129266 +}
129267 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
129268 +{
129269 + u16 *__dest = dest;
129270 + const u16 *__src = src;
129271 + size_t __sz = sz >> 1;
129272 + BUG_ON((unsigned long)dest & 0x1);
129273 + BUG_ON((unsigned long)src & 0x1);
129274 + BUG_ON(sz & 0x1);
129275 + while (__sz--)
129276 + *(__dest++) = *(__src++);
129277 +}
129278 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
129279 +{
129280 + u8 *__dest = dest;
129281 + const u8 *__src = src;
129282 + while (sz--)
129283 + *(__dest++) = *(__src++);
129284 +}
129285 +#else
129286 +#define copy_words memcpy
129287 +#define copy_shorts memcpy
129288 +#define copy_bytes memcpy
129289 +#endif
129290 +
129291 +/************/
129292 +/* RB-trees */
129293 +/************/
129294 +
129295 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
129296 + * non-linux systems. This also encapsulates the extra plumbing that linux code
129297 + * usually provides when using RB-trees. This encapsulation assumes that the
129298 + * data type held by the tree is u32. */
129299 +
129300 +struct dpa_rbtree {
129301 + struct rb_root root;
129302 +};
129303 +#define DPA_RBTREE { .root = RB_ROOT }
129304 +
129305 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
129306 +{
129307 + tree->root = RB_ROOT;
129308 +}
129309 +
129310 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
129311 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
129312 +{ \
129313 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
129314 + while (*p) { \
129315 + u32 item; \
129316 + parent = *p; \
129317 + item = rb_entry(parent, type, node_field)->val_field; \
129318 + if (obj->val_field < item) \
129319 + p = &parent->rb_left; \
129320 + else if (obj->val_field > item) \
129321 + p = &parent->rb_right; \
129322 + else \
129323 + return -EBUSY; \
129324 + } \
129325 + rb_link_node(&obj->node_field, parent, p); \
129326 + rb_insert_color(&obj->node_field, &tree->root); \
129327 + return 0; \
129328 +} \
129329 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
129330 +{ \
129331 + rb_erase(&obj->node_field, &tree->root); \
129332 +} \
129333 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
129334 +{ \
129335 + type *ret; \
129336 + struct rb_node *p = tree->root.rb_node; \
129337 + while (p) { \
129338 + ret = rb_entry(p, type, node_field); \
129339 + if (val < ret->val_field) \
129340 + p = p->rb_left; \
129341 + else if (val > ret->val_field) \
129342 + p = p->rb_right; \
129343 + else \
129344 + return ret; \
129345 + } \
129346 + return NULL; \
129347 +}
129348 +
129349 +/************/
129350 +/* Bootargs */
129351 +/************/
129352 +
129353 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
129354 + * though; a comma-separated list of items, each item being a cpu index and/or a
129355 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
129356 + * that the portal associated with that cpu should be shared. See bman_driver.c
129357 + * for more specifics. */
129358 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
129359 +{
129360 + *cpu = 0;
129361 + if (!isdigit(**s))
129362 + return -EINVAL;
129363 + while (isdigit(**s))
129364 + *cpu = *cpu * 10 + (*((*s)++) - '0');
129365 + return 0;
129366 +}
129367 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
129368 + struct cpumask *want_unshared,
129369 + const char *argname)
129370 +{
129371 + const char *s = str;
129372 + unsigned int shared, cpu1, cpu2, loop;
129373 +
129374 +keep_going:
129375 + if (*s == 's') {
129376 + shared = 1;
129377 + s++;
129378 + } else
129379 + shared = 0;
129380 + if (__parse_portals_cpu(&s, &cpu1))
129381 + goto err;
129382 + if (*s == '-') {
129383 + s++;
129384 + if (__parse_portals_cpu(&s, &cpu2))
129385 + goto err;
129386 + if (cpu2 < cpu1)
129387 + goto err;
129388 + } else
129389 + cpu2 = cpu1;
129390 + for (loop = cpu1; loop <= cpu2; loop++)
129391 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
129392 + if (*s == ',') {
129393 + s++;
129394 + goto keep_going;
129395 + } else if ((*s == '\0') || isspace(*s))
129396 + return 0;
129397 +err:
129398 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
129399 + (unsigned long)s - (unsigned long)str);
129400 + return -EINVAL;
129401 +}
129402 +#ifdef CONFIG_FSL_USDPAA
129403 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
129404 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
129405 + enum usdpaa_portal_type ptype, unsigned int *irq,
129406 + void **iir_reg);
129407 +#endif
129408 +#endif /* DPA_SYS_H */
129409 --- /dev/null
129410 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
129411 @@ -0,0 +1,95 @@
129412 +/* Copyright 2016 Freescale Semiconductor, Inc.
129413 + *
129414 + * Redistribution and use in source and binary forms, with or without
129415 + * modification, are permitted provided that the following conditions are met:
129416 + * * Redistributions of source code must retain the above copyright
129417 + * notice, this list of conditions and the following disclaimer.
129418 + * * Redistributions in binary form must reproduce the above copyright
129419 + * notice, this list of conditions and the following disclaimer in the
129420 + * documentation and/or other materials provided with the distribution.
129421 + * * Neither the name of Freescale Semiconductor nor the
129422 + * names of its contributors may be used to endorse or promote products
129423 + * derived from this software without specific prior written permission.
129424 + *
129425 + *
129426 + * ALTERNATIVELY, this software may be distributed under the terms of the
129427 + * GNU General Public License ("GPL") as published by the Free Software
129428 + * Foundation, either version 2 of that License or (at your option) any
129429 + * later version.
129430 + *
129431 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129432 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129433 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129434 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129435 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129436 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129437 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129438 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129439 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129440 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129441 + */
129442 +
129443 +#ifndef DPA_SYS_ARM_H
129444 +#define DPA_SYS_ARM_H
129445 +
129446 +#include <asm/cacheflush.h>
129447 +#include <asm/barrier.h>
129448 +
129449 +/* Implementation of ARM specific routines */
129450 +
129451 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129452 + * barriers and that dcb*() won't fall victim to compiler or execution
129453 + * reordering with respect to other code/instructions that manipulate the same
129454 + * cacheline. */
129455 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129456 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129457 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
129458 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
129459 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
129460 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
129461 +
129462 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
129463 +
129464 +#define dcbf_64(p) \
129465 + do { \
129466 + dcbf((u32)p); \
129467 + } while (0)
129468 +/* Commonly used combo */
129469 +#define dcbit_ro(p) \
129470 + do { \
129471 + dcbi((u32)p); \
129472 + dcbt_ro((u32)p); \
129473 + } while (0)
129474 +
129475 +static inline u64 mfatb(void)
129476 +{
129477 + return get_cycles();
129478 +}
129479 +
129480 +static inline u32 in_be32(volatile void *addr)
129481 +{
129482 + return be32_to_cpu(*((volatile u32 *) addr));
129483 +}
129484 +
129485 +static inline void out_be32(void *addr, u32 val)
129486 +{
129487 + *((u32 *) addr) = cpu_to_be32(val);
129488 +}
129489 +
129490 +
129491 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129492 +{
129493 + *p |= mask;
129494 +}
129495 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129496 +{
129497 + *p &= ~mask;
129498 +}
129499 +
129500 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129501 +{
129502 + __cpuc_flush_dcache_area((void *) start, stop - start);
129503 +}
129504 +
129505 +#define hard_smp_processor_id() raw_smp_processor_id()
129506 +#endif
129507 --- /dev/null
129508 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
129509 @@ -0,0 +1,102 @@
129510 +/* Copyright 2014 Freescale Semiconductor, Inc.
129511 + *
129512 + * Redistribution and use in source and binary forms, with or without
129513 + * modification, are permitted provided that the following conditions are met:
129514 + * * Redistributions of source code must retain the above copyright
129515 + * notice, this list of conditions and the following disclaimer.
129516 + * * Redistributions in binary form must reproduce the above copyright
129517 + * notice, this list of conditions and the following disclaimer in the
129518 + * documentation and/or other materials provided with the distribution.
129519 + * * Neither the name of Freescale Semiconductor nor the
129520 + * names of its contributors may be used to endorse or promote products
129521 + * derived from this software without specific prior written permission.
129522 + *
129523 + *
129524 + * ALTERNATIVELY, this software may be distributed under the terms of the
129525 + * GNU General Public License ("GPL") as published by the Free Software
129526 + * Foundation, either version 2 of that License or (at your option) any
129527 + * later version.
129528 + *
129529 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129530 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129531 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129532 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129533 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129534 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129535 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129536 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129537 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129538 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129539 + */
129540 +
129541 +#ifndef DPA_SYS_ARM64_H
129542 +#define DPA_SYS_ARM64_H
129543 +
129544 +#include <asm/cacheflush.h>
129545 +#include <asm/barrier.h>
129546 +
129547 +/* Implementation of ARM 64 bit specific routines */
129548 +
129549 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129550 + * barriers and that dcb*() won't fall victim to compiler or execution
129551 + * reordering with respect to other code/instructions that manipulate the same
129552 + * cacheline. */
129553 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
129554 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
129555 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
129556 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
129557 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
129558 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
129559 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
129560 +
129561 +#define dcbz_64(p) \
129562 + do { \
129563 + dcbz(p); \
129564 + } while (0)
129565 +
129566 +#define dcbf_64(p) \
129567 + do { \
129568 + dcbf(p); \
129569 + } while (0)
129570 +/* Commonly used combo */
129571 +#define dcbit_ro(p) \
129572 + do { \
129573 + dcbi(p); \
129574 + dcbt_ro(p); \
129575 + } while (0)
129576 +
129577 +static inline u64 mfatb(void)
129578 +{
129579 + return get_cycles();
129580 +}
129581 +
129582 +static inline u32 in_be32(volatile void *addr)
129583 +{
129584 + return be32_to_cpu(*((volatile u32 *) addr));
129585 +}
129586 +
129587 +static inline void out_be32(void *addr, u32 val)
129588 +{
129589 + *((u32 *) addr) = cpu_to_be32(val);
129590 +}
129591 +
129592 +
129593 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
129594 +{
129595 + *p |= mask;
129596 +}
129597 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
129598 +{
129599 + *p &= ~mask;
129600 +}
129601 +
129602 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
129603 +{
129604 + __flush_dcache_area((void *) start, stop - start);
129605 +}
129606 +
129607 +#define hard_smp_processor_id() raw_smp_processor_id()
129608 +
129609 +
129610 +
129611 +#endif
129612 --- /dev/null
129613 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
129614 @@ -0,0 +1,70 @@
129615 +/* Copyright 2014 Freescale Semiconductor, Inc.
129616 + *
129617 + * Redistribution and use in source and binary forms, with or without
129618 + * modification, are permitted provided that the following conditions are met:
129619 + * * Redistributions of source code must retain the above copyright
129620 + * notice, this list of conditions and the following disclaimer.
129621 + * * Redistributions in binary form must reproduce the above copyright
129622 + * notice, this list of conditions and the following disclaimer in the
129623 + * documentation and/or other materials provided with the distribution.
129624 + * * Neither the name of Freescale Semiconductor nor the
129625 + * names of its contributors may be used to endorse or promote products
129626 + * derived from this software without specific prior written permission.
129627 + *
129628 + *
129629 + * ALTERNATIVELY, this software may be distributed under the terms of the
129630 + * GNU General Public License ("GPL") as published by the Free Software
129631 + * Foundation, either version 2 of that License or (at your option) any
129632 + * later version.
129633 + *
129634 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129635 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129636 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129637 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129638 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129639 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129640 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129641 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129642 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129643 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129644 + */
129645 +
129646 +#ifndef DPA_SYS_PPC32_H
129647 +#define DPA_SYS_PPC32_H
129648 +
129649 +/* Implementation of PowerPC 32 bit specific routines */
129650 +
129651 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129652 + * barriers and that dcb*() won't fall victim to compiler or execution
129653 + * reordering with respect to other code/instructions that manipulate the same
129654 + * cacheline. */
129655 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129656 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129657 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129658 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129659 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129660 +#define dcbi(p) dcbf(p)
129661 +
129662 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
129663 +#define dcbz_64(p) dcbzl(p)
129664 +#define dcbf_64(p) dcbf(p)
129665 +
129666 +/* Commonly used combo */
129667 +#define dcbit_ro(p) \
129668 + do { \
129669 + dcbi(p); \
129670 + dcbt_ro(p); \
129671 + } while (0)
129672 +
129673 +static inline u64 mfatb(void)
129674 +{
129675 + u32 hi, lo, chk;
129676 + do {
129677 + hi = mfspr(SPRN_ATBU);
129678 + lo = mfspr(SPRN_ATBL);
129679 + chk = mfspr(SPRN_ATBU);
129680 + } while (unlikely(hi != chk));
129681 + return ((u64)hi << 32) | (u64)lo;
129682 +}
129683 +
129684 +#endif
129685 --- /dev/null
129686 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
129687 @@ -0,0 +1,79 @@
129688 +/* Copyright 2014 Freescale Semiconductor, Inc.
129689 + *
129690 + * Redistribution and use in source and binary forms, with or without
129691 + * modification, are permitted provided that the following conditions are met:
129692 + * * Redistributions of source code must retain the above copyright
129693 + * notice, this list of conditions and the following disclaimer.
129694 + * * Redistributions in binary form must reproduce the above copyright
129695 + * notice, this list of conditions and the following disclaimer in the
129696 + * documentation and/or other materials provided with the distribution.
129697 + * * Neither the name of Freescale Semiconductor nor the
129698 + * names of its contributors may be used to endorse or promote products
129699 + * derived from this software without specific prior written permission.
129700 + *
129701 + *
129702 + * ALTERNATIVELY, this software may be distributed under the terms of the
129703 + * GNU General Public License ("GPL") as published by the Free Software
129704 + * Foundation, either version 2 of that License or (at your option) any
129705 + * later version.
129706 + *
129707 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129708 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129709 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129710 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129711 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129712 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129713 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129714 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129715 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129716 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129717 + */
129718 +
129719 +#ifndef DPA_SYS_PPC64_H
129720 +#define DPA_SYS_PPC64_H
129721 +
129722 +/* Implementation of PowerPC 64 bit specific routines */
129723 +
129724 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
129725 + * barriers and that dcb*() won't fall victim to compiler or execution
129726 + * reordering with respect to other code/instructions that manipulate the same
129727 + * cacheline. */
129728 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
129729 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
129730 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
129731 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
129732 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
129733 +#define dcbi(p) dcbf(p)
129734 +
129735 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
129736 +#define dcbz_64(p) \
129737 + do { \
129738 + dcbz((void*)p + 32); \
129739 + dcbz(p); \
129740 + } while (0)
129741 +#define dcbf_64(p) \
129742 + do { \
129743 + dcbf((void*)p + 32); \
129744 + dcbf(p); \
129745 + } while (0)
129746 +/* Commonly used combo */
129747 +#define dcbit_ro(p) \
129748 + do { \
129749 + dcbi(p); \
129750 + dcbi((void*)p + 32); \
129751 + dcbt_ro(p); \
129752 + dcbt_ro((void*)p + 32); \
129753 + } while (0)
129754 +
129755 +static inline u64 mfatb(void)
129756 +{
129757 + u32 hi, lo, chk;
129758 + do {
129759 + hi = mfspr(SPRN_ATBU);
129760 + lo = mfspr(SPRN_ATBL);
129761 + chk = mfspr(SPRN_ATBU);
129762 + } while (unlikely(hi != chk));
129763 + return ((u64)hi << 32) | (u64)lo;
129764 +}
129765 +
129766 +#endif
129767 --- /dev/null
129768 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
129769 @@ -0,0 +1,2007 @@
129770 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
129771 + * Authors: Andy Fleming <afleming@freescale.com>
129772 + * Timur Tabi <timur@freescale.com>
129773 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
129774 + *
129775 + * This file is licensed under the terms of the GNU General Public License
129776 + * version 2. This program is licensed "as is" without any warranty of any
129777 + * kind, whether express or implied.
129778 + */
129779 +
129780 +
129781 +#include <linux/miscdevice.h>
129782 +#include <linux/fs.h>
129783 +#include <linux/cdev.h>
129784 +#include <linux/mm.h>
129785 +#include <linux/of.h>
129786 +#include <linux/memblock.h>
129787 +#include <linux/slab.h>
129788 +#include <linux/mman.h>
129789 +#include <linux/of_reserved_mem.h>
129790 +
129791 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
129792 +#include <mm/mmu_decl.h>
129793 +#endif
129794 +
129795 +#include "dpa_sys.h"
129796 +#include <linux/fsl_usdpaa.h>
129797 +#include "bman_low.h"
129798 +#include "qman_low.h"
129799 +
129800 +/* Physical address range of the memory reservation, exported for mm/mem.c */
129801 +static u64 phys_start;
129802 +static u64 phys_size;
129803 +static u64 arg_phys_size;
129804 +
129805 +/* PFN versions of the above */
129806 +static unsigned long pfn_start;
129807 +static unsigned long pfn_size;
129808 +
129809 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
129810 + * isn't atomic_t). */
129811 +static DEFINE_SPINLOCK(mem_lock);
129812 +
129813 +/* The range of TLB1 indices */
129814 +static unsigned int first_tlb;
129815 +static unsigned int num_tlb = 1;
129816 +static unsigned int current_tlb; /* loops around for fault handling */
129817 +
129818 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
129819 + * may be mapped. Unmapped fragments are always merged where possible. */
129820 +static LIST_HEAD(mem_list);
129821 +
129822 +struct mem_mapping;
129823 +
129824 +/* Memory fragments are in 'mem_list'. */
129825 +struct mem_fragment {
129826 + u64 base;
129827 + u64 len;
129828 + unsigned long pfn_base; /* PFN version of 'base' */
129829 + unsigned long pfn_len; /* PFN version of 'len' */
129830 + unsigned int refs; /* zero if unmapped */
129831 + u64 root_len; /* Size of the orignal fragment */
129832 + unsigned long root_pfn; /* PFN of the orignal fragment */
129833 + struct list_head list;
129834 + /* if mapped, flags+name captured at creation time */
129835 + u32 flags;
129836 + char name[USDPAA_DMA_NAME_MAX];
129837 + u64 map_len;
129838 + /* support multi-process locks per-memory-fragment. */
129839 + int has_locking;
129840 + wait_queue_head_t wq;
129841 + struct mem_mapping *owner;
129842 +};
129843 +
129844 +/* Mappings of memory fragments in 'struct ctx'. These are created from
129845 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
129846 + * mmap(). */
129847 +struct mem_mapping {
129848 + struct mem_fragment *root_frag;
129849 + u32 frag_count;
129850 + u64 total_size;
129851 + struct list_head list;
129852 + int refs;
129853 + void *virt_addr;
129854 +};
129855 +
129856 +struct portal_mapping {
129857 + struct usdpaa_ioctl_portal_map user;
129858 + union {
129859 + struct qm_portal_config *qportal;
129860 + struct bm_portal_config *bportal;
129861 + };
129862 + /* Declare space for the portals in case the process
129863 + exits unexpectedly and needs to be cleaned by the kernel */
129864 + union {
129865 + struct qm_portal qman_portal_low;
129866 + struct bm_portal bman_portal_low;
129867 + };
129868 + struct list_head list;
129869 + struct resource *phys;
129870 + struct iommu_domain *iommu_domain;
129871 +};
129872 +
129873 +/* Track the DPAA resources the process is using */
129874 +struct active_resource {
129875 + struct list_head list;
129876 + u32 id;
129877 + u32 num;
129878 + unsigned int refcount;
129879 +};
129880 +
129881 +/* Per-FD state (which should also be per-process but we don't enforce that) */
129882 +struct ctx {
129883 + /* Lock to protect the context */
129884 + spinlock_t lock;
129885 + /* Allocated resources get put here for accounting */
129886 + struct list_head resources[usdpaa_id_max];
129887 + /* list of DMA maps */
129888 + struct list_head maps;
129889 + /* list of portal maps */
129890 + struct list_head portals;
129891 +};
129892 +
129893 +/* Different resource classes */
129894 +static const struct alloc_backend {
129895 + enum usdpaa_id_type id_type;
129896 + int (*alloc)(u32 *, u32, u32, int);
129897 + void (*release)(u32 base, unsigned int count);
129898 + int (*reserve)(u32 base, unsigned int count);
129899 + const char *acronym;
129900 +} alloc_backends[] = {
129901 + {
129902 + .id_type = usdpaa_id_fqid,
129903 + .alloc = qman_alloc_fqid_range,
129904 + .release = qman_release_fqid_range,
129905 + .reserve = qman_reserve_fqid_range,
129906 + .acronym = "FQID"
129907 + },
129908 + {
129909 + .id_type = usdpaa_id_bpid,
129910 + .alloc = bman_alloc_bpid_range,
129911 + .release = bman_release_bpid_range,
129912 + .reserve = bman_reserve_bpid_range,
129913 + .acronym = "BPID"
129914 + },
129915 + {
129916 + .id_type = usdpaa_id_qpool,
129917 + .alloc = qman_alloc_pool_range,
129918 + .release = qman_release_pool_range,
129919 + .reserve = qman_reserve_pool_range,
129920 + .acronym = "QPOOL"
129921 + },
129922 + {
129923 + .id_type = usdpaa_id_cgrid,
129924 + .alloc = qman_alloc_cgrid_range,
129925 + .release = qman_release_cgrid_range,
129926 + .acronym = "CGRID"
129927 + },
129928 + {
129929 + .id_type = usdpaa_id_ceetm0_lfqid,
129930 + .alloc = qman_alloc_ceetm0_lfqid_range,
129931 + .release = qman_release_ceetm0_lfqid_range,
129932 + .acronym = "CEETM0_LFQID"
129933 + },
129934 + {
129935 + .id_type = usdpaa_id_ceetm0_channelid,
129936 + .alloc = qman_alloc_ceetm0_channel_range,
129937 + .release = qman_release_ceetm0_channel_range,
129938 + .acronym = "CEETM0_LFQID"
129939 + },
129940 + {
129941 + .id_type = usdpaa_id_ceetm1_lfqid,
129942 + .alloc = qman_alloc_ceetm1_lfqid_range,
129943 + .release = qman_release_ceetm1_lfqid_range,
129944 + .acronym = "CEETM1_LFQID"
129945 + },
129946 + {
129947 + .id_type = usdpaa_id_ceetm1_channelid,
129948 + .alloc = qman_alloc_ceetm1_channel_range,
129949 + .release = qman_release_ceetm1_channel_range,
129950 + .acronym = "CEETM1_LFQID"
129951 + },
129952 + {
129953 + /* This terminates the array */
129954 + .id_type = usdpaa_id_max
129955 + }
129956 +};
129957 +
129958 +/* Determines the largest acceptable page size for a given size
129959 + The sizes are determined by what the TLB1 acceptable page sizes are */
129960 +static u32 largest_page_size(u32 size)
129961 +{
129962 + int shift = 30; /* Start at 1G size */
129963 + if (size < 4096)
129964 + return 0;
129965 + do {
129966 + if (size >= (1<<shift))
129967 + return 1<<shift;
129968 + shift -= 2;
129969 + } while (shift >= 12); /* Up to 4k */
129970 + return 0;
129971 +}
129972 +
129973 +/* Determine if value is power of 4 */
129974 +static inline bool is_power_of_4(u64 x)
129975 +{
129976 + if (x == 0 || ((x & (x - 1)) != 0))
129977 + return false;
129978 + return !!(x & 0x5555555555555555ull);
129979 +}
129980 +
129981 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
129982 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
129983 + * until it has a suitable fragment size.) */
129984 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
129985 +{
129986 + struct mem_fragment *x[3];
129987 +
129988 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129989 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129990 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
129991 + if (!x[0] || !x[1] || !x[2]) {
129992 + kfree(x[0]);
129993 + kfree(x[1]);
129994 + kfree(x[2]);
129995 + return NULL;
129996 + }
129997 + BUG_ON(frag->refs);
129998 + frag->len >>= 2;
129999 + frag->pfn_len >>= 2;
130000 + x[0]->base = frag->base + frag->len;
130001 + x[1]->base = x[0]->base + frag->len;
130002 + x[2]->base = x[1]->base + frag->len;
130003 + x[0]->len = x[1]->len = x[2]->len = frag->len;
130004 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
130005 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
130006 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
130007 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
130008 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
130009 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
130010 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
130011 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
130012 + list_add_tail(&x[0]->list, &frag->list);
130013 + list_add_tail(&x[1]->list, &x[0]->list);
130014 + list_add_tail(&x[2]->list, &x[1]->list);
130015 + return x[2];
130016 +}
130017 +
130018 +static __maybe_unused void dump_frags(void)
130019 +{
130020 + struct mem_fragment *frag;
130021 + int i = 0;
130022 + list_for_each_entry(frag, &mem_list, list) {
130023 + pr_info("FRAG %d: base 0x%llx pfn_base 0x%lx len 0x%llx root_len 0x%llx root_pfn 0x%lx refs %d name %s\n",
130024 + i, frag->base, frag->pfn_base,
130025 + frag->len, frag->root_len, frag->root_pfn,
130026 + frag->refs, frag->name);
130027 + ++i;
130028 + }
130029 +}
130030 +
130031 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
130032 +static void compress_frags(void)
130033 +{
130034 + /* Walk the fragment list and combine fragments */
130035 + struct mem_fragment *frag, *nxtfrag;
130036 + u64 len = 0;
130037 +
130038 + int i, numfrags;
130039 +
130040 +
130041 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130042 +
130043 + while (&frag->list != &mem_list) {
130044 + /* Must combine consecutive fragemenst with
130045 + same root_pfn such that they are power of 4 */
130046 + if (frag->refs != 0) {
130047 + frag = list_entry(frag->list.next,
130048 + struct mem_fragment, list);
130049 + continue; /* Not this window */
130050 + }
130051 + len = frag->len;
130052 + numfrags = 0;
130053 + nxtfrag = list_entry(frag->list.next,
130054 + struct mem_fragment, list);
130055 + while (true) {
130056 + if (&nxtfrag->list == &mem_list) {
130057 + numfrags = 0;
130058 + break; /* End of list */
130059 + }
130060 + if (nxtfrag->refs) {
130061 + numfrags = 0;
130062 + break; /* In use still */
130063 + }
130064 + if (nxtfrag->root_pfn != frag->root_pfn) {
130065 + numfrags = 0;
130066 + break; /* Crosses root fragment boundary */
130067 + }
130068 + len += nxtfrag->len;
130069 + numfrags++;
130070 + if (is_power_of_4(len)) {
130071 + /* These fragments can be combined */
130072 + break;
130073 + }
130074 + nxtfrag = list_entry(nxtfrag->list.next,
130075 + struct mem_fragment, list);
130076 + }
130077 + if (numfrags == 0) {
130078 + frag = list_entry(frag->list.next,
130079 + struct mem_fragment, list);
130080 + continue; /* try the next window */
130081 + }
130082 + for (i = 0; i < numfrags; i++) {
130083 + struct mem_fragment *todel =
130084 + list_entry(nxtfrag->list.prev,
130085 + struct mem_fragment, list);
130086 + nxtfrag->len += todel->len;
130087 + nxtfrag->pfn_len += todel->pfn_len;
130088 + list_del(&todel->list);
130089 + }
130090 + /* Re evaluate the list, things may merge now */
130091 + frag = list_entry(mem_list.next, struct mem_fragment, list);
130092 + }
130093 +}
130094 +
130095 +/* Hook from arch/powerpc/mm/mem.c */
130096 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
130097 +{
130098 + struct mem_fragment *frag;
130099 + int idx = -1;
130100 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
130101 + return -1;
130102 + /* It's in-range, we need to find the fragment */
130103 + spin_lock(&mem_lock);
130104 + list_for_each_entry(frag, &mem_list, list) {
130105 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
130106 + frag->pfn_len))) {
130107 + *phys_addr = frag->base;
130108 + *size = frag->len;
130109 + idx = current_tlb++;
130110 + if (current_tlb >= (first_tlb + num_tlb))
130111 + current_tlb = first_tlb;
130112 + break;
130113 + }
130114 + }
130115 + spin_unlock(&mem_lock);
130116 + return idx;
130117 +}
130118 +
130119 +static int usdpaa_open(struct inode *inode, struct file *filp)
130120 +{
130121 + const struct alloc_backend *backend = &alloc_backends[0];
130122 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
130123 + if (!ctx)
130124 + return -ENOMEM;
130125 + filp->private_data = ctx;
130126 +
130127 + while (backend->id_type != usdpaa_id_max) {
130128 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
130129 + backend++;
130130 + }
130131 +
130132 + INIT_LIST_HEAD(&ctx->maps);
130133 + INIT_LIST_HEAD(&ctx->portals);
130134 + spin_lock_init(&ctx->lock);
130135 +
130136 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
130137 +
130138 + return 0;
130139 +}
130140 +
130141 +#define DQRR_MAXFILL 15
130142 +
130143 +
130144 +/* Invalidate a portal */
130145 +void dbci_portal(void *addr)
130146 +{
130147 + int i;
130148 +
130149 + for (i = 0; i < 0x4000; i += 64)
130150 + dcbi(addr + i);
130151 +}
130152 +
130153 +/* Reset a QMan portal to its default state */
130154 +static int init_qm_portal(struct qm_portal_config *config,
130155 + struct qm_portal *portal)
130156 +{
130157 + const struct qm_dqrr_entry *dqrr = NULL;
130158 + int i;
130159 +
130160 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130161 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130162 +
130163 + /* Make sure interrupts are inhibited */
130164 + qm_out(IIR, 1);
130165 +
130166 + /*
130167 + * Invalidate the entire CE portal are to ensure no stale
130168 + * cachelines are present. This should be done on all
130169 + * cores as the portal is mapped as M=0 (non-coherent).
130170 + */
130171 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
130172 +
130173 + /* Initialize the DQRR. This will stop any dequeue
130174 + commands that are in progress */
130175 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
130176 + qm_dqrr_cdc, DQRR_MAXFILL)) {
130177 + pr_err("qm_dqrr_init() failed when trying to"
130178 + " recover portal, portal will be leaked\n");
130179 + return 1;
130180 + }
130181 +
130182 + /* Discard any entries on the DQRR */
130183 + /* If we consume the ring twice something is wrong */
130184 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
130185 + qm_dqrr_pvb_update(portal);
130186 + dqrr = qm_dqrr_current(portal);
130187 + if (!dqrr)
130188 + break;
130189 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
130190 + qm_dqrr_pvb_update(portal);
130191 + qm_dqrr_next(portal);
130192 + }
130193 + /* Initialize the EQCR */
130194 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
130195 + qm_eqcr_get_ci_stashing(portal), 1)) {
130196 + pr_err("Qman EQCR initialisation failed\n");
130197 + return 1;
130198 + }
130199 + /* initialize the MR */
130200 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
130201 + pr_err("Qman MR initialisation failed\n");
130202 + return 1;
130203 + }
130204 + qm_mr_pvb_update(portal);
130205 + while (qm_mr_current(portal)) {
130206 + qm_mr_next(portal);
130207 + qm_mr_cci_consume_to_current(portal);
130208 + qm_mr_pvb_update(portal);
130209 + }
130210 +
130211 + if (qm_mc_init(portal)) {
130212 + pr_err("Qman MC initialisation failed\n");
130213 + return 1;
130214 + }
130215 + return 0;
130216 +}
130217 +
130218 +static int init_bm_portal(struct bm_portal_config *config,
130219 + struct bm_portal *portal)
130220 +{
130221 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
130222 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
130223 +
130224 + /*
130225 + * Invalidate the entire CE portal are to ensure no stale
130226 + * cachelines are present. This should be done on all
130227 + * cores as the portal is mapped as M=0 (non-coherent).
130228 + */
130229 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
130230 +
130231 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
130232 + pr_err("Bman RCR initialisation failed\n");
130233 + return 1;
130234 + }
130235 + if (bm_mc_init(portal)) {
130236 + pr_err("Bman MC initialisation failed\n");
130237 + return 1;
130238 + }
130239 + return 0;
130240 +}
130241 +
130242 +/* Function that will scan all FQ's in the system. For each FQ that is not
130243 + OOS it will call the check_channel helper to determine if the FQ should
130244 + be torn down. If the check_channel helper returns true the FQ will be
130245 + transitioned to the OOS state */
130246 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
130247 + bool (*check_channel)(void*, u32))
130248 +{
130249 + u32 fq_id = 0;
130250 + while (1) {
130251 + struct qm_mc_command *mcc;
130252 + struct qm_mc_result *mcr;
130253 + u8 state;
130254 + u32 channel;
130255 +
130256 + /* Determine the channel for the FQID */
130257 + mcc = qm_mc_start(portal);
130258 + mcc->queryfq.fqid = fq_id;
130259 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
130260 + while (!(mcr = qm_mc_result(portal)))
130261 + cpu_relax();
130262 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130263 + == QM_MCR_VERB_QUERYFQ);
130264 + if (mcr->result != QM_MCR_RESULT_OK)
130265 + break; /* End of valid FQIDs */
130266 +
130267 + channel = mcr->queryfq.fqd.dest.channel;
130268 + /* Determine the state of the FQID */
130269 + mcc = qm_mc_start(portal);
130270 + mcc->queryfq_np.fqid = fq_id;
130271 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
130272 + while (!(mcr = qm_mc_result(portal)))
130273 + cpu_relax();
130274 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
130275 + == QM_MCR_VERB_QUERYFQ_NP);
130276 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
130277 + if (state == QM_MCR_NP_STATE_OOS)
130278 + /* Already OOS, no need to do anymore checks */
130279 + goto next;
130280 +
130281 + if (check_channel(ctx, channel))
130282 + qm_shutdown_fq(&portal, 1, fq_id);
130283 + next:
130284 + ++fq_id;
130285 + }
130286 + return 0;
130287 +}
130288 +
130289 +static bool check_channel_device(void *_ctx, u32 channel)
130290 +{
130291 + struct ctx *ctx = _ctx;
130292 + struct portal_mapping *portal, *tmpportal;
130293 + struct active_resource *res;
130294 +
130295 + /* See if the FQ is destined for one of the portals we're cleaning up */
130296 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130297 + if (portal->user.type == usdpaa_portal_qman) {
130298 + if (portal->qportal->public_cfg.channel == channel) {
130299 + /* This FQs destination is a portal
130300 + we're cleaning, send a retire */
130301 + return true;
130302 + }
130303 + }
130304 + }
130305 +
130306 + /* Check the pool channels that will be released as well */
130307 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
130308 + if ((res->id >= channel) &&
130309 + ((res->id + res->num - 1) <= channel))
130310 + return true;
130311 + }
130312 + return false;
130313 +}
130314 +
130315 +static bool check_portal_channel(void *ctx, u32 channel)
130316 +{
130317 + u32 portal_channel = *(u32 *)ctx;
130318 + if (portal_channel == channel) {
130319 + /* This FQs destination is a portal
130320 + we're cleaning, send a retire */
130321 + return true;
130322 + }
130323 + return false;
130324 +}
130325 +
130326 +
130327 +
130328 +
130329 +static int usdpaa_release(struct inode *inode, struct file *filp)
130330 +{
130331 + struct ctx *ctx = filp->private_data;
130332 + struct mem_mapping *map, *tmpmap;
130333 + struct portal_mapping *portal, *tmpportal;
130334 + const struct alloc_backend *backend = &alloc_backends[0];
130335 + struct active_resource *res;
130336 + struct qm_portal *qm_cleanup_portal = NULL;
130337 + struct bm_portal *bm_cleanup_portal = NULL;
130338 + struct qm_portal_config *qm_alloced_portal = NULL;
130339 + struct bm_portal_config *bm_alloced_portal = NULL;
130340 +
130341 + struct qm_portal *portal_array[qman_portal_max];
130342 + int portal_count = 0;
130343 +
130344 + /* Ensure the release operation cannot be migrated to another
130345 + CPU as CPU specific variables may be needed during cleanup */
130346 +#ifdef CONFIG_PREEMPT_RT_FULL
130347 + migrate_disable();
130348 +#endif
130349 + /* The following logic is used to recover resources that were not
130350 + correctly released by the process that is closing the FD.
130351 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
130352 + in the kernel
130353 + */
130354 +
130355 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130356 + /* Try to recover any portals that weren't shut down */
130357 + if (portal->user.type == usdpaa_portal_qman) {
130358 + portal_array[portal_count] = &portal->qman_portal_low;
130359 + ++portal_count;
130360 + init_qm_portal(portal->qportal,
130361 + &portal->qman_portal_low);
130362 + if (!qm_cleanup_portal) {
130363 + qm_cleanup_portal = &portal->qman_portal_low;
130364 + } else {
130365 + /* Clean FQs on the dedicated channel */
130366 + u32 chan = portal->qportal->public_cfg.channel;
130367 + qm_check_and_destroy_fqs(
130368 + &portal->qman_portal_low, &chan,
130369 + check_portal_channel);
130370 + }
130371 + } else {
130372 + /* BMAN */
130373 + init_bm_portal(portal->bportal,
130374 + &portal->bman_portal_low);
130375 + if (!bm_cleanup_portal)
130376 + bm_cleanup_portal = &portal->bman_portal_low;
130377 + }
130378 + }
130379 + /* If no portal was found, allocate one for cleanup */
130380 + if (!qm_cleanup_portal) {
130381 + qm_alloced_portal = qm_get_unused_portal();
130382 + if (!qm_alloced_portal) {
130383 + pr_crit("No QMan portal avalaible for cleanup\n");
130384 +#ifdef CONFIG_PREEMPT_RT_FULL
130385 + migrate_enable();
130386 +#endif
130387 + return -1;
130388 + }
130389 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
130390 + GFP_KERNEL);
130391 + if (!qm_cleanup_portal) {
130392 +#ifdef CONFIG_PREEMPT_RT_FULL
130393 + migrate_enable();
130394 +#endif
130395 + return -ENOMEM;
130396 + }
130397 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
130398 + portal_array[portal_count] = qm_cleanup_portal;
130399 + ++portal_count;
130400 + }
130401 + if (!bm_cleanup_portal) {
130402 + bm_alloced_portal = bm_get_unused_portal();
130403 + if (!bm_alloced_portal) {
130404 + pr_crit("No BMan portal avalaible for cleanup\n");
130405 +#ifdef CONFIG_PREEMPT_RT_FULL
130406 + migrate_enable();
130407 +#endif
130408 + return -1;
130409 + }
130410 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
130411 + GFP_KERNEL);
130412 + if (!bm_cleanup_portal) {
130413 +#ifdef CONFIG_PREEMPT_RT_FULL
130414 + migrate_enable();
130415 +#endif
130416 + return -ENOMEM;
130417 + }
130418 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
130419 + }
130420 +
130421 + /* OOS the FQs associated with this process */
130422 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
130423 +
130424 + while (backend->id_type != usdpaa_id_max) {
130425 + int leaks = 0;
130426 + list_for_each_entry(res, &ctx->resources[backend->id_type],
130427 + list) {
130428 + if (backend->id_type == usdpaa_id_fqid) {
130429 + int i = 0;
130430 + for (; i < res->num; i++) {
130431 + /* Clean FQs with the cleanup portal */
130432 + qm_shutdown_fq(portal_array,
130433 + portal_count,
130434 + res->id + i);
130435 + }
130436 + }
130437 + leaks += res->num;
130438 + backend->release(res->id, res->num);
130439 + }
130440 + if (leaks)
130441 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
130442 + backend->acronym, (leaks > 1) ? "s" : "");
130443 + backend++;
130444 + }
130445 + /* Release any DMA regions */
130446 + spin_lock(&mem_lock);
130447 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
130448 + struct mem_fragment *current_frag = map->root_frag;
130449 + int i;
130450 + if (map->root_frag->has_locking &&
130451 + (map->root_frag->owner == map)) {
130452 + map->root_frag->owner = NULL;
130453 + wake_up(&map->root_frag->wq);
130454 + }
130455 + /* Check each fragment and merge if the ref count is 0 */
130456 + for (i = 0; i < map->frag_count; i++) {
130457 + --current_frag->refs;
130458 + current_frag = list_entry(current_frag->list.prev,
130459 + struct mem_fragment, list);
130460 + }
130461 +
130462 + compress_frags();
130463 + list_del(&map->list);
130464 + kfree(map);
130465 + }
130466 + spin_unlock(&mem_lock);
130467 +
130468 + /* Return portals */
130469 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
130470 + if (portal->user.type == usdpaa_portal_qman) {
130471 + /* Give the portal back to the allocator */
130472 + init_qm_portal(portal->qportal,
130473 + &portal->qman_portal_low);
130474 + qm_put_unused_portal(portal->qportal);
130475 + } else {
130476 + init_bm_portal(portal->bportal,
130477 + &portal->bman_portal_low);
130478 + bm_put_unused_portal(portal->bportal);
130479 + }
130480 + list_del(&portal->list);
130481 + kfree(portal);
130482 + }
130483 + if (qm_alloced_portal) {
130484 + qm_put_unused_portal(qm_alloced_portal);
130485 + kfree(qm_cleanup_portal);
130486 + }
130487 + if (bm_alloced_portal) {
130488 + bm_put_unused_portal(bm_alloced_portal);
130489 + kfree(bm_cleanup_portal);
130490 + }
130491 +
130492 + kfree(ctx);
130493 +#ifdef CONFIG_PREEMPT_RT_FULL
130494 + migrate_enable();
130495 +#endif
130496 + return 0;
130497 +}
130498 +
130499 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
130500 + int *match, unsigned long *pfn)
130501 +{
130502 + struct mem_mapping *map;
130503 +
130504 + list_for_each_entry(map, &ctx->maps, list) {
130505 + int i;
130506 + struct mem_fragment *frag = map->root_frag;
130507 +
130508 + for (i = 0; i < map->frag_count; i++) {
130509 + if (frag->pfn_base == vma->vm_pgoff) {
130510 + *match = 1;
130511 + *pfn = frag->pfn_base;
130512 + return 0;
130513 + }
130514 + frag = list_entry(frag->list.next, struct mem_fragment,
130515 + list);
130516 + }
130517 + }
130518 + *match = 0;
130519 + return 0;
130520 +}
130521 +
130522 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
130523 + int *match, unsigned long *pfn)
130524 +{
130525 + *pfn = res->start >> PAGE_SHIFT;
130526 + if (*pfn == vma->vm_pgoff) {
130527 + *match = 1;
130528 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
130529 + return -EINVAL;
130530 + } else
130531 + *match = 0;
130532 + return 0;
130533 +}
130534 +
130535 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
130536 + int *match, unsigned long *pfn)
130537 +{
130538 + struct portal_mapping *portal;
130539 + int ret;
130540 +
130541 + list_for_each_entry(portal, &ctx->portals, list) {
130542 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
130543 + match, pfn);
130544 + if (*match) {
130545 + vma->vm_page_prot =
130546 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
130547 + pgprot_cached_ns(vma->vm_page_prot);
130548 +#else
130549 + pgprot_cached_noncoherent(vma->vm_page_prot);
130550 +#endif
130551 + return ret;
130552 + }
130553 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
130554 + match, pfn);
130555 + if (*match) {
130556 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
130557 + return ret;
130558 + }
130559 + }
130560 + *match = 0;
130561 + return 0;
130562 +}
130563 +
130564 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
130565 +{
130566 + struct ctx *ctx = filp->private_data;
130567 + unsigned long pfn = 0;
130568 + int match, ret;
130569 +
130570 + spin_lock(&mem_lock);
130571 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
130572 + if (!match)
130573 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
130574 + spin_unlock(&mem_lock);
130575 + if (!match)
130576 + return -EINVAL;
130577 + if (!ret)
130578 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
130579 + vma->vm_end - vma->vm_start,
130580 + vma->vm_page_prot);
130581 + return ret;
130582 +}
130583 +
130584 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
130585 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
130586 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
130587 + ({ \
130588 + unsigned long foo_align = (sz) - 1; \
130589 + ((addr) + foo_align) & ~foo_align; \
130590 + })
130591 +/* Searching for a size-aligned virtual address range starting from 'addr' */
130592 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
130593 + unsigned long addr,
130594 + unsigned long len,
130595 + unsigned long pgoff,
130596 + unsigned long flags)
130597 +{
130598 + struct vm_area_struct *vma;
130599 +
130600 + if (len % PAGE_SIZE)
130601 + return -EINVAL;
130602 + if (!len)
130603 + return -EINVAL;
130604 +
130605 + /* Need to align the address to the largest pagesize of the mapping
130606 + * because the MMU requires the virtual address to have the same
130607 + * alignment as the physical address */
130608 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
130609 + vma = find_vma(current->mm, addr);
130610 + /* Keep searching until we reach the end of currently-used virtual
130611 + * address-space or we find a big enough gap. */
130612 + while (vma) {
130613 + if ((addr + len) < vma->vm_start)
130614 + return addr;
130615 +
130616 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
130617 + vma = vma->vm_next;
130618 + }
130619 + if ((TASK_SIZE - len) < addr)
130620 + return -ENOMEM;
130621 + return addr;
130622 +}
130623 +
130624 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
130625 +{
130626 + struct usdpaa_ioctl_id_alloc i;
130627 + const struct alloc_backend *backend;
130628 + struct active_resource *res;
130629 + int ret = copy_from_user(&i, arg, sizeof(i));
130630 + if (ret)
130631 + return ret;
130632 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130633 + return -EINVAL;
130634 + backend = &alloc_backends[i.id_type];
130635 + /* Allocate the required resource type */
130636 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
130637 + if (ret < 0)
130638 + return ret;
130639 + i.num = ret;
130640 + /* Copy the result to user-space */
130641 + ret = copy_to_user(arg, &i, sizeof(i));
130642 + if (ret) {
130643 + backend->release(i.base, i.num);
130644 + return ret;
130645 + }
130646 + /* Assign the allocated range to the FD accounting */
130647 + res = kmalloc(sizeof(*res), GFP_KERNEL);
130648 + if (!res) {
130649 + backend->release(i.base, i.num);
130650 + return -ENOMEM;
130651 + }
130652 + spin_lock(&ctx->lock);
130653 + res->id = i.base;
130654 + res->num = i.num;
130655 + res->refcount = 1;
130656 + list_add(&res->list, &ctx->resources[i.id_type]);
130657 + spin_unlock(&ctx->lock);
130658 + return 0;
130659 +}
130660 +
130661 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
130662 +{
130663 + struct usdpaa_ioctl_id_release i;
130664 + const struct alloc_backend *backend;
130665 + struct active_resource *tmp, *pos;
130666 +
130667 + int ret = copy_from_user(&i, arg, sizeof(i));
130668 + if (ret)
130669 + return ret;
130670 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130671 + return -EINVAL;
130672 + backend = &alloc_backends[i.id_type];
130673 + /* Pull the range out of the FD accounting - the range is valid iff this
130674 + * succeeds. */
130675 + spin_lock(&ctx->lock);
130676 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130677 + if (pos->id == i.base && pos->num == i.num) {
130678 + pos->refcount--;
130679 + if (pos->refcount) {
130680 + spin_unlock(&ctx->lock);
130681 + return 0; /* Still being used */
130682 + }
130683 + list_del(&pos->list);
130684 + kfree(pos);
130685 + spin_unlock(&ctx->lock);
130686 + goto found;
130687 + }
130688 + }
130689 + /* Failed to find the resource */
130690 + spin_unlock(&ctx->lock);
130691 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
130692 + i.id_type, i.base, i.num);
130693 + return -EINVAL;
130694 +found:
130695 + /* Release the resource to the backend */
130696 + backend->release(i.base, i.num);
130697 + return 0;
130698 +}
130699 +
130700 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
130701 +{
130702 + struct usdpaa_ioctl_id_reserve i;
130703 + const struct alloc_backend *backend;
130704 + struct active_resource *tmp, *pos;
130705 +
130706 + int ret = copy_from_user(&i, arg, sizeof(i));
130707 + if (ret)
130708 + return ret;
130709 + if ((i.id_type >= usdpaa_id_max) || !i.num)
130710 + return -EINVAL;
130711 + backend = &alloc_backends[i.id_type];
130712 + if (!backend->reserve)
130713 + return -EINVAL;
130714 + /* Pull the range out of the FD accounting - the range is valid iff this
130715 + * succeeds. */
130716 + spin_lock(&ctx->lock);
130717 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
130718 + if (pos->id == i.base && pos->num == i.num) {
130719 + pos->refcount++;
130720 + spin_unlock(&ctx->lock);
130721 + return 0;
130722 + }
130723 + }
130724 +
130725 + /* Failed to find the resource */
130726 + spin_unlock(&ctx->lock);
130727 +
130728 + /* Reserve the resource in the backend */
130729 + ret = backend->reserve(i.base, i.num);
130730 + if (ret)
130731 + return ret;
130732 + /* Assign the reserved range to the FD accounting */
130733 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
130734 + if (!pos) {
130735 + backend->release(i.base, i.num);
130736 + return -ENOMEM;
130737 + }
130738 + spin_lock(&ctx->lock);
130739 + pos->id = i.base;
130740 + pos->num = i.num;
130741 + pos->refcount = 1;
130742 + list_add(&pos->list, &ctx->resources[i.id_type]);
130743 + spin_unlock(&ctx->lock);
130744 + return 0;
130745 +}
130746 +
130747 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
130748 + struct usdpaa_ioctl_dma_map *i)
130749 +{
130750 + struct mem_fragment *frag, *start_frag, *next_frag;
130751 + struct mem_mapping *map, *tmp;
130752 + int ret = 0;
130753 + u32 largest_page, so_far = 0;
130754 + int frag_count = 0;
130755 + unsigned long next_addr = PAGE_SIZE, populate;
130756 +
130757 + /* error checking to ensure values copied from user space are valid */
130758 + if (i->len % PAGE_SIZE)
130759 + return -EINVAL;
130760 +
130761 + map = kmalloc(sizeof(*map), GFP_KERNEL);
130762 + if (!map)
130763 + return -ENOMEM;
130764 +
130765 + spin_lock(&mem_lock);
130766 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
130767 + list_for_each_entry(frag, &mem_list, list) {
130768 + if (frag->refs && (frag->flags &
130769 + USDPAA_DMA_FLAG_SHARE) &&
130770 + !strncmp(i->name, frag->name,
130771 + USDPAA_DMA_NAME_MAX)) {
130772 + /* Matching entry */
130773 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
130774 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
130775 + ret = -EBUSY;
130776 + goto out;
130777 + }
130778 +
130779 + /* Check to ensure size matches record */
130780 + if (i->len != frag->map_len && i->len) {
130781 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
130782 + frag->name);
130783 + return -EINVAL;
130784 + }
130785 +
130786 + /* Check if this has already been mapped
130787 + to this process */
130788 + list_for_each_entry(tmp, &ctx->maps, list)
130789 + if (tmp->root_frag == frag) {
130790 + /* Already mapped, just need to
130791 + inc ref count */
130792 + tmp->refs++;
130793 + kfree(map);
130794 + i->did_create = 0;
130795 + i->len = tmp->total_size;
130796 + i->phys_addr = frag->base;
130797 + i->ptr = tmp->virt_addr;
130798 + spin_unlock(&mem_lock);
130799 + return 0;
130800 + }
130801 + /* Matching entry - just need to map */
130802 + i->has_locking = frag->has_locking;
130803 + i->did_create = 0;
130804 + i->len = frag->map_len;
130805 + start_frag = frag;
130806 + goto do_map;
130807 + }
130808 + }
130809 + /* No matching entry */
130810 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
130811 + pr_err("ioctl_dma_map() No matching entry\n");
130812 + ret = -ENOMEM;
130813 + goto out;
130814 + }
130815 + }
130816 + /* New fragment required, size must be provided. */
130817 + if (!i->len) {
130818 + ret = -EINVAL;
130819 + goto out;
130820 + }
130821 +
130822 + /* Find one of more contiguous fragments that satisfy the total length
130823 + trying to minimize the number of fragments
130824 + compute the largest page size that the allocation could use */
130825 + largest_page = largest_page_size(i->len);
130826 + start_frag = NULL;
130827 + while (largest_page &&
130828 + largest_page <= largest_page_size(phys_size) &&
130829 + start_frag == NULL) {
130830 + /* Search the list for a frag of that size */
130831 + list_for_each_entry(frag, &mem_list, list) {
130832 + if (!frag->refs && (frag->len == largest_page)) {
130833 + /* See if the next x fragments are free
130834 + and can accomidate the size */
130835 + u32 found_size = largest_page;
130836 + next_frag = list_entry(frag->list.prev,
130837 + struct mem_fragment,
130838 + list);
130839 + /* If the fragement is too small check
130840 + if the neighbours cab support it */
130841 + while (found_size < i->len) {
130842 + if (&mem_list == &next_frag->list)
130843 + break; /* End of list */
130844 + if (next_frag->refs != 0 ||
130845 + next_frag->len == 0)
130846 + break; /* not enough space */
130847 + found_size += next_frag->len;
130848 + next_frag = list_entry(
130849 + next_frag->list.prev,
130850 + struct mem_fragment,
130851 + list);
130852 + }
130853 + if (found_size >= i->len) {
130854 + /* Success! there is enough contigous
130855 + free space */
130856 + start_frag = frag;
130857 + break;
130858 + }
130859 + }
130860 + } /* next frag loop */
130861 + /* Couldn't statisfy the request with this
130862 + largest page size, try a smaller one */
130863 + largest_page <<= 2;
130864 + }
130865 + if (start_frag == NULL) {
130866 + /* Couldn't find proper amount of space */
130867 + ret = -ENOMEM;
130868 + goto out;
130869 + }
130870 + i->did_create = 1;
130871 +do_map:
130872 + /* Verify there is sufficient space to do the mapping */
130873 + down_write(&current->mm->mmap_sem);
130874 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
130875 + up_write(&current->mm->mmap_sem);
130876 +
130877 + if (next_addr & ~PAGE_MASK) {
130878 + ret = -ENOMEM;
130879 + goto out;
130880 + }
130881 +
130882 + /* We may need to divide the final fragment to accomidate the mapping */
130883 + next_frag = start_frag;
130884 + while (so_far != i->len) {
130885 + BUG_ON(next_frag->len == 0);
130886 + while ((next_frag->len + so_far) > i->len) {
130887 + /* Split frag until they match */
130888 + split_frag(next_frag);
130889 + }
130890 + so_far += next_frag->len;
130891 + next_frag->refs++;
130892 + ++frag_count;
130893 + next_frag = list_entry(next_frag->list.prev,
130894 + struct mem_fragment, list);
130895 + }
130896 + if (i->did_create) {
130897 + size_t name_len = 0;
130898 + start_frag->flags = i->flags;
130899 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
130900 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
130901 + if (name_len >= USDPAA_DMA_NAME_MAX) {
130902 + ret = -EFAULT;
130903 + goto out;
130904 + }
130905 + start_frag->map_len = i->len;
130906 + start_frag->has_locking = i->has_locking;
130907 + init_waitqueue_head(&start_frag->wq);
130908 + start_frag->owner = NULL;
130909 + }
130910 +
130911 + /* Setup the map entry */
130912 + map->root_frag = start_frag;
130913 + map->total_size = i->len;
130914 + map->frag_count = frag_count;
130915 + map->refs = 1;
130916 + list_add(&map->list, &ctx->maps);
130917 + i->phys_addr = start_frag->base;
130918 +out:
130919 + spin_unlock(&mem_lock);
130920 +
130921 + if (!ret) {
130922 + unsigned long longret;
130923 + down_write(&current->mm->mmap_sem);
130924 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
130925 + PROT_READ |
130926 + (i->flags &
130927 + USDPAA_DMA_FLAG_RDONLY ? 0
130928 + : PROT_WRITE),
130929 + MAP_SHARED,
130930 + start_frag->pfn_base,
130931 + &populate);
130932 + up_write(&current->mm->mmap_sem);
130933 + if (longret & ~PAGE_MASK) {
130934 + ret = (int)longret;
130935 + } else {
130936 + i->ptr = (void *)longret;
130937 + map->virt_addr = i->ptr;
130938 + }
130939 + } else
130940 + kfree(map);
130941 + return ret;
130942 +}
130943 +
130944 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
130945 +{
130946 + struct mem_mapping *map;
130947 + struct vm_area_struct *vma;
130948 + int ret, i;
130949 + struct mem_fragment *current_frag;
130950 + size_t sz;
130951 + unsigned long base;
130952 + unsigned long vaddr;
130953 +
130954 + down_write(&current->mm->mmap_sem);
130955 + vma = find_vma(current->mm, (unsigned long)arg);
130956 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
130957 + up_write(&current->mm->mmap_sem);
130958 + return -EFAULT;
130959 + }
130960 + spin_lock(&mem_lock);
130961 + list_for_each_entry(map, &ctx->maps, list) {
130962 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
130963 + /* Drop the map lock if we hold it */
130964 + if (map->root_frag->has_locking &&
130965 + (map->root_frag->owner == map)) {
130966 + map->root_frag->owner = NULL;
130967 + wake_up(&map->root_frag->wq);
130968 + }
130969 + goto map_match;
130970 + }
130971 + }
130972 + /* Failed to find a matching mapping for this process */
130973 + ret = -EFAULT;
130974 + spin_unlock(&mem_lock);
130975 + goto out;
130976 +map_match:
130977 + map->refs--;
130978 + if (map->refs != 0) {
130979 + /* Another call the dma_map is referencing this */
130980 + ret = 0;
130981 + spin_unlock(&mem_lock);
130982 + goto out;
130983 + }
130984 +
130985 + current_frag = map->root_frag;
130986 + vaddr = (unsigned long) map->virt_addr;
130987 + for (i = 0; i < map->frag_count; i++) {
130988 + DPA_ASSERT(current_frag->refs > 0);
130989 + --current_frag->refs;
130990 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
130991 + /*
130992 + * Make sure we invalidate the TLB entry for
130993 + * this fragment, otherwise a remap of a different
130994 + * page to this vaddr would give acces to an
130995 + * incorrect piece of memory
130996 + */
130997 + cleartlbcam(vaddr, mfspr(SPRN_PID));
130998 +#endif
130999 + vaddr += current_frag->len;
131000 + current_frag = list_entry(current_frag->list.prev,
131001 + struct mem_fragment, list);
131002 + }
131003 + map->root_frag->name[0] = 0;
131004 + list_del(&map->list);
131005 + compress_frags();
131006 + spin_unlock(&mem_lock);
131007 +
131008 + base = vma->vm_start;
131009 + sz = vma->vm_end - vma->vm_start;
131010 + do_munmap(current->mm, base, sz);
131011 + ret = 0;
131012 + out:
131013 + up_write(&current->mm->mmap_sem);
131014 + return ret;
131015 +}
131016 +
131017 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
131018 +{
131019 + struct mem_fragment *frag;
131020 + struct usdpaa_ioctl_dma_used result;
131021 +
131022 + result.free_bytes = 0;
131023 + result.total_bytes = phys_size;
131024 +
131025 + list_for_each_entry(frag, &mem_list, list) {
131026 + if (frag->refs == 0)
131027 + result.free_bytes += frag->len;
131028 + }
131029 +
131030 + return copy_to_user(arg, &result, sizeof(result)); }
131031 +
131032 +static int test_lock(struct mem_mapping *map)
131033 +{
131034 + int ret = 0;
131035 + spin_lock(&mem_lock);
131036 + if (!map->root_frag->owner) {
131037 + map->root_frag->owner = map;
131038 + ret = 1;
131039 + }
131040 + spin_unlock(&mem_lock);
131041 + return ret;
131042 +}
131043 +
131044 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
131045 +{
131046 + struct mem_mapping *map;
131047 + struct vm_area_struct *vma;
131048 +
131049 + down_read(&current->mm->mmap_sem);
131050 + vma = find_vma(current->mm, (unsigned long)arg);
131051 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
131052 + up_read(&current->mm->mmap_sem);
131053 + return -EFAULT;
131054 + }
131055 + spin_lock(&mem_lock);
131056 + list_for_each_entry(map, &ctx->maps, list) {
131057 + if (map->root_frag->pfn_base == vma->vm_pgoff)
131058 + goto map_match;
131059 + }
131060 + map = NULL;
131061 +map_match:
131062 + spin_unlock(&mem_lock);
131063 + up_read(&current->mm->mmap_sem);
131064 +
131065 + if (!map)
131066 + return -EFAULT;
131067 + if (!map->root_frag->has_locking)
131068 + return -ENODEV;
131069 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
131070 +}
131071 +
131072 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
131073 +{
131074 + struct mem_mapping *map;
131075 + struct vm_area_struct *vma;
131076 + int ret;
131077 +
131078 + down_read(&current->mm->mmap_sem);
131079 + vma = find_vma(current->mm, (unsigned long)arg);
131080 + if (!vma || (vma->vm_start > (unsigned long)arg))
131081 + ret = -EFAULT;
131082 + else {
131083 + spin_lock(&mem_lock);
131084 + list_for_each_entry(map, &ctx->maps, list) {
131085 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
131086 + if (!map->root_frag->has_locking)
131087 + ret = -ENODEV;
131088 + else if (map->root_frag->owner == map) {
131089 + map->root_frag->owner = NULL;
131090 + wake_up(&map->root_frag->wq);
131091 + ret = 0;
131092 + } else
131093 + ret = -EBUSY;
131094 + goto map_match;
131095 + }
131096 + }
131097 + ret = -EINVAL;
131098 +map_match:
131099 + spin_unlock(&mem_lock);
131100 + }
131101 + up_read(&current->mm->mmap_sem);
131102 + return ret;
131103 +}
131104 +
131105 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
131106 +{
131107 + unsigned long longret = 0, populate;
131108 + resource_size_t len;
131109 +
131110 + down_write(&current->mm->mmap_sem);
131111 + len = resource_size(res);
131112 + if (len != (unsigned long)len)
131113 + return -EINVAL;
131114 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
131115 + PROT_READ | PROT_WRITE, MAP_SHARED,
131116 + res->start >> PAGE_SHIFT, &populate);
131117 + up_write(&current->mm->mmap_sem);
131118 +
131119 + if (longret & ~PAGE_MASK)
131120 + return (int)longret;
131121 +
131122 + *ptr = (void *) longret;
131123 + return 0;
131124 +}
131125 +
131126 +static void portal_munmap(struct resource *res, void *ptr)
131127 +{
131128 + down_write(&current->mm->mmap_sem);
131129 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res));
131130 + up_write(&current->mm->mmap_sem);
131131 +}
131132 +
131133 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
131134 + struct usdpaa_ioctl_portal_map *arg)
131135 +{
131136 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131137 + int ret;
131138 +
131139 + if (!mapping)
131140 + return -ENOMEM;
131141 +
131142 + mapping->user = *arg;
131143 + mapping->iommu_domain = NULL;
131144 +
131145 + if (mapping->user.type == usdpaa_portal_qman) {
131146 + mapping->qportal =
131147 + qm_get_unused_portal_idx(mapping->user.index);
131148 + if (!mapping->qportal) {
131149 + ret = -ENODEV;
131150 + goto err_get_portal;
131151 + }
131152 + mapping->phys = &mapping->qportal->addr_phys[0];
131153 + mapping->user.channel = mapping->qportal->public_cfg.channel;
131154 + mapping->user.pools = mapping->qportal->public_cfg.pools;
131155 + mapping->user.index = mapping->qportal->public_cfg.index;
131156 + } else if (mapping->user.type == usdpaa_portal_bman) {
131157 + mapping->bportal =
131158 + bm_get_unused_portal_idx(mapping->user.index);
131159 + if (!mapping->bportal) {
131160 + ret = -ENODEV;
131161 + goto err_get_portal;
131162 + }
131163 + mapping->phys = &mapping->bportal->addr_phys[0];
131164 + mapping->user.index = mapping->bportal->public_cfg.index;
131165 + } else {
131166 + ret = -EINVAL;
131167 + goto err_copy_from_user;
131168 + }
131169 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131170 + * handlers look it up. */
131171 + spin_lock(&mem_lock);
131172 + list_add(&mapping->list, &ctx->portals);
131173 + spin_unlock(&mem_lock);
131174 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
131175 + &mapping->user.addr.cena);
131176 + if (ret)
131177 + goto err_mmap_cena;
131178 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
131179 + &mapping->user.addr.cinh);
131180 + if (ret)
131181 + goto err_mmap_cinh;
131182 + *arg = mapping->user;
131183 + return ret;
131184 +
131185 +err_mmap_cinh:
131186 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131187 +err_mmap_cena:
131188 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
131189 + qm_put_unused_portal(mapping->qportal);
131190 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
131191 + bm_put_unused_portal(mapping->bportal);
131192 + spin_lock(&mem_lock);
131193 + list_del(&mapping->list);
131194 + spin_unlock(&mem_lock);
131195 +err_get_portal:
131196 +err_copy_from_user:
131197 + kfree(mapping);
131198 + return ret;
131199 +}
131200 +
131201 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
131202 +{
131203 + struct portal_mapping *mapping;
131204 + struct vm_area_struct *vma;
131205 + unsigned long pfn;
131206 + u32 channel;
131207 +
131208 + /* Get the PFN corresponding to one of the virt addresses */
131209 + down_read(&current->mm->mmap_sem);
131210 + vma = find_vma(current->mm, (unsigned long)i->cinh);
131211 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
131212 + up_read(&current->mm->mmap_sem);
131213 + return -EFAULT;
131214 + }
131215 + pfn = vma->vm_pgoff;
131216 + up_read(&current->mm->mmap_sem);
131217 +
131218 + /* Find the corresponding portal */
131219 + spin_lock(&mem_lock);
131220 + list_for_each_entry(mapping, &ctx->portals, list) {
131221 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
131222 + goto found;
131223 + }
131224 + mapping = NULL;
131225 +found:
131226 + if (mapping)
131227 + list_del(&mapping->list);
131228 + spin_unlock(&mem_lock);
131229 + if (!mapping)
131230 + return -ENODEV;
131231 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
131232 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
131233 + if (mapping->user.type == usdpaa_portal_qman) {
131234 + init_qm_portal(mapping->qportal,
131235 + &mapping->qman_portal_low);
131236 +
131237 + /* Tear down any FQs this portal is referencing */
131238 + channel = mapping->qportal->public_cfg.channel;
131239 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131240 + &channel,
131241 + check_portal_channel);
131242 + qm_put_unused_portal(mapping->qportal);
131243 + } else if (mapping->user.type == usdpaa_portal_bman) {
131244 + init_bm_portal(mapping->bportal,
131245 + &mapping->bman_portal_low);
131246 + bm_put_unused_portal(mapping->bportal);
131247 + }
131248 + kfree(mapping);
131249 + return 0;
131250 +}
131251 +
131252 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
131253 + uint32_t cpu, uint32_t cache, uint32_t window)
131254 +{
131255 +#ifdef CONFIG_FSL_PAMU
131256 + int ret;
131257 + int window_count = 1;
131258 + struct iommu_domain_geometry geom_attr;
131259 + struct pamu_stash_attribute stash_attr;
131260 +
131261 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
131262 + if (!pcfg->iommu_domain) {
131263 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
131264 + __func__);
131265 + goto _no_iommu;
131266 + }
131267 + geom_attr.aperture_start = 0;
131268 + geom_attr.aperture_end =
131269 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
131270 + geom_attr.force_aperture = true;
131271 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
131272 + &geom_attr);
131273 + if (ret < 0) {
131274 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131275 + __func__, ret);
131276 + goto _iommu_domain_free;
131277 + }
131278 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
131279 + &window_count);
131280 + if (ret < 0) {
131281 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131282 + __func__, ret);
131283 + goto _iommu_domain_free;
131284 + }
131285 + stash_attr.cpu = cpu;
131286 + stash_attr.cache = cache;
131287 + /* set stash information for the window */
131288 + stash_attr.window = 0;
131289 +
131290 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131291 + DOMAIN_ATTR_FSL_PAMU_STASH,
131292 + &stash_attr);
131293 + if (ret < 0) {
131294 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131295 + __func__, ret);
131296 + goto _iommu_domain_free;
131297 + }
131298 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
131299 + IOMMU_READ | IOMMU_WRITE);
131300 + if (ret < 0) {
131301 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
131302 + __func__, ret);
131303 + goto _iommu_domain_free;
131304 + }
131305 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
131306 + if (ret < 0) {
131307 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
131308 + __func__, ret);
131309 + goto _iommu_domain_free;
131310 + }
131311 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
131312 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
131313 + &window_count);
131314 + if (ret < 0) {
131315 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
131316 + __func__, ret);
131317 + goto _iommu_detach_device;
131318 + }
131319 +_no_iommu:
131320 +#endif
131321 +
131322 +#ifdef CONFIG_FSL_QMAN_CONFIG
131323 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
131324 +#endif
131325 + pr_warn("Failed to set QMan portal's stash request queue\n");
131326 +
131327 + return;
131328 +
131329 +#ifdef CONFIG_FSL_PAMU
131330 +_iommu_detach_device:
131331 + iommu_detach_device(pcfg->iommu_domain, NULL);
131332 +_iommu_domain_free:
131333 + iommu_domain_free(pcfg->iommu_domain);
131334 +#endif
131335 +}
131336 +
131337 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
131338 + struct usdpaa_ioctl_raw_portal *arg)
131339 +{
131340 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
131341 + int ret;
131342 +
131343 + if (!mapping)
131344 + return -ENOMEM;
131345 +
131346 + mapping->user.type = arg->type;
131347 + mapping->iommu_domain = NULL;
131348 + if (arg->type == usdpaa_portal_qman) {
131349 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
131350 + if (!mapping->qportal) {
131351 + ret = -ENODEV;
131352 + goto err;
131353 + }
131354 + mapping->phys = &mapping->qportal->addr_phys[0];
131355 + arg->index = mapping->qportal->public_cfg.index;
131356 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
131357 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
131358 + if (arg->enable_stash) {
131359 + /* Setup the PAMU with the supplied parameters */
131360 + portal_config_pamu(mapping->qportal, arg->sdest,
131361 + arg->cpu, arg->cache, arg->window);
131362 + }
131363 + } else if (mapping->user.type == usdpaa_portal_bman) {
131364 + mapping->bportal =
131365 + bm_get_unused_portal_idx(arg->index);
131366 + if (!mapping->bportal) {
131367 + ret = -ENODEV;
131368 + goto err;
131369 + }
131370 + mapping->phys = &mapping->bportal->addr_phys[0];
131371 + arg->index = mapping->bportal->public_cfg.index;
131372 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
131373 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
131374 + } else {
131375 + ret = -EINVAL;
131376 + goto err;
131377 + }
131378 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
131379 + * handlers look it up. */
131380 + spin_lock(&mem_lock);
131381 + list_add(&mapping->list, &ctx->portals);
131382 + spin_unlock(&mem_lock);
131383 + return 0;
131384 +err:
131385 + kfree(mapping);
131386 + return ret;
131387 +}
131388 +
131389 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
131390 + struct usdpaa_ioctl_raw_portal *arg)
131391 +{
131392 + struct portal_mapping *mapping;
131393 + u32 channel;
131394 +
131395 + /* Find the corresponding portal */
131396 + spin_lock(&mem_lock);
131397 + list_for_each_entry(mapping, &ctx->portals, list) {
131398 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
131399 + goto found;
131400 + }
131401 + mapping = NULL;
131402 +found:
131403 + if (mapping)
131404 + list_del(&mapping->list);
131405 + spin_unlock(&mem_lock);
131406 + if (!mapping)
131407 + return -ENODEV;
131408 + if (mapping->user.type == usdpaa_portal_qman) {
131409 + init_qm_portal(mapping->qportal,
131410 + &mapping->qman_portal_low);
131411 +
131412 + /* Tear down any FQs this portal is referencing */
131413 + channel = mapping->qportal->public_cfg.channel;
131414 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
131415 + &channel,
131416 + check_portal_channel);
131417 + qm_put_unused_portal(mapping->qportal);
131418 + } else if (mapping->user.type == usdpaa_portal_bman) {
131419 + init_bm_portal(mapping->bportal,
131420 + &mapping->bman_portal_low);
131421 + bm_put_unused_portal(mapping->bportal);
131422 + }
131423 + kfree(mapping);
131424 + return 0;
131425 +}
131426 +
131427 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
131428 +{
131429 + struct ctx *ctx = fp->private_data;
131430 + void __user *a = (void __user *)arg;
131431 + switch (cmd) {
131432 + case USDPAA_IOCTL_ID_ALLOC:
131433 + return ioctl_id_alloc(ctx, a);
131434 + case USDPAA_IOCTL_ID_RELEASE:
131435 + return ioctl_id_release(ctx, a);
131436 + case USDPAA_IOCTL_ID_RESERVE:
131437 + return ioctl_id_reserve(ctx, a);
131438 + case USDPAA_IOCTL_DMA_MAP:
131439 + {
131440 + struct usdpaa_ioctl_dma_map input;
131441 + int ret;
131442 + if (copy_from_user(&input, a, sizeof(input)))
131443 + return -EFAULT;
131444 + ret = ioctl_dma_map(fp, ctx, &input);
131445 + if (copy_to_user(a, &input, sizeof(input)))
131446 + return -EFAULT;
131447 + return ret;
131448 + }
131449 + case USDPAA_IOCTL_DMA_UNMAP:
131450 + return ioctl_dma_unmap(ctx, a);
131451 + case USDPAA_IOCTL_DMA_LOCK:
131452 + return ioctl_dma_lock(ctx, a);
131453 + case USDPAA_IOCTL_DMA_UNLOCK:
131454 + return ioctl_dma_unlock(ctx, a);
131455 + case USDPAA_IOCTL_PORTAL_MAP:
131456 + {
131457 + struct usdpaa_ioctl_portal_map input;
131458 + int ret;
131459 + if (copy_from_user(&input, a, sizeof(input)))
131460 + return -EFAULT;
131461 + ret = ioctl_portal_map(fp, ctx, &input);
131462 + if (copy_to_user(a, &input, sizeof(input)))
131463 + return -EFAULT;
131464 + return ret;
131465 + }
131466 + case USDPAA_IOCTL_PORTAL_UNMAP:
131467 + {
131468 + struct usdpaa_portal_map input;
131469 + if (copy_from_user(&input, a, sizeof(input)))
131470 + return -EFAULT;
131471 + return ioctl_portal_unmap(ctx, &input);
131472 + }
131473 + case USDPAA_IOCTL_DMA_USED:
131474 + return ioctl_dma_stats(ctx, a);
131475 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
131476 + {
131477 + struct usdpaa_ioctl_raw_portal input;
131478 + int ret;
131479 + if (copy_from_user(&input, a, sizeof(input)))
131480 + return -EFAULT;
131481 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
131482 + if (copy_to_user(a, &input, sizeof(input)))
131483 + return -EFAULT;
131484 + return ret;
131485 + }
131486 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
131487 + {
131488 + struct usdpaa_ioctl_raw_portal input;
131489 + if (copy_from_user(&input, a, sizeof(input)))
131490 + return -EFAULT;
131491 + return ioctl_free_raw_portal(fp, ctx, &input);
131492 + }
131493 + }
131494 + return -EINVAL;
131495 +}
131496 +
131497 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
131498 + unsigned long arg)
131499 +{
131500 +#ifdef CONFIG_COMPAT
131501 + struct ctx *ctx = fp->private_data;
131502 + void __user *a = (void __user *)arg;
131503 +#endif
131504 + switch (cmd) {
131505 +#ifdef CONFIG_COMPAT
131506 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
131507 + {
131508 + int ret;
131509 + struct usdpaa_ioctl_dma_map_compat input;
131510 + struct usdpaa_ioctl_dma_map converted;
131511 +
131512 + if (copy_from_user(&input, a, sizeof(input)))
131513 + return -EFAULT;
131514 +
131515 + converted.ptr = compat_ptr(input.ptr);
131516 + converted.phys_addr = input.phys_addr;
131517 + converted.len = input.len;
131518 + converted.flags = input.flags;
131519 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
131520 + converted.has_locking = input.has_locking;
131521 + converted.did_create = input.did_create;
131522 +
131523 + ret = ioctl_dma_map(fp, ctx, &converted);
131524 + input.ptr = ptr_to_compat(converted.ptr);
131525 + input.phys_addr = converted.phys_addr;
131526 + input.len = converted.len;
131527 + input.flags = converted.flags;
131528 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
131529 + input.has_locking = converted.has_locking;
131530 + input.did_create = converted.did_create;
131531 + if (copy_to_user(a, &input, sizeof(input)))
131532 + return -EFAULT;
131533 + return ret;
131534 + }
131535 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
131536 + {
131537 + int ret;
131538 + struct compat_usdpaa_ioctl_portal_map input;
131539 + struct usdpaa_ioctl_portal_map converted;
131540 + if (copy_from_user(&input, a, sizeof(input)))
131541 + return -EFAULT;
131542 + converted.type = input.type;
131543 + converted.index = input.index;
131544 + ret = ioctl_portal_map(fp, ctx, &converted);
131545 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
131546 + input.addr.cena = ptr_to_compat(converted.addr.cena);
131547 + input.channel = converted.channel;
131548 + input.pools = converted.pools;
131549 + input.index = converted.index;
131550 + if (copy_to_user(a, &input, sizeof(input)))
131551 + return -EFAULT;
131552 + return ret;
131553 + }
131554 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
131555 + {
131556 + struct usdpaa_portal_map_compat input;
131557 + struct usdpaa_portal_map converted;
131558 +
131559 + if (copy_from_user(&input, a, sizeof(input)))
131560 + return -EFAULT;
131561 + converted.cinh = compat_ptr(input.cinh);
131562 + converted.cena = compat_ptr(input.cena);
131563 + return ioctl_portal_unmap(ctx, &converted);
131564 + }
131565 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
131566 + {
131567 + int ret;
131568 + struct usdpaa_ioctl_raw_portal converted;
131569 + struct compat_ioctl_raw_portal input;
131570 + if (copy_from_user(&input, a, sizeof(input)))
131571 + return -EFAULT;
131572 + converted.type = input.type;
131573 + converted.index = input.index;
131574 + converted.enable_stash = input.enable_stash;
131575 + converted.cpu = input.cpu;
131576 + converted.cache = input.cache;
131577 + converted.window = input.window;
131578 + converted.sdest = input.sdest;
131579 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
131580 +
131581 + input.cinh = converted.cinh;
131582 + input.cena = converted.cena;
131583 + input.index = converted.index;
131584 +
131585 + if (copy_to_user(a, &input, sizeof(input)))
131586 + return -EFAULT;
131587 + return ret;
131588 + }
131589 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
131590 + {
131591 + struct usdpaa_ioctl_raw_portal converted;
131592 + struct compat_ioctl_raw_portal input;
131593 + if (copy_from_user(&input, a, sizeof(input)))
131594 + return -EFAULT;
131595 + converted.type = input.type;
131596 + converted.index = input.index;
131597 + converted.cinh = input.cinh;
131598 + converted.cena = input.cena;
131599 + return ioctl_free_raw_portal(fp, ctx, &converted);
131600 + }
131601 +#endif
131602 + default:
131603 + return usdpaa_ioctl(fp, cmd, arg);
131604 + }
131605 + return -EINVAL;
131606 +}
131607 +
131608 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131609 + enum usdpaa_portal_type ptype, unsigned int *irq,
131610 + void **iir_reg)
131611 +{
131612 + /* Walk the list of portals for filp and return the config
131613 + for the portal that matches the hint */
131614 + struct ctx *context;
131615 + struct portal_mapping *portal;
131616 +
131617 + /* First sanitize the filp */
131618 + if (filp->f_op->open != usdpaa_open)
131619 + return -ENODEV;
131620 + context = filp->private_data;
131621 + spin_lock(&context->lock);
131622 + list_for_each_entry(portal, &context->portals, list) {
131623 + if (portal->user.type == ptype &&
131624 + portal->user.addr.cinh == cinh) {
131625 + if (ptype == usdpaa_portal_qman) {
131626 + *irq = portal->qportal->public_cfg.irq;
131627 + *iir_reg = portal->qportal->addr_virt[1] +
131628 + QM_REG_IIR;
131629 + } else {
131630 + *irq = portal->bportal->public_cfg.irq;
131631 + *iir_reg = portal->bportal->addr_virt[1] +
131632 + BM_REG_IIR;
131633 + }
131634 + spin_unlock(&context->lock);
131635 + return 0;
131636 + }
131637 + }
131638 + spin_unlock(&context->lock);
131639 + return -EINVAL;
131640 +}
131641 +
131642 +static const struct file_operations usdpaa_fops = {
131643 + .open = usdpaa_open,
131644 + .release = usdpaa_release,
131645 + .mmap = usdpaa_mmap,
131646 + .get_unmapped_area = usdpaa_get_unmapped_area,
131647 + .unlocked_ioctl = usdpaa_ioctl,
131648 + .compat_ioctl = usdpaa_ioctl_compat
131649 +};
131650 +
131651 +static struct miscdevice usdpaa_miscdev = {
131652 + .name = "fsl-usdpaa",
131653 + .fops = &usdpaa_fops,
131654 + .minor = MISC_DYNAMIC_MINOR,
131655 +};
131656 +
131657 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
131658 + * indicate how much memory (if any) to allocate during early boot. If the
131659 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
131660 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
131661 + * than there are TLB1 entries, fault-handling will occur. */
131662 +
131663 +static __init int usdpaa_mem(char *arg)
131664 +{
131665 + pr_warn("uspdaa_mem argument is depracated\n");
131666 + arg_phys_size = memparse(arg, &arg);
131667 + num_tlb = 1;
131668 + if (*arg == ',') {
131669 + unsigned long ul;
131670 + int err = kstrtoul(arg + 1, 0, &ul);
131671 + if (err < 0) {
131672 + num_tlb = 1;
131673 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
131674 + } else
131675 + num_tlb = (unsigned int)ul;
131676 + }
131677 + return 0;
131678 +}
131679 +early_param("usdpaa_mem", usdpaa_mem);
131680 +
131681 +static int usdpaa_mem_init(struct reserved_mem *rmem)
131682 +{
131683 + phys_start = rmem->base;
131684 + phys_size = rmem->size;
131685 +
131686 + WARN_ON(!(phys_start && phys_size));
131687 +
131688 + return 0;
131689 +}
131690 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
131691 +
131692 +__init int fsl_usdpaa_init_early(void)
131693 +{
131694 + if (!phys_size || !phys_start) {
131695 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
131696 + return 0;
131697 + }
131698 + if (phys_size % PAGE_SIZE) {
131699 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
131700 + phys_size = 0;
131701 + return 0;
131702 + }
131703 + if (arg_phys_size && phys_size != arg_phys_size) {
131704 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
131705 + arg_phys_size, phys_size);
131706 + phys_size = 0;
131707 + return 0;
131708 + }
131709 + pfn_start = phys_start >> PAGE_SHIFT;
131710 + pfn_size = phys_size >> PAGE_SHIFT;
131711 +#ifdef CONFIG_PPC
131712 + first_tlb = current_tlb = tlbcam_index;
131713 + tlbcam_index += num_tlb;
131714 +#endif
131715 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
131716 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
131717 + return 0;
131718 +}
131719 +subsys_initcall(fsl_usdpaa_init_early);
131720 +
131721 +
131722 +static int __init usdpaa_init(void)
131723 +{
131724 + struct mem_fragment *frag;
131725 + int ret;
131726 + u64 tmp_size = phys_size;
131727 + u64 tmp_start = phys_start;
131728 + u64 tmp_pfn_size = pfn_size;
131729 + u64 tmp_pfn_start = pfn_start;
131730 +
131731 + pr_info("Freescale USDPAA process driver\n");
131732 + if (!phys_start) {
131733 + pr_warn("fsl-usdpaa: no region found\n");
131734 + return 0;
131735 + }
131736 +
131737 + while (tmp_size != 0) {
131738 + u32 frag_size = largest_page_size(tmp_size);
131739 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
131740 + if (!frag) {
131741 + pr_err("Failed to setup USDPAA memory accounting\n");
131742 + return -ENOMEM;
131743 + }
131744 + frag->base = tmp_start;
131745 + frag->len = frag->root_len = frag_size;
131746 + frag->root_pfn = tmp_pfn_start;
131747 + frag->pfn_base = tmp_pfn_start;
131748 + frag->pfn_len = frag_size / PAGE_SIZE;
131749 + frag->refs = 0;
131750 + init_waitqueue_head(&frag->wq);
131751 + frag->owner = NULL;
131752 + list_add(&frag->list, &mem_list);
131753 +
131754 + /* Adjust for this frag */
131755 + tmp_start += frag_size;
131756 + tmp_size -= frag_size;
131757 + tmp_pfn_start += frag_size / PAGE_SIZE;
131758 + tmp_pfn_size -= frag_size / PAGE_SIZE;
131759 + }
131760 + ret = misc_register(&usdpaa_miscdev);
131761 + if (ret)
131762 + pr_err("fsl-usdpaa: failed to register misc device\n");
131763 + return ret;
131764 +}
131765 +
131766 +static void __exit usdpaa_exit(void)
131767 +{
131768 + misc_deregister(&usdpaa_miscdev);
131769 +}
131770 +
131771 +module_init(usdpaa_init);
131772 +module_exit(usdpaa_exit);
131773 +
131774 +MODULE_LICENSE("GPL");
131775 +MODULE_AUTHOR("Freescale Semiconductor");
131776 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
131777 --- /dev/null
131778 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
131779 @@ -0,0 +1,289 @@
131780 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
131781 + * All rights reserved.
131782 + *
131783 + * Redistribution and use in source and binary forms, with or without
131784 + * modification, are permitted provided that the following conditions are met:
131785 + * * Redistributions of source code must retain the above copyright
131786 + * notice, this list of conditions and the following disclaimer.
131787 + * * Redistributions in binary form must reproduce the above copyright
131788 + * notice, this list of conditions and the following disclaimer in the
131789 + * documentation and/or other materials provided with the distribution.
131790 + * * Neither the name of Freescale Semiconductor nor the
131791 + * names of its contributors may be used to endorse or promote products
131792 + * derived from this software without specific prior written permission.
131793 + *
131794 + *
131795 + * ALTERNATIVELY, this software may be distributed under the terms of the
131796 + * GNU General Public License ("GPL") as published by the Free Software
131797 + * Foundation, either version 2 of that License or (at your option) any
131798 + * later version.
131799 + *
131800 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131801 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131802 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131803 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131804 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131805 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131806 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131807 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131808 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131809 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131810 + */
131811 +
131812 +/* define a device that allows USPDAA processes to open a file
131813 + descriptor and specify which IRQ it wants to montior using an ioctl()
131814 + When an IRQ is received, the device becomes readable so that a process
131815 + can use read() or select() type calls to monitor for IRQs */
131816 +
131817 +#include <linux/miscdevice.h>
131818 +#include <linux/fs.h>
131819 +#include <linux/cdev.h>
131820 +#include <linux/slab.h>
131821 +#include <linux/interrupt.h>
131822 +#include <linux/poll.h>
131823 +#include <linux/uaccess.h>
131824 +#include <linux/fsl_usdpaa.h>
131825 +#include <linux/module.h>
131826 +#include <linux/fdtable.h>
131827 +#include <linux/file.h>
131828 +
131829 +#include "qman_low.h"
131830 +#include "bman_low.h"
131831 +
131832 +struct usdpaa_irq_ctx {
131833 + int irq_set; /* Set to true once the irq is set via ioctl */
131834 + unsigned int irq_num;
131835 + u32 last_irq_count; /* Last value returned from read */
131836 + u32 irq_count; /* Number of irqs since last read */
131837 + wait_queue_head_t wait_queue; /* Waiting processes */
131838 + spinlock_t lock;
131839 + void *inhibit_addr; /* inhibit register address */
131840 + struct file *usdpaa_filp;
131841 + char irq_name[128];
131842 +};
131843 +
131844 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
131845 +{
131846 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
131847 + if (!ctx)
131848 + return -ENOMEM;
131849 + ctx->irq_set = 0;
131850 + ctx->irq_count = 0;
131851 + ctx->last_irq_count = 0;
131852 + init_waitqueue_head(&ctx->wait_queue);
131853 + spin_lock_init(&ctx->lock);
131854 + filp->private_data = ctx;
131855 + return 0;
131856 +}
131857 +
131858 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
131859 +{
131860 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131861 + if (ctx->irq_set) {
131862 + /* Inhibit the IRQ */
131863 + out_be32(ctx->inhibit_addr, 0x1);
131864 + irq_set_affinity_hint(ctx->irq_num, NULL);
131865 + free_irq(ctx->irq_num, ctx);
131866 + ctx->irq_set = 0;
131867 + fput(ctx->usdpaa_filp);
131868 + }
131869 + kfree(filp->private_data);
131870 + return 0;
131871 +}
131872 +
131873 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
131874 +{
131875 + unsigned long flags;
131876 + struct usdpaa_irq_ctx *ctx = _ctx;
131877 + spin_lock_irqsave(&ctx->lock, flags);
131878 + ++ctx->irq_count;
131879 + spin_unlock_irqrestore(&ctx->lock, flags);
131880 + wake_up_all(&ctx->wait_queue);
131881 + /* Set the inhibit register. This will be reenabled
131882 + once the USDPAA code handles the IRQ */
131883 + out_be32(ctx->inhibit_addr, 0x1);
131884 + pr_info("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
131885 + return IRQ_HANDLED;
131886 +}
131887 +
131888 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
131889 +{
131890 + struct usdpaa_irq_ctx *ctx = fp->private_data;
131891 + int ret;
131892 +
131893 + if (ctx->irq_set) {
131894 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
131895 + return -EBUSY;
131896 + }
131897 +
131898 + ctx->usdpaa_filp = fget(irq_map->fd);
131899 + if (!ctx->usdpaa_filp) {
131900 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
131901 + return -EINVAL;
131902 + }
131903 +
131904 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
131905 + irq_map->type, &ctx->irq_num,
131906 + &ctx->inhibit_addr);
131907 + if (ret) {
131908 + pr_debug("USDPAA IRQ couldn't identify portal\n");
131909 + fput(ctx->usdpaa_filp);
131910 + return ret;
131911 + }
131912 +
131913 + ctx->irq_set = 1;
131914 +
131915 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
131916 + "usdpaa_irq %d", ctx->irq_num);
131917 +
131918 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
131919 + ctx->irq_name, ctx);
131920 + if (ret) {
131921 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
131922 + ctx->irq_num, ret);
131923 + ctx->irq_set = 0;
131924 + fput(ctx->usdpaa_filp);
131925 + return ret;
131926 + }
131927 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
131928 + if (ret)
131929 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
131930 +
131931 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
131932 + if (ret)
131933 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
131934 +
131935 + return 0;
131936 +}
131937 +
131938 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
131939 + unsigned long arg)
131940 +{
131941 + int ret;
131942 + struct usdpaa_ioctl_irq_map irq_map;
131943 +
131944 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
131945 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
131946 + return -EINVAL;
131947 + }
131948 +
131949 + ret = copy_from_user(&irq_map, (void __user *)arg,
131950 + sizeof(irq_map));
131951 + if (ret)
131952 + return ret;
131953 + return map_irq(fp, &irq_map);
131954 +}
131955 +
131956 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
131957 + size_t count, loff_t *offp)
131958 +{
131959 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131960 + int ret;
131961 +
131962 + if (!ctx->irq_set) {
131963 + pr_debug("Reading USDPAA IRQ before it was set\n");
131964 + return -EINVAL;
131965 + }
131966 +
131967 + if (count < sizeof(ctx->irq_count)) {
131968 + pr_debug("USDPAA IRQ Read too small\n");
131969 + return -EINVAL;
131970 + }
131971 + if (ctx->irq_count == ctx->last_irq_count) {
131972 + if (filp->f_flags & O_NONBLOCK)
131973 + return -EAGAIN;
131974 +
131975 + ret = wait_event_interruptible(ctx->wait_queue,
131976 + ctx->irq_count != ctx->last_irq_count);
131977 + if (ret == -ERESTARTSYS)
131978 + return ret;
131979 + }
131980 +
131981 + ctx->last_irq_count = ctx->irq_count;
131982 +
131983 + if (copy_to_user(buff, &ctx->last_irq_count,
131984 + sizeof(ctx->last_irq_count)))
131985 + return -EFAULT;
131986 + return sizeof(ctx->irq_count);
131987 +}
131988 +
131989 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
131990 +{
131991 + struct usdpaa_irq_ctx *ctx = filp->private_data;
131992 + unsigned int ret = 0;
131993 + unsigned long flags;
131994 +
131995 + if (!ctx->irq_set)
131996 + return POLLHUP;
131997 +
131998 + poll_wait(filp, &ctx->wait_queue, wait);
131999 +
132000 + spin_lock_irqsave(&ctx->lock, flags);
132001 + if (ctx->irq_count != ctx->last_irq_count)
132002 + ret |= POLLIN | POLLRDNORM;
132003 + spin_unlock_irqrestore(&ctx->lock, flags);
132004 + return ret;
132005 +}
132006 +
132007 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
132008 + unsigned long arg)
132009 +{
132010 +#ifdef CONFIG_COMPAT
132011 + void __user *a = (void __user *)arg;
132012 +#endif
132013 + switch (cmd) {
132014 +#ifdef CONFIG_COMPAT
132015 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
132016 + {
132017 + struct compat_ioctl_irq_map input;
132018 + struct usdpaa_ioctl_irq_map converted;
132019 + if (copy_from_user(&input, a, sizeof(input)))
132020 + return -EFAULT;
132021 + converted.type = input.type;
132022 + converted.fd = input.fd;
132023 + converted.portal_cinh = compat_ptr(input.portal_cinh);
132024 + return map_irq(fp, &converted);
132025 + }
132026 +#endif
132027 + default:
132028 + return usdpaa_irq_ioctl(fp, cmd, arg);
132029 + }
132030 +}
132031 +
132032 +static const struct file_operations usdpaa_irq_fops = {
132033 + .open = usdpaa_irq_open,
132034 + .release = usdpaa_irq_release,
132035 + .unlocked_ioctl = usdpaa_irq_ioctl,
132036 + .compat_ioctl = usdpaa_irq_ioctl_compat,
132037 + .read = usdpaa_irq_read,
132038 + .poll = usdpaa_irq_poll
132039 +};
132040 +
132041 +static struct miscdevice usdpaa_miscdev = {
132042 + .name = "fsl-usdpaa-irq",
132043 + .fops = &usdpaa_irq_fops,
132044 + .minor = MISC_DYNAMIC_MINOR,
132045 +};
132046 +
132047 +static int __init usdpaa_irq_init(void)
132048 +{
132049 + int ret;
132050 +
132051 + pr_info("Freescale USDPAA process IRQ driver\n");
132052 + ret = misc_register(&usdpaa_miscdev);
132053 + if (ret)
132054 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
132055 + return ret;
132056 +}
132057 +
132058 +static void __exit usdpaa_irq_exit(void)
132059 +{
132060 + misc_deregister(&usdpaa_miscdev);
132061 +}
132062 +
132063 +module_init(usdpaa_irq_init);
132064 +module_exit(usdpaa_irq_exit);
132065 +
132066 +MODULE_LICENSE("GPL");
132067 +MODULE_AUTHOR("Freescale Semiconductor");
132068 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
132069 --- /dev/null
132070 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
132071 @@ -0,0 +1,88 @@
132072 +/* Copyright 2013 Freescale Semiconductor, Inc.
132073 + *
132074 + * Redistribution and use in source and binary forms, with or without
132075 + * modification, are permitted provided that the following conditions are met:
132076 + * * Redistributions of source code must retain the above copyright
132077 + * notice, this list of conditions and the following disclaimer.
132078 + * * Redistributions in binary form must reproduce the above copyright
132079 + * notice, this list of conditions and the following disclaimer in the
132080 + * documentation and/or other materials provided with the distribution.
132081 + * * Neither the name of Freescale Semiconductor nor the
132082 + * names of its contributors may be used to endorse or promote products
132083 + * derived from this software without specific prior written permission.
132084 + *
132085 + *
132086 + * ALTERNATIVELY, this software may be distributed under the terms of the
132087 + * GNU General Public License ("GPL") as published by the Free Software
132088 + * Foundation, either version 2 of that License or (at your option) any
132089 + * later version.
132090 + *
132091 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132092 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132093 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132094 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132095 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132096 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132097 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132098 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132099 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132100 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132101 + */
132102 +
132103 +#include <linux/time.h>
132104 +#include "qman_private.h"
132105 +#include "bman_private.h"
132106 +__init void qman_init_early(void);
132107 +__init void bman_init_early(void);
132108 +
132109 +static __init int qbman_init(void)
132110 +{
132111 + struct device_node *dn;
132112 + u32 is_portal_available;
132113 +
132114 + bman_init();
132115 + qman_init();
132116 +
132117 + is_portal_available = 0;
132118 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
132119 + if (!of_device_is_available(dn))
132120 + continue;
132121 + else
132122 + is_portal_available = 1;
132123 + }
132124 +
132125 + if (!qman_have_ccsr() && is_portal_available) {
132126 + struct qman_fq fq = {
132127 + .fqid = 1
132128 + };
132129 + struct qm_mcr_queryfq_np np;
132130 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
132131 + struct timespec nowts, diffts, startts = current_kernel_time();
132132 + /* Loop while querying given fqid succeeds or time out */
132133 + while (1) {
132134 + err = qman_query_fq_np(&fq, &np);
132135 + if (!err) {
132136 + /* success, control-plane has configured QMan */
132137 + break;
132138 + } else if (err != -ERANGE) {
132139 + pr_err("QMan: I/O error, continuing anyway\n");
132140 + break;
132141 + }
132142 + nowts = current_kernel_time();
132143 + diffts = timespec_sub(nowts, startts);
132144 + if (diffts.tv_sec > 0) {
132145 + if (!retry--) {
132146 + pr_err("QMan: time out, control-plane"
132147 + " dead?\n");
132148 + break;
132149 + }
132150 + pr_warn("QMan: polling for the control-plane"
132151 + " (%d)\n", retry);
132152 + }
132153 + }
132154 + }
132155 + bman_resource_init();
132156 + qman_resource_init();
132157 + return 0;
132158 +}
132159 +subsys_initcall(qbman_init);
132160 --- /dev/null
132161 +++ b/drivers/staging/fsl_qbman/qman_config.c
132162 @@ -0,0 +1,1224 @@
132163 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
132164 + *
132165 + * Redistribution and use in source and binary forms, with or without
132166 + * modification, are permitted provided that the following conditions are met:
132167 + * * Redistributions of source code must retain the above copyright
132168 + * notice, this list of conditions and the following disclaimer.
132169 + * * Redistributions in binary form must reproduce the above copyright
132170 + * notice, this list of conditions and the following disclaimer in the
132171 + * documentation and/or other materials provided with the distribution.
132172 + * * Neither the name of Freescale Semiconductor nor the
132173 + * names of its contributors may be used to endorse or promote products
132174 + * derived from this software without specific prior written permission.
132175 + *
132176 + *
132177 + * ALTERNATIVELY, this software may be distributed under the terms of the
132178 + * GNU General Public License ("GPL") as published by the Free Software
132179 + * Foundation, either version 2 of that License or (at your option) any
132180 + * later version.
132181 + *
132182 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
132183 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
132184 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
132185 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
132186 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
132187 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
132188 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
132189 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
132190 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
132191 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
132192 + */
132193 +
132194 +#include <asm/cacheflush.h>
132195 +#include "qman_private.h"
132196 +#include <linux/highmem.h>
132197 +#include <linux/of_reserved_mem.h>
132198 +
132199 +/* Last updated for v00.800 of the BG */
132200 +
132201 +/* Register offsets */
132202 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
132203 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
132204 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
132205 +#define REG_DD_CFG 0x0200
132206 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
132207 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
132208 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
132209 +#define REG_PFDR_FPC 0x0400
132210 +#define REG_PFDR_FP_HEAD 0x0404
132211 +#define REG_PFDR_FP_TAIL 0x0408
132212 +#define REG_PFDR_FP_LWIT 0x0410
132213 +#define REG_PFDR_CFG 0x0414
132214 +#define REG_SFDR_CFG 0x0500
132215 +#define REG_SFDR_IN_USE 0x0504
132216 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
132217 +#define REG_WQ_DEF_ENC_WQID 0x0630
132218 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
132219 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
132220 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
132221 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
132222 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
132223 +#define REG_CM_CFG 0x0800
132224 +#define REG_ECSR 0x0a00
132225 +#define REG_ECIR 0x0a04
132226 +#define REG_EADR 0x0a08
132227 +#define REG_ECIR2 0x0a0c
132228 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
132229 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
132230 +#define REG_MCR 0x0b00
132231 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
132232 +#define REG_MISC_CFG 0x0be0
132233 +#define REG_HID_CFG 0x0bf0
132234 +#define REG_IDLE_STAT 0x0bf4
132235 +#define REG_IP_REV_1 0x0bf8
132236 +#define REG_IP_REV_2 0x0bfc
132237 +#define REG_FQD_BARE 0x0c00
132238 +#define REG_PFDR_BARE 0x0c20
132239 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
132240 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
132241 +#define REG_QCSP_BARE 0x0c80
132242 +#define REG_QCSP_BAR 0x0c84
132243 +#define REG_CI_SCHED_CFG 0x0d00
132244 +#define REG_SRCIDR 0x0d04
132245 +#define REG_LIODNR 0x0d08
132246 +#define REG_CI_RLM_AVG 0x0d14
132247 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
132248 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
132249 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
132250 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
132251 +#define REG_CEETM_CFG_IDX 0x900
132252 +#define REG_CEETM_CFG_PRES 0x904
132253 +#define REG_CEETM_XSFDR_IN_USE 0x908
132254 +
132255 +/* Assists for QMAN_MCR */
132256 +#define MCR_INIT_PFDR 0x01000000
132257 +#define MCR_get_rslt(v) (u8)((v) >> 24)
132258 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
132259 +#define MCR_rslt_ok(r) (rslt == 0xf0)
132260 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
132261 +#define MCR_rslt_inval(r) (rslt == 0xff)
132262 +
132263 +struct qman;
132264 +
132265 +/* Follows WQ_CS_CFG0-5 */
132266 +enum qm_wq_class {
132267 + qm_wq_portal = 0,
132268 + qm_wq_pool = 1,
132269 + qm_wq_fman0 = 2,
132270 + qm_wq_fman1 = 3,
132271 + qm_wq_caam = 4,
132272 + qm_wq_pme = 5,
132273 + qm_wq_first = qm_wq_portal,
132274 + qm_wq_last = qm_wq_pme
132275 +};
132276 +
132277 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
132278 +enum qm_memory {
132279 + qm_memory_fqd,
132280 + qm_memory_pfdr
132281 +};
132282 +
132283 +/* Used by all error interrupt registers except 'inhibit' */
132284 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
132285 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
132286 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
132287 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
132288 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
132289 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
132290 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
132291 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
132292 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
132293 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
132294 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
132295 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
132296 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
132297 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
132298 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
132299 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
132300 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
132301 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
132302 +
132303 +/* QMAN_ECIR valid error bit */
132304 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
132305 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
132306 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
132307 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
132308 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
132309 + QM_EIRQ_IFSI)
132310 +
132311 +union qman_ecir {
132312 + u32 ecir_raw;
132313 + struct {
132314 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132315 + u32 __reserved:2;
132316 + u32 portal_type:1;
132317 + u32 portal_num:5;
132318 + u32 fqid:24;
132319 +#else
132320 + u32 fqid:24;
132321 + u32 portal_num:5;
132322 + u32 portal_type:1;
132323 + u32 __reserved:2;
132324 +#endif
132325 + } __packed info;
132326 +};
132327 +
132328 +union qman_ecir2 {
132329 + u32 ecir2_raw;
132330 + struct {
132331 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132332 + u32 portal_type:1;
132333 + u32 __reserved:21;
132334 + u32 portal_num:10;
132335 +#else
132336 + u32 portal_num:10;
132337 + u32 __reserved:21;
132338 + u32 portal_type:1;
132339 +#endif
132340 + } __packed info;
132341 +};
132342 +
132343 +union qman_eadr {
132344 + u32 eadr_raw;
132345 + struct {
132346 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132347 + u32 __reserved1:4;
132348 + u32 memid:4;
132349 + u32 __reserved2:12;
132350 + u32 eadr:12;
132351 +#else
132352 + u32 eadr:12;
132353 + u32 __reserved2:12;
132354 + u32 memid:4;
132355 + u32 __reserved1:4;
132356 +#endif
132357 + } __packed info;
132358 + struct {
132359 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
132360 + u32 __reserved1:3;
132361 + u32 memid:5;
132362 + u32 __reserved:8;
132363 + u32 eadr:16;
132364 +#else
132365 + u32 eadr:16;
132366 + u32 __reserved:8;
132367 + u32 memid:5;
132368 + u32 __reserved1:3;
132369 +#endif
132370 + } __packed info_rev3;
132371 +};
132372 +
132373 +struct qman_hwerr_txt {
132374 + u32 mask;
132375 + const char *txt;
132376 +};
132377 +
132378 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
132379 +
132380 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
132381 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
132382 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
132383 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
132384 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
132385 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
132386 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
132387 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
132388 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
132389 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
132390 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
132391 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
132392 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
132393 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
132394 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
132395 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
132396 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
132397 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
132398 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
132399 +};
132400 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
132401 +
132402 +struct qman_error_info_mdata {
132403 + u16 addr_mask;
132404 + u16 bits;
132405 + const char *txt;
132406 +};
132407 +
132408 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
132409 +static const struct qman_error_info_mdata error_mdata[] = {
132410 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
132411 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
132412 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
132413 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
132414 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
132415 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
132416 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
132417 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
132418 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
132419 + QMAN_ERR_MDATA(0x01FF, 256, "SW portal ring memory"),
132420 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
132421 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
132422 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
132423 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
132424 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
132425 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
132426 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
132427 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
132428 +};
132429 +#define QMAN_ERR_MDATA_COUNT \
132430 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
132431 +
132432 +/* Add this in Kconfig */
132433 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
132434 +
132435 +/**
132436 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
132437 + * @v: for accessors that write values, this is the 32-bit value
132438 + *
132439 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
132440 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
132441 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
132442 + * "write the enable register" rather than "enable the write register"!
132443 + */
132444 +#define qm_err_isr_status_read(qm) \
132445 + __qm_err_isr_read(qm, qm_isr_status)
132446 +#define qm_err_isr_status_clear(qm, m) \
132447 + __qm_err_isr_write(qm, qm_isr_status, m)
132448 +#define qm_err_isr_enable_read(qm) \
132449 + __qm_err_isr_read(qm, qm_isr_enable)
132450 +#define qm_err_isr_enable_write(qm, v) \
132451 + __qm_err_isr_write(qm, qm_isr_enable, v)
132452 +#define qm_err_isr_disable_read(qm) \
132453 + __qm_err_isr_read(qm, qm_isr_disable)
132454 +#define qm_err_isr_disable_write(qm, v) \
132455 + __qm_err_isr_write(qm, qm_isr_disable, v)
132456 +#define qm_err_isr_inhibit(qm) \
132457 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
132458 +#define qm_err_isr_uninhibit(qm) \
132459 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
132460 +
132461 +/*
132462 + * TODO: unimplemented registers
132463 + *
132464 + * Keeping a list here of Qman registers I have not yet covered;
132465 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
132466 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
132467 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
132468 + */
132469 +
132470 +/* Encapsulate "struct qman *" as a cast of the register space address. */
132471 +
132472 +static struct qman *qm_create(void *regs)
132473 +{
132474 + return (struct qman *)regs;
132475 +}
132476 +
132477 +static inline u32 __qm_in(struct qman *qm, u32 offset)
132478 +{
132479 + return in_be32((void *)qm + offset);
132480 +}
132481 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
132482 +{
132483 + out_be32((void *)qm + offset, val);
132484 +}
132485 +#define qm_in(reg) __qm_in(qm, REG_##reg)
132486 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
132487 +
132488 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
132489 +{
132490 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
132491 +}
132492 +
132493 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
132494 +{
132495 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
132496 +}
132497 +
132498 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
132499 + int ed, u8 sernd)
132500 +{
132501 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
132502 + (portal == qm_dc_portal_fman1));
132503 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132504 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
132505 + else
132506 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
132507 +}
132508 +
132509 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
132510 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
132511 + u8 csw6, u8 csw7)
132512 +{
132513 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
132514 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
132515 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
132516 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
132517 +}
132518 +
132519 +static void qm_set_hid(struct qman *qm)
132520 +{
132521 + qm_out(HID_CFG, 0);
132522 +}
132523 +
132524 +static void qm_set_corenet_initiator(struct qman *qm)
132525 +{
132526 + qm_out(CI_SCHED_CFG,
132527 + 0x80000000 | /* write srcciv enable */
132528 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
132529 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
132530 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
132531 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
132532 +}
132533 +
132534 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
132535 + u8 *cfg)
132536 +{
132537 + u32 v = qm_in(IP_REV_1);
132538 + u32 v2 = qm_in(IP_REV_2);
132539 + *id = (v >> 16);
132540 + *major = (v >> 8) & 0xff;
132541 + *minor = v & 0xff;
132542 + *cfg = v2 & 0xff;
132543 +}
132544 +
132545 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
132546 + int enable, int prio, int stash, u32 size)
132547 +{
132548 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
132549 + u32 exp = ilog2(size);
132550 + /* choke if size isn't within range */
132551 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
132552 + is_power_of_2(size));
132553 + /* choke if 'ba' has lower-alignment than 'size' */
132554 + DPA_ASSERT(!(ba & (size - 1)));
132555 + __qm_out(qm, offset, upper_32_bits(ba));
132556 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
132557 + __qm_out(qm, offset + REG_offset_AR,
132558 + (enable ? 0x80000000 : 0) |
132559 + (prio ? 0x40000000 : 0) |
132560 + (stash ? 0x20000000 : 0) |
132561 + (exp - 1));
132562 +}
132563 +
132564 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
132565 +{
132566 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
132567 + qm_out(PFDR_CFG, k);
132568 +}
132569 +
132570 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
132571 +{
132572 + qm_out(SFDR_CFG, th & 0x3ff);
132573 +}
132574 +
132575 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
132576 +{
132577 + u8 rslt = MCR_get_rslt(qm_in(MCR));
132578 +
132579 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
132580 + /* Make sure the command interface is 'idle' */
132581 + if (!MCR_rslt_idle(rslt))
132582 + panic("QMAN_MCR isn't idle");
132583 +
132584 + /* Write the MCR command params then the verb */
132585 + qm_out(MCP(0), pfdr_start);
132586 + /* TODO: remove this - it's a workaround for a model bug that is
132587 + * corrected in more recent versions. We use the workaround until
132588 + * everyone has upgraded. */
132589 + qm_out(MCP(1), (pfdr_start + num - 16));
132590 + lwsync();
132591 + qm_out(MCR, MCR_INIT_PFDR);
132592 + /* Poll for the result */
132593 + do {
132594 + rslt = MCR_get_rslt(qm_in(MCR));
132595 + } while (!MCR_rslt_idle(rslt));
132596 + if (MCR_rslt_ok(rslt))
132597 + return 0;
132598 + if (MCR_rslt_eaccess(rslt))
132599 + return -EACCES;
132600 + if (MCR_rslt_inval(rslt))
132601 + return -EINVAL;
132602 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
132603 + return -ENOSYS;
132604 +}
132605 +
132606 +/*****************/
132607 +/* Config driver */
132608 +/*****************/
132609 +
132610 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
132611 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
132612 +
132613 +/* We support only one of these */
132614 +static struct qman *qm;
132615 +static struct device_node *qm_node;
132616 +
132617 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
132618 + * during qman_init_ccsr(). */
132619 +static dma_addr_t fqd_a, pfdr_a;
132620 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
132621 +
132622 +static int qman_fqd(struct reserved_mem *rmem)
132623 +{
132624 + fqd_a = rmem->base;
132625 + fqd_sz = rmem->size;
132626 +
132627 + WARN_ON(!(fqd_a && fqd_sz));
132628 +
132629 + return 0;
132630 +}
132631 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
132632 +
132633 +static int qman_pfdr(struct reserved_mem *rmem)
132634 +{
132635 + pfdr_a = rmem->base;
132636 + pfdr_sz = rmem->size;
132637 +
132638 + WARN_ON(!(pfdr_a && pfdr_sz));
132639 +
132640 + return 0;
132641 +}
132642 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
132643 +
132644 +size_t get_qman_fqd_size()
132645 +{
132646 + return fqd_sz;
132647 +}
132648 +
132649 +/* Parse the <name> property to extract the memory location and size and
132650 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
132651 + * size. Also flush this memory range from data cache so that QMAN originated
132652 + * transactions for this memory region could be marked non-coherent.
132653 + */
132654 +static __init int parse_mem_property(struct device_node *node, const char *name,
132655 + dma_addr_t *addr, size_t *sz, int zero)
132656 +{
132657 + int ret;
132658 +
132659 + /* If using a "zero-pma", don't try to zero it, even if you asked */
132660 + if (zero && of_find_property(node, "zero-pma", &ret)) {
132661 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
132662 + zero = 0;
132663 + }
132664 +
132665 + if (zero) {
132666 + /* map as cacheable, non-guarded */
132667 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132668 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
132669 +#else
132670 + void __iomem *tmpp = ioremap(*addr, *sz);
132671 +#endif
132672 +
132673 + if (!tmpp)
132674 + return -ENOMEM;
132675 + memset_io(tmpp, 0, *sz);
132676 + flush_dcache_range((unsigned long)tmpp,
132677 + (unsigned long)tmpp + *sz);
132678 + iounmap(tmpp);
132679 + }
132680 +
132681 + return 0;
132682 +}
132683 +
132684 +/* TODO:
132685 + * - there is obviously no handling of errors,
132686 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
132687 + * both memory resources to zero.
132688 + */
132689 +static int __init fsl_qman_init(struct device_node *node)
132690 +{
132691 + struct resource res;
132692 + resource_size_t len;
132693 + u32 __iomem *regs;
132694 + const char *s;
132695 + int ret, standby = 0;
132696 + u16 id;
132697 + u8 major, minor, cfg;
132698 + ret = of_address_to_resource(node, 0, &res);
132699 + if (ret) {
132700 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
132701 + return ret;
132702 + }
132703 + s = of_get_property(node, "fsl,hv-claimable", &ret);
132704 + if (s && !strcmp(s, "standby"))
132705 + standby = 1;
132706 + if (!standby) {
132707 + ret = parse_mem_property(node, "fsl,qman-fqd",
132708 + &fqd_a, &fqd_sz, 1);
132709 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
132710 + BUG_ON(ret);
132711 + ret = parse_mem_property(node, "fsl,qman-pfdr",
132712 + &pfdr_a, &pfdr_sz, 0);
132713 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
132714 + BUG_ON(ret);
132715 + }
132716 + /* Global configuration */
132717 + len = resource_size(&res);
132718 + if (len != (unsigned long)len)
132719 + return -EINVAL;
132720 + regs = ioremap(res.start, (unsigned long)len);
132721 + qm = qm_create(regs);
132722 + qm_node = node;
132723 + qm_get_version(qm, &id, &major, &minor, &cfg);
132724 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
132725 + if (!qman_ip_rev) {
132726 + if ((major == 1) && (minor == 0)) {
132727 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
132728 + iounmap(regs);
132729 + return -ENODEV;
132730 + } else if ((major == 1) && (minor == 1))
132731 + qman_ip_rev = QMAN_REV11;
132732 + else if ((major == 1) && (minor == 2))
132733 + qman_ip_rev = QMAN_REV12;
132734 + else if ((major == 2) && (minor == 0))
132735 + qman_ip_rev = QMAN_REV20;
132736 + else if ((major == 3) && (minor == 0))
132737 + qman_ip_rev = QMAN_REV30;
132738 + else if ((major == 3) && (minor == 1))
132739 + qman_ip_rev = QMAN_REV31;
132740 + else if ((major == 3) && (minor == 2))
132741 + qman_ip_rev = QMAN_REV32;
132742 + else {
132743 + pr_warn("unknown Qman version, default to rev1.1\n");
132744 + qman_ip_rev = QMAN_REV11;
132745 + }
132746 + qman_ip_cfg = cfg;
132747 + }
132748 +
132749 + if (standby) {
132750 + pr_info(" -> in standby mode\n");
132751 + return 0;
132752 + }
132753 + return 0;
132754 +}
132755 +
132756 +int qman_have_ccsr(void)
132757 +{
132758 + return qm ? 1 : 0;
132759 +}
132760 +
132761 +__init int qman_init_early(void)
132762 +{
132763 + struct device_node *dn;
132764 + int ret;
132765 +
132766 + for_each_compatible_node(dn, NULL, "fsl,qman") {
132767 + if (qm)
132768 + pr_err("%s: only one 'fsl,qman' allowed\n",
132769 + dn->full_name);
132770 + else {
132771 + if (!of_device_is_available(dn))
132772 + continue;
132773 +
132774 + ret = fsl_qman_init(dn);
132775 + BUG_ON(ret);
132776 + }
132777 + }
132778 + return 0;
132779 +}
132780 +postcore_initcall_sync(qman_init_early);
132781 +
132782 +static void log_edata_bits(u32 bit_count)
132783 +{
132784 + u32 i, j, mask = 0xffffffff;
132785 +
132786 + pr_warn("Qman ErrInt, EDATA:\n");
132787 + i = bit_count/32;
132788 + if (bit_count%32) {
132789 + i++;
132790 + mask = ~(mask << bit_count%32);
132791 + }
132792 + j = 16-i;
132793 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
132794 + j++;
132795 + for (; j < 16; j++)
132796 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
132797 +}
132798 +
132799 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
132800 +{
132801 + union qman_ecir ecir_val;
132802 + union qman_eadr eadr_val;
132803 +
132804 + ecir_val.ecir_raw = qm_in(ECIR);
132805 + /* Is portal info valid */
132806 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132807 + union qman_ecir2 ecir2_val;
132808 + ecir2_val.ecir2_raw = qm_in(ECIR2);
132809 + if (ecsr_val & PORTAL_ECSR_ERR) {
132810 + pr_warn("Qman ErrInt: %s id %d\n",
132811 + (ecir2_val.info.portal_type) ?
132812 + "DCP" : "SWP", ecir2_val.info.portal_num);
132813 + }
132814 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
132815 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132816 + ecir_val.info.fqid);
132817 + }
132818 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132819 + eadr_val.eadr_raw = qm_in(EADR);
132820 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132821 + error_mdata[eadr_val.info_rev3.memid].txt,
132822 + error_mdata[eadr_val.info_rev3.memid].addr_mask
132823 + & eadr_val.info_rev3.eadr);
132824 + log_edata_bits(
132825 + error_mdata[eadr_val.info_rev3.memid].bits);
132826 + }
132827 + } else {
132828 + if (ecsr_val & PORTAL_ECSR_ERR) {
132829 + pr_warn("Qman ErrInt: %s id %d\n",
132830 + (ecir_val.info.portal_type) ?
132831 + "DCP" : "SWP", ecir_val.info.portal_num);
132832 + }
132833 + if (ecsr_val & FQID_ECSR_ERR) {
132834 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
132835 + ecir_val.info.fqid);
132836 + }
132837 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
132838 + eadr_val.eadr_raw = qm_in(EADR);
132839 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
132840 + error_mdata[eadr_val.info.memid].txt,
132841 + error_mdata[eadr_val.info.memid].addr_mask
132842 + & eadr_val.info.eadr);
132843 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
132844 + }
132845 + }
132846 +}
132847 +
132848 +/* Qman interrupt handler */
132849 +static irqreturn_t qman_isr(int irq, void *ptr)
132850 +{
132851 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
132852 +
132853 + ier_val = qm_err_isr_enable_read(qm);
132854 + isr_val = qm_err_isr_status_read(qm);
132855 + ecsr_val = qm_in(ECSR);
132856 + isr_mask = isr_val & ier_val;
132857 +
132858 + if (!isr_mask)
132859 + return IRQ_NONE;
132860 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
132861 + if (qman_hwerr_txts[i].mask & isr_mask) {
132862 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
132863 + if (qman_hwerr_txts[i].mask & ecsr_val) {
132864 + log_additional_error_info(isr_mask, ecsr_val);
132865 + /* Re-arm error capture registers */
132866 + qm_out(ECSR, ecsr_val);
132867 + }
132868 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
132869 + pr_devel("Qman un-enabling error 0x%x\n",
132870 + qman_hwerr_txts[i].mask);
132871 + ier_val &= ~qman_hwerr_txts[i].mask;
132872 + qm_err_isr_enable_write(qm, ier_val);
132873 + }
132874 + }
132875 + }
132876 + qm_err_isr_status_clear(qm, isr_val);
132877 + return IRQ_HANDLED;
132878 +}
132879 +
132880 +static int __bind_irq(void)
132881 +{
132882 + int ret, err_irq;
132883 +
132884 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
132885 + if (err_irq == 0) {
132886 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
132887 + "interrupts");
132888 + return -ENODEV;
132889 + }
132890 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
132891 + if (ret) {
132892 + pr_err("request_irq() failed %d for '%s'\n", ret,
132893 + qm_node->full_name);
132894 + return -ENODEV;
132895 + }
132896 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
132897 + * to resource allocation during driver init). */
132898 + qm_err_isr_status_clear(qm, 0xffffffff);
132899 + /* Enable Error Interrupts */
132900 + qm_err_isr_enable_write(qm, 0xffffffff);
132901 + return 0;
132902 +}
132903 +
132904 +int qman_init_ccsr(struct device_node *node)
132905 +{
132906 + int ret;
132907 + if (!qman_have_ccsr())
132908 + return 0;
132909 + if (node != qm_node)
132910 + return -EINVAL;
132911 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132912 + /* TEMP for LS1043 : should be done in uboot */
132913 + qm_out(QCSP_BARE, 0x5);
132914 + qm_out(QCSP_BAR, 0x0);
132915 +#endif
132916 + /* FQD memory */
132917 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
132918 + /* PFDR memory */
132919 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
132920 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
132921 + /* thresholds */
132922 + qm_set_pfdr_threshold(qm, 512, 64);
132923 + qm_set_sfdr_threshold(qm, 128);
132924 + /* clear stale PEBI bit from interrupt status register */
132925 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
132926 + /* corenet initiator settings */
132927 + qm_set_corenet_initiator(qm);
132928 + /* HID settings */
132929 + qm_set_hid(qm);
132930 + /* Set scheduling weights to defaults */
132931 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
132932 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
132933 + /* We are not prepared to accept ERNs for hardware enqueues */
132934 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
132935 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
132936 + /* Initialise Error Interrupt Handler */
132937 + ret = __bind_irq();
132938 + if (ret)
132939 + return ret;
132940 + return 0;
132941 +}
132942 +
132943 +#define LIO_CFG_LIODN_MASK 0x0fff0000
132944 +void qman_liodn_fixup(u16 channel)
132945 +{
132946 + static int done;
132947 + static u32 liodn_offset;
132948 + u32 before, after;
132949 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132950 +
132951 + if (!qman_have_ccsr())
132952 + return;
132953 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132954 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
132955 + else
132956 + before = qm_in(QCSP_LIO_CFG(idx));
132957 + if (!done) {
132958 + liodn_offset = before & LIO_CFG_LIODN_MASK;
132959 + done = 1;
132960 + return;
132961 + }
132962 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
132963 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
132964 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
132965 + else
132966 + qm_out(QCSP_LIO_CFG(idx), after);
132967 +}
132968 +
132969 +#define IO_CFG_SDEST_MASK 0x00ff0000
132970 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
132971 +{
132972 + int idx = channel - QM_CHANNEL_SWPORTAL0;
132973 + u32 before, after;
132974 +
132975 + if (!qman_have_ccsr())
132976 + return -ENODEV;
132977 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
132978 + /* LS1043A - only one L2 cache */
132979 + cpu_idx = 0;
132980 + }
132981 +
132982 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
132983 + before = qm_in(REV3_QCSP_IO_CFG(idx));
132984 + /* Each pair of vcpu share the same SRQ(SDEST) */
132985 + cpu_idx /= 2;
132986 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132987 + qm_out(REV3_QCSP_IO_CFG(idx), after);
132988 + } else {
132989 + before = qm_in(QCSP_IO_CFG(idx));
132990 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
132991 + qm_out(QCSP_IO_CFG(idx), after);
132992 + }
132993 + return 0;
132994 +}
132995 +
132996 +#define MISC_CFG_WPM_MASK 0x00000002
132997 +int qm_set_wpm(int wpm)
132998 +{
132999 + u32 before;
133000 + u32 after;
133001 +
133002 + if (!qman_have_ccsr())
133003 + return -ENODEV;
133004 +
133005 + before = qm_in(MISC_CFG);
133006 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
133007 + qm_out(MISC_CFG, after);
133008 + return 0;
133009 +}
133010 +
133011 +int qm_get_wpm(int *wpm)
133012 +{
133013 + u32 before;
133014 +
133015 + if (!qman_have_ccsr())
133016 + return -ENODEV;
133017 +
133018 + before = qm_in(MISC_CFG);
133019 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
133020 + return 0;
133021 +}
133022 +
133023 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
133024 + * PRES = (2^22 / credit update reference period) * QMan clock period
133025 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
133026 + */
133027 +
133028 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
133029 +{
133030 + u64 temp;
133031 + u16 pres;
133032 +
133033 + if (!qman_have_ccsr())
133034 + return -ENODEV;
133035 +
133036 + temp = 0x400000 * 100;
133037 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
133038 + temp *= 10000000;
133039 + do_div(temp, qman_clk);
133040 + pres = (u16) temp;
133041 + qm_out(CEETM_CFG_IDX, portal);
133042 + qm_out(CEETM_CFG_PRES, pres);
133043 + return 0;
133044 +}
133045 +
133046 +int qman_ceetm_get_prescaler(u16 *pres)
133047 +{
133048 + if (!qman_have_ccsr())
133049 + return -ENODEV;
133050 + *pres = (u16)qm_in(CEETM_CFG_PRES);
133051 + return 0;
133052 +}
133053 +
133054 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
133055 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
133056 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133057 +{
133058 + u32 dcp_cfg;
133059 +
133060 + if (!qman_have_ccsr())
133061 + return -ENODEV;
133062 +
133063 + dcp_cfg = qm_in(DCP_CFG(portal));
133064 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
133065 + qm_out(DCP_CFG(portal), dcp_cfg);
133066 + return 0;
133067 +}
133068 +
133069 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
133070 +{
133071 + u32 dcp_cfg;
133072 +
133073 + if (!qman_have_ccsr())
133074 + return -ENODEV;
133075 + dcp_cfg = qm_in(DCP_CFG(portal));
133076 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
133077 + qm_out(DCP_CFG(portal), dcp_cfg);
133078 + return 0;
133079 +}
133080 +
133081 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
133082 +{
133083 + if (!qman_have_ccsr())
133084 + return -ENODEV;
133085 + *num = qm_in(CEETM_XSFDR_IN_USE);
133086 + return 0;
133087 +}
133088 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
133089 +
133090 +#ifdef CONFIG_SYSFS
133091 +
133092 +#define DRV_NAME "fsl-qman"
133093 +#define DCP_MAX_ID 3
133094 +#define DCP_MIN_ID 0
133095 +
133096 +static ssize_t show_pfdr_fpc(struct device *dev,
133097 + struct device_attribute *dev_attr, char *buf)
133098 +{
133099 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
133100 +};
133101 +
133102 +static ssize_t show_dlm_avg(struct device *dev,
133103 + struct device_attribute *dev_attr, char *buf)
133104 +{
133105 + u32 data;
133106 + int i;
133107 +
133108 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133109 + return -EINVAL;
133110 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133111 + return -EINVAL;
133112 + data = qm_in(DCP_DLM_AVG(i));
133113 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133114 + (data & 0x000000ff)*390625);
133115 +};
133116 +
133117 +static ssize_t set_dlm_avg(struct device *dev,
133118 + struct device_attribute *dev_attr, const char *buf, size_t count)
133119 +{
133120 + unsigned long val;
133121 + int i;
133122 +
133123 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
133124 + return -EINVAL;
133125 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
133126 + return -EINVAL;
133127 + if (kstrtoul(buf, 0, &val)) {
133128 + dev_dbg(dev, "invalid input %s\n", buf);
133129 + return -EINVAL;
133130 + }
133131 + qm_out(DCP_DLM_AVG(i), val);
133132 + return count;
133133 +};
133134 +
133135 +static ssize_t show_pfdr_cfg(struct device *dev,
133136 + struct device_attribute *dev_attr, char *buf)
133137 +{
133138 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
133139 +};
133140 +
133141 +static ssize_t set_pfdr_cfg(struct device *dev,
133142 + struct device_attribute *dev_attr, const char *buf, size_t count)
133143 +{
133144 + unsigned long val;
133145 +
133146 + if (kstrtoul(buf, 0, &val)) {
133147 + dev_dbg(dev, "invalid input %s\n", buf);
133148 + return -EINVAL;
133149 + }
133150 + qm_out(PFDR_CFG, val);
133151 + return count;
133152 +};
133153 +
133154 +static ssize_t show_sfdr_in_use(struct device *dev,
133155 + struct device_attribute *dev_attr, char *buf)
133156 +{
133157 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
133158 +};
133159 +
133160 +static ssize_t show_idle_stat(struct device *dev,
133161 + struct device_attribute *dev_attr, char *buf)
133162 +{
133163 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
133164 +};
133165 +
133166 +static ssize_t show_ci_rlm_avg(struct device *dev,
133167 + struct device_attribute *dev_attr, char *buf)
133168 +{
133169 + u32 data = qm_in(CI_RLM_AVG);
133170 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
133171 + (data & 0x000000ff)*390625);
133172 +};
133173 +
133174 +static ssize_t set_ci_rlm_avg(struct device *dev,
133175 + struct device_attribute *dev_attr, const char *buf, size_t count)
133176 +{
133177 + unsigned long val;
133178 +
133179 + if (kstrtoul(buf, 0, &val)) {
133180 + dev_dbg(dev, "invalid input %s\n", buf);
133181 + return -EINVAL;
133182 + }
133183 + qm_out(CI_RLM_AVG, val);
133184 + return count;
133185 +};
133186 +
133187 +static ssize_t show_err_isr(struct device *dev,
133188 + struct device_attribute *dev_attr, char *buf)
133189 +{
133190 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
133191 +};
133192 +
133193 +#define SBEC_MAX_ID 14
133194 +#define SBEC_MIN_ID 0
133195 +
133196 +static ssize_t show_sbec(struct device *dev,
133197 + struct device_attribute *dev_attr, char *buf)
133198 +{
133199 + int i;
133200 +
133201 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
133202 + return -EINVAL;
133203 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
133204 + return -EINVAL;
133205 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
133206 +};
133207 +
133208 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
133209 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
133210 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
133211 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
133212 + show_ci_rlm_avg, set_ci_rlm_avg);
133213 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
133214 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
133215 +
133216 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133217 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133218 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133219 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
133220 +
133221 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
133222 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
133223 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
133224 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
133225 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
133226 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
133227 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
133228 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
133229 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
133230 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
133231 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
133232 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
133233 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
133234 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
133235 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
133236 +
133237 +static struct attribute *qman_dev_attributes[] = {
133238 + &dev_attr_pfdr_fpc.attr,
133239 + &dev_attr_pfdr_cfg.attr,
133240 + &dev_attr_idle_stat.attr,
133241 + &dev_attr_ci_rlm_avg.attr,
133242 + &dev_attr_err_isr.attr,
133243 + &dev_attr_dcp0_dlm_avg.attr,
133244 + &dev_attr_dcp1_dlm_avg.attr,
133245 + &dev_attr_dcp2_dlm_avg.attr,
133246 + &dev_attr_dcp3_dlm_avg.attr,
133247 + /* sfdr_in_use will be added if necessary */
133248 + NULL
133249 +};
133250 +
133251 +static struct attribute *qman_dev_ecr_attributes[] = {
133252 + &dev_attr_sbec_0.attr,
133253 + &dev_attr_sbec_1.attr,
133254 + &dev_attr_sbec_2.attr,
133255 + &dev_attr_sbec_3.attr,
133256 + &dev_attr_sbec_4.attr,
133257 + &dev_attr_sbec_5.attr,
133258 + &dev_attr_sbec_6.attr,
133259 + &dev_attr_sbec_7.attr,
133260 + &dev_attr_sbec_8.attr,
133261 + &dev_attr_sbec_9.attr,
133262 + &dev_attr_sbec_10.attr,
133263 + &dev_attr_sbec_11.attr,
133264 + &dev_attr_sbec_12.attr,
133265 + &dev_attr_sbec_13.attr,
133266 + &dev_attr_sbec_14.attr,
133267 + NULL
133268 +};
133269 +
133270 +/* root level */
133271 +static const struct attribute_group qman_dev_attr_grp = {
133272 + .name = NULL,
133273 + .attrs = qman_dev_attributes
133274 +};
133275 +static const struct attribute_group qman_dev_ecr_grp = {
133276 + .name = "error_capture",
133277 + .attrs = qman_dev_ecr_attributes
133278 +};
133279 +
133280 +static int of_fsl_qman_remove(struct platform_device *ofdev)
133281 +{
133282 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133283 + return 0;
133284 +};
133285 +
133286 +static int of_fsl_qman_probe(struct platform_device *ofdev)
133287 +{
133288 + int ret;
133289 +
133290 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133291 + if (ret)
133292 + goto done;
133293 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
133294 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
133295 + if (ret)
133296 + goto del_group_0;
133297 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
133298 + if (ret)
133299 + goto del_group_0;
133300 +
133301 + goto done;
133302 +
133303 +del_group_0:
133304 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
133305 +done:
133306 + if (ret)
133307 + dev_err(&ofdev->dev,
133308 + "Cannot create dev attributes ret=%d\n", ret);
133309 + return ret;
133310 +};
133311 +
133312 +static struct of_device_id of_fsl_qman_ids[] = {
133313 + {
133314 + .compatible = "fsl,qman",
133315 + },
133316 + {}
133317 +};
133318 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
133319 +
133320 +#ifdef CONFIG_SUSPEND
133321 +
133322 +static u32 saved_isdr;
133323 +static int qman_pm_suspend_noirq(struct device *dev)
133324 +{
133325 + uint32_t idle_state;
133326 +
133327 + suspend_unused_qportal();
133328 + /* save isdr, disable all, clear isr */
133329 + saved_isdr = qm_err_isr_disable_read(qm);
133330 + qm_err_isr_disable_write(qm, 0xffffffff);
133331 + qm_err_isr_status_clear(qm, 0xffffffff);
133332 + idle_state = qm_in(IDLE_STAT);
133333 + if (!(idle_state & 0x1)) {
133334 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
133335 + qm_err_isr_disable_write(qm, saved_isdr);
133336 + resume_unused_qportal();
133337 + return -EBUSY;
133338 + }
133339 +#ifdef CONFIG_PM_DEBUG
133340 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
133341 +#endif
133342 + return 0;
133343 +}
133344 +
133345 +static int qman_pm_resume_noirq(struct device *dev)
133346 +{
133347 + /* restore isdr */
133348 + qm_err_isr_disable_write(qm, saved_isdr);
133349 + resume_unused_qportal();
133350 + return 0;
133351 +}
133352 +#else
133353 +#define qman_pm_suspend_noirq NULL
133354 +#define qman_pm_resume_noirq NULL
133355 +#endif
133356 +
133357 +static const struct dev_pm_ops qman_pm_ops = {
133358 + .suspend_noirq = qman_pm_suspend_noirq,
133359 + .resume_noirq = qman_pm_resume_noirq,
133360 +};
133361 +
133362 +static struct platform_driver of_fsl_qman_driver = {
133363 + .driver = {
133364 + .owner = THIS_MODULE,
133365 + .name = DRV_NAME,
133366 + .of_match_table = of_fsl_qman_ids,
133367 + .pm = &qman_pm_ops,
133368 + },
133369 + .probe = of_fsl_qman_probe,
133370 + .remove = of_fsl_qman_remove,
133371 +};
133372 +
133373 +static int qman_ctrl_init(void)
133374 +{
133375 + return platform_driver_register(&of_fsl_qman_driver);
133376 +}
133377 +
133378 +static void qman_ctrl_exit(void)
133379 +{
133380 + platform_driver_unregister(&of_fsl_qman_driver);
133381 +}
133382 +
133383 +module_init(qman_ctrl_init);
133384 +module_exit(qman_ctrl_exit);
133385 +
133386 +#endif /* CONFIG_SYSFS */
133387 --- /dev/null
133388 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
133389 @@ -0,0 +1,1594 @@
133390 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
133391 + *
133392 + * Redistribution and use in source and binary forms, with or without
133393 + * modification, are permitted provided that the following conditions are met:
133394 + * * Redistributions of source code must retain the above copyright
133395 + * notice, this list of conditions and the following disclaimer.
133396 + * * Redistributions in binary form must reproduce the above copyright
133397 + * notice, this list of conditions and the following disclaimer in the
133398 + * documentation and/or other materials provided with the distribution.
133399 + * * Neither the name of Freescale Semiconductor nor the
133400 + * names of its contributors may be used to endorse or promote products
133401 + * derived from this software without specific prior written permission.
133402 + *
133403 + *
133404 + * ALTERNATIVELY, this software may be distributed under the terms of the
133405 + * GNU General Public License ("GPL") as published by the Free Software
133406 + * Foundation, either version 2 of that License or (at your option) any
133407 + * later version.
133408 + *
133409 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133410 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133411 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133412 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133413 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133414 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133415 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133416 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133417 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133418 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133419 + */
133420 +#include "qman_private.h"
133421 +
133422 +#define MAX_FQID (0x00ffffff)
133423 +#define QM_FQD_BLOCK_SIZE 64
133424 +#define QM_FQD_AR (0xC10)
133425 +
133426 +static u32 fqid_max;
133427 +static u64 qman_ccsr_start;
133428 +static u64 qman_ccsr_size;
133429 +
133430 +static const char * const state_txt[] = {
133431 + "Out of Service",
133432 + "Retired",
133433 + "Tentatively Scheduled",
133434 + "Truly Scheduled",
133435 + "Parked",
133436 + "Active, Active Held or Held Suspended",
133437 + "Unknown State 6",
133438 + "Unknown State 7",
133439 + NULL,
133440 +};
133441 +
133442 +static const u8 fqd_states[] = {
133443 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
133444 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
133445 + QM_MCR_NP_STATE_ACTIVE};
133446 +
133447 +struct mask_to_text {
133448 + u16 mask;
133449 + const char *txt;
133450 +};
133451 +
133452 +struct mask_filter_s {
133453 + u16 mask;
133454 + u8 filter;
133455 +};
133456 +
133457 +static const struct mask_filter_s mask_filter[] = {
133458 + {QM_FQCTRL_PREFERINCACHE, 0},
133459 + {QM_FQCTRL_PREFERINCACHE, 1},
133460 + {QM_FQCTRL_HOLDACTIVE, 0},
133461 + {QM_FQCTRL_HOLDACTIVE, 1},
133462 + {QM_FQCTRL_AVOIDBLOCK, 0},
133463 + {QM_FQCTRL_AVOIDBLOCK, 1},
133464 + {QM_FQCTRL_FORCESFDR, 0},
133465 + {QM_FQCTRL_FORCESFDR, 1},
133466 + {QM_FQCTRL_CPCSTASH, 0},
133467 + {QM_FQCTRL_CPCSTASH, 1},
133468 + {QM_FQCTRL_CTXASTASHING, 0},
133469 + {QM_FQCTRL_CTXASTASHING, 1},
133470 + {QM_FQCTRL_ORP, 0},
133471 + {QM_FQCTRL_ORP, 1},
133472 + {QM_FQCTRL_TDE, 0},
133473 + {QM_FQCTRL_TDE, 1},
133474 + {QM_FQCTRL_CGE, 0},
133475 + {QM_FQCTRL_CGE, 1}
133476 +};
133477 +
133478 +static const struct mask_to_text fq_ctrl_text_list[] = {
133479 + {
133480 + .mask = QM_FQCTRL_PREFERINCACHE,
133481 + .txt = "Prefer in cache",
133482 + },
133483 + {
133484 + .mask = QM_FQCTRL_HOLDACTIVE,
133485 + .txt = "Hold active in portal",
133486 + },
133487 + {
133488 + .mask = QM_FQCTRL_AVOIDBLOCK,
133489 + .txt = "Avoid Blocking",
133490 + },
133491 + {
133492 + .mask = QM_FQCTRL_FORCESFDR,
133493 + .txt = "High-priority SFDRs",
133494 + },
133495 + {
133496 + .mask = QM_FQCTRL_CPCSTASH,
133497 + .txt = "CPC Stash Enable",
133498 + },
133499 + {
133500 + .mask = QM_FQCTRL_CTXASTASHING,
133501 + .txt = "Context-A stashing",
133502 + },
133503 + {
133504 + .mask = QM_FQCTRL_ORP,
133505 + .txt = "ORP Enable",
133506 + },
133507 + {
133508 + .mask = QM_FQCTRL_TDE,
133509 + .txt = "Tail-Drop Enable",
133510 + },
133511 + {
133512 + .mask = QM_FQCTRL_CGE,
133513 + .txt = "Congestion Group Enable",
133514 + },
133515 + {
133516 + .mask = 0,
133517 + .txt = NULL,
133518 + }
133519 +};
133520 +
133521 +static const char *get_fqd_ctrl_text(u16 mask)
133522 +{
133523 + int i = 0;
133524 +
133525 + while (fq_ctrl_text_list[i].txt != NULL) {
133526 + if (fq_ctrl_text_list[i].mask == mask)
133527 + return fq_ctrl_text_list[i].txt;
133528 + i++;
133529 + }
133530 + return NULL;
133531 +}
133532 +
133533 +static const struct mask_to_text stashing_text_list[] = {
133534 + {
133535 + .mask = QM_STASHING_EXCL_CTX,
133536 + .txt = "FQ Ctx Stash"
133537 + },
133538 + {
133539 + .mask = QM_STASHING_EXCL_DATA,
133540 + .txt = "Frame Data Stash",
133541 + },
133542 + {
133543 + .mask = QM_STASHING_EXCL_ANNOTATION,
133544 + .txt = "Frame Annotation Stash",
133545 + },
133546 + {
133547 + .mask = 0,
133548 + .txt = NULL,
133549 + },
133550 +};
133551 +
133552 +static int user_input_convert(const char __user *user_buf, size_t count,
133553 + unsigned long *val)
133554 +{
133555 + char buf[12];
133556 +
133557 + if (count > sizeof(buf) - 1)
133558 + return -EINVAL;
133559 + if (copy_from_user(buf, user_buf, count))
133560 + return -EFAULT;
133561 + buf[count] = '\0';
133562 + if (kstrtoul(buf, 0, val))
133563 + return -EINVAL;
133564 + return 0;
133565 +}
133566 +
133567 +struct line_buffer_fq {
133568 + u32 buf[8];
133569 + u32 buf_cnt;
133570 + int line_cnt;
133571 +};
133572 +
133573 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
133574 + struct seq_file *file)
133575 +{
133576 + line_buf->buf[line_buf->buf_cnt] = fqid;
133577 + line_buf->buf_cnt++;
133578 + if (line_buf->buf_cnt == 8) {
133579 + /* Buffer is full, flush it */
133580 + if (line_buf->line_cnt != 0)
133581 + seq_puts(file, ",\n");
133582 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
133583 + "0x%06x,0x%06x,0x%06x",
133584 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
133585 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
133586 + line_buf->buf[6], line_buf->buf[7]);
133587 + line_buf->buf_cnt = 0;
133588 + line_buf->line_cnt++;
133589 + }
133590 +}
133591 +
133592 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
133593 + struct seq_file *file)
133594 +{
133595 + if (line_buf->buf_cnt) {
133596 + int y = 0;
133597 + if (line_buf->line_cnt != 0)
133598 + seq_puts(file, ",\n");
133599 + while (y != line_buf->buf_cnt) {
133600 + if (y+1 == line_buf->buf_cnt)
133601 + seq_printf(file, "0x%06x", line_buf->buf[y]);
133602 + else
133603 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
133604 + y++;
133605 + }
133606 + line_buf->line_cnt++;
133607 + }
133608 + if (line_buf->line_cnt)
133609 + seq_putc(file, '\n');
133610 +}
133611 +
133612 +static struct dentry *dfs_root; /* debugfs root directory */
133613 +
133614 +/*******************************************************************************
133615 + * Query Frame Queue Non Programmable Fields
133616 + ******************************************************************************/
133617 +struct query_fq_np_fields_data_s {
133618 + u32 fqid;
133619 +};
133620 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
133621 + .fqid = 1,
133622 +};
133623 +
133624 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
133625 +{
133626 + int ret;
133627 + struct qm_mcr_queryfq_np np;
133628 + struct qman_fq fq;
133629 +
133630 + fq.fqid = query_fq_np_fields_data.fqid;
133631 + ret = qman_query_fq_np(&fq, &np);
133632 + if (ret)
133633 + return ret;
133634 + /* Print state */
133635 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
133636 + fq.fqid);
133637 + seq_printf(file, " force eligible pending: %s\n",
133638 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
133639 + seq_printf(file, " retirement pending: %s\n",
133640 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
133641 + seq_printf(file, " state: %s\n",
133642 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
133643 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
133644 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
133645 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
133646 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
133647 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
133648 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
133649 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
133650 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
133651 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
133652 + seq_printf(file, " is: ics_surp contains a %s\n",
133653 + (np.is) ? "deficit" : "surplus");
133654 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
133655 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
133656 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
133657 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
133658 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
133659 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
133660 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
133661 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
133662 + return 0;
133663 +}
133664 +
133665 +static int query_fq_np_fields_open(struct inode *inode,
133666 + struct file *file)
133667 +{
133668 + return single_open(file, query_fq_np_fields_show, NULL);
133669 +}
133670 +
133671 +static ssize_t query_fq_np_fields_write(struct file *f,
133672 + const char __user *buf, size_t count, loff_t *off)
133673 +{
133674 + int ret;
133675 + unsigned long val;
133676 +
133677 + ret = user_input_convert(buf, count, &val);
133678 + if (ret)
133679 + return ret;
133680 + if (val > MAX_FQID)
133681 + return -EINVAL;
133682 + query_fq_np_fields_data.fqid = (u32)val;
133683 + return count;
133684 +}
133685 +
133686 +static const struct file_operations query_fq_np_fields_fops = {
133687 + .owner = THIS_MODULE,
133688 + .open = query_fq_np_fields_open,
133689 + .read = seq_read,
133690 + .write = query_fq_np_fields_write,
133691 + .release = single_release,
133692 +};
133693 +
133694 +/*******************************************************************************
133695 + * Frame Queue Programmable Fields
133696 + ******************************************************************************/
133697 +struct query_fq_fields_data_s {
133698 + u32 fqid;
133699 +};
133700 +
133701 +static struct query_fq_fields_data_s query_fq_fields_data = {
133702 + .fqid = 1,
133703 +};
133704 +
133705 +static int query_fq_fields_show(struct seq_file *file, void *offset)
133706 +{
133707 + int ret;
133708 + struct qm_fqd fqd;
133709 + struct qman_fq fq;
133710 + int i = 0;
133711 +
133712 + memset(&fqd, 0, sizeof(struct qm_fqd));
133713 + fq.fqid = query_fq_fields_data.fqid;
133714 + ret = qman_query_fq(&fq, &fqd);
133715 + if (ret)
133716 + return ret;
133717 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
133718 + fq.fqid);
133719 + seq_printf(file, " orprws: %u\n", fqd.orprws);
133720 + seq_printf(file, " oa: %u\n", fqd.oa);
133721 + seq_printf(file, " olws: %u\n", fqd.olws);
133722 +
133723 + seq_printf(file, " cgid: %u\n", fqd.cgid);
133724 +
133725 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
133726 + seq_puts(file, " fq_ctrl: None\n");
133727 + else {
133728 + i = 0;
133729 + seq_puts(file, " fq_ctrl:\n");
133730 + while (fq_ctrl_text_list[i].txt != NULL) {
133731 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
133732 + fq_ctrl_text_list[i].mask)
133733 + seq_printf(file, " %s\n",
133734 + fq_ctrl_text_list[i].txt);
133735 + i++;
133736 + }
133737 + }
133738 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
133739 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
133740 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
133741 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
133742 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
133743 +
133744 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
133745 +
133746 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
133747 + /* Any stashing configured */
133748 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
133749 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
133750 + else {
133751 + seq_puts(file, " ctx_a_stash_exclusive:\n");
133752 + i = 0;
133753 + while (stashing_text_list[i].txt != NULL) {
133754 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
133755 + seq_printf(file, " %s\n",
133756 + stashing_text_list[i].txt);
133757 + i++;
133758 + }
133759 + }
133760 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
133761 + fqd.context_a.stashing.annotation_cl);
133762 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
133763 + fqd.context_a.stashing.data_cl);
133764 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
133765 + fqd.context_a.stashing.context_cl);
133766 + return 0;
133767 +}
133768 +
133769 +static int query_fq_fields_open(struct inode *inode,
133770 + struct file *file)
133771 +{
133772 + return single_open(file, query_fq_fields_show, NULL);
133773 +}
133774 +
133775 +static ssize_t query_fq_fields_write(struct file *f,
133776 + const char __user *buf, size_t count, loff_t *off)
133777 +{
133778 + int ret;
133779 + unsigned long val;
133780 +
133781 + ret = user_input_convert(buf, count, &val);
133782 + if (ret)
133783 + return ret;
133784 + if (val > MAX_FQID)
133785 + return -EINVAL;
133786 + query_fq_fields_data.fqid = (u32)val;
133787 + return count;
133788 +}
133789 +
133790 +static const struct file_operations query_fq_fields_fops = {
133791 + .owner = THIS_MODULE,
133792 + .open = query_fq_fields_open,
133793 + .read = seq_read,
133794 + .write = query_fq_fields_write,
133795 + .release = single_release,
133796 +};
133797 +
133798 +/*******************************************************************************
133799 + * Query WQ lengths
133800 + ******************************************************************************/
133801 +struct query_wq_lengths_data_s {
133802 + union {
133803 + u16 channel_wq; /* ignores wq (3 lsbits) */
133804 + struct {
133805 + u16 id:13; /* qm_channel */
133806 + u16 __reserved:3;
133807 + } __packed channel;
133808 + };
133809 +};
133810 +static struct query_wq_lengths_data_s query_wq_lengths_data;
133811 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
133812 +{
133813 + int ret;
133814 + struct qm_mcr_querywq wq;
133815 + int i;
133816 +
133817 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
133818 + wq.channel.id = query_wq_lengths_data.channel.id;
133819 + ret = qman_query_wq(0, &wq);
133820 + if (ret)
133821 + return ret;
133822 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
133823 + for (i = 0; i < 8; i++)
133824 + /* mask out upper 4 bits since they are not part of length */
133825 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
133826 + return 0;
133827 +}
133828 +
133829 +static int query_wq_lengths_open(struct inode *inode,
133830 + struct file *file)
133831 +{
133832 + return single_open(file, query_wq_lengths_show, NULL);
133833 +}
133834 +
133835 +static ssize_t query_wq_lengths_write(struct file *f,
133836 + const char __user *buf, size_t count, loff_t *off)
133837 +{
133838 + int ret;
133839 + unsigned long val;
133840 +
133841 + ret = user_input_convert(buf, count, &val);
133842 + if (ret)
133843 + return ret;
133844 + if (val > 0xfff8)
133845 + return -EINVAL;
133846 + query_wq_lengths_data.channel.id = (u16)val;
133847 + return count;
133848 +}
133849 +
133850 +static const struct file_operations query_wq_lengths_fops = {
133851 + .owner = THIS_MODULE,
133852 + .open = query_wq_lengths_open,
133853 + .read = seq_read,
133854 + .write = query_wq_lengths_write,
133855 + .release = single_release,
133856 +};
133857 +
133858 +/*******************************************************************************
133859 + * Query CGR
133860 + ******************************************************************************/
133861 +struct query_cgr_s {
133862 + u8 cgid;
133863 +};
133864 +static struct query_cgr_s query_cgr_data;
133865 +
133866 +static int query_cgr_show(struct seq_file *file, void *offset)
133867 +{
133868 + int ret;
133869 + struct qm_mcr_querycgr cgrd;
133870 + struct qman_cgr cgr;
133871 + int i, j;
133872 + u32 mask;
133873 +
133874 + memset(&cgr, 0, sizeof(cgr));
133875 + memset(&cgrd, 0, sizeof(cgrd));
133876 + cgr.cgrid = query_cgr_data.cgid;
133877 + ret = qman_query_cgr(&cgr, &cgrd);
133878 + if (ret)
133879 + return ret;
133880 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
133881 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133882 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
133883 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
133884 + cgrd.cgr.wr_parm_g.Pn);
133885 +
133886 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133887 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
133888 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
133889 + cgrd.cgr.wr_parm_y.Pn);
133890 +
133891 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133892 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
133893 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
133894 + cgrd.cgr.wr_parm_r.Pn);
133895 +
133896 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
133897 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
133898 +
133899 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
133900 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
133901 + seq_puts(file, " cscn_targ_dcp:\n");
133902 + mask = 0x80000000;
133903 + for (i = 0; i < 32; i++) {
133904 + if (cgrd.cgr.cscn_targ & mask)
133905 + seq_printf(file, " send CSCN to dcp %u\n",
133906 + (31 - i));
133907 + mask >>= 1;
133908 + }
133909 +
133910 + seq_puts(file, " cscn_targ_swp:\n");
133911 + for (i = 0; i < 4; i++) {
133912 + mask = 0x80000000;
133913 + for (j = 0; j < 32; j++) {
133914 + if (cgrd.cscn_targ_swp[i] & mask)
133915 + seq_printf(file, " send CSCN to swp"
133916 + " %u\n", (127 - (i * 32) - j));
133917 + mask >>= 1;
133918 + }
133919 + }
133920 + } else {
133921 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
133922 + }
133923 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
133924 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
133925 +
133926 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
133927 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
133928 +
133929 + seq_printf(file, " mode: %s\n",
133930 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
133931 + "frame count" : "byte count");
133932 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
133933 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
133934 +
133935 + return 0;
133936 +}
133937 +
133938 +static int query_cgr_open(struct inode *inode, struct file *file)
133939 +{
133940 + return single_open(file, query_cgr_show, NULL);
133941 +}
133942 +
133943 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
133944 + size_t count, loff_t *off)
133945 +{
133946 + int ret;
133947 + unsigned long val;
133948 +
133949 + ret = user_input_convert(buf, count, &val);
133950 + if (ret)
133951 + return ret;
133952 + if (val > 0xff)
133953 + return -EINVAL;
133954 + query_cgr_data.cgid = (u8)val;
133955 + return count;
133956 +}
133957 +
133958 +static const struct file_operations query_cgr_fops = {
133959 + .owner = THIS_MODULE,
133960 + .open = query_cgr_open,
133961 + .read = seq_read,
133962 + .write = query_cgr_write,
133963 + .release = single_release,
133964 +};
133965 +
133966 +/*******************************************************************************
133967 + * Test Write CGR
133968 + ******************************************************************************/
133969 +struct test_write_cgr_s {
133970 + u64 i_bcnt;
133971 + u8 cgid;
133972 +};
133973 +static struct test_write_cgr_s test_write_cgr_data;
133974 +
133975 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
133976 +{
133977 + int ret;
133978 + struct qm_mcr_cgrtestwrite result;
133979 + struct qman_cgr cgr;
133980 + u64 i_bcnt;
133981 +
133982 + memset(&cgr, 0, sizeof(struct qman_cgr));
133983 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
133984 + cgr.cgrid = test_write_cgr_data.cgid;
133985 + i_bcnt = test_write_cgr_data.i_bcnt;
133986 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
133987 + if (ret)
133988 + return ret;
133989 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
133990 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133991 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
133992 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
133993 + result.cgr.wr_parm_g.Pn);
133994 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133995 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
133996 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
133997 + result.cgr.wr_parm_y.Pn);
133998 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
133999 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
134000 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
134001 + result.cgr.wr_parm_r.Pn);
134002 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134003 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
134004 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
134005 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
134006 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
134007 + seq_printf(file, " cs: %u\n", result.cgr.cs);
134008 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
134009 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
134010 +
134011 + /* Add Mode for Si 2 */
134012 + seq_printf(file, " mode: %s\n",
134013 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
134014 + "frame count" : "byte count");
134015 +
134016 + seq_printf(file, " i_bcnt: %llu\n",
134017 + qm_mcr_cgrtestwrite_i_get64(&result));
134018 + seq_printf(file, " a_bcnt: %llu\n",
134019 + qm_mcr_cgrtestwrite_a_get64(&result));
134020 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
134021 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
134022 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
134023 + return 0;
134024 +}
134025 +
134026 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
134027 +{
134028 + return single_open(file, testwrite_cgr_show, NULL);
134029 +}
134030 +
134031 +static const struct file_operations testwrite_cgr_fops = {
134032 + .owner = THIS_MODULE,
134033 + .open = testwrite_cgr_open,
134034 + .read = seq_read,
134035 + .release = single_release,
134036 +};
134037 +
134038 +
134039 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
134040 +{
134041 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
134042 + return 0;
134043 +}
134044 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
134045 +{
134046 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
134047 +}
134048 +
134049 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
134050 + size_t count, loff_t *off)
134051 +{
134052 + int ret;
134053 + unsigned long val;
134054 +
134055 + ret = user_input_convert(buf, count, &val);
134056 + if (ret)
134057 + return ret;
134058 + test_write_cgr_data.i_bcnt = val;
134059 + return count;
134060 +}
134061 +
134062 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
134063 + .owner = THIS_MODULE,
134064 + .open = testwrite_cgr_ibcnt_open,
134065 + .read = seq_read,
134066 + .write = testwrite_cgr_ibcnt_write,
134067 + .release = single_release,
134068 +};
134069 +
134070 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
134071 +{
134072 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
134073 + return 0;
134074 +}
134075 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
134076 +{
134077 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
134078 +}
134079 +
134080 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
134081 + size_t count, loff_t *off)
134082 +{
134083 + int ret;
134084 + unsigned long val;
134085 +
134086 + ret = user_input_convert(buf, count, &val);
134087 + if (ret)
134088 + return ret;
134089 + if (val > 0xff)
134090 + return -EINVAL;
134091 + test_write_cgr_data.cgid = (u8)val;
134092 + return count;
134093 +}
134094 +
134095 +static const struct file_operations teswrite_cgr_cgrid_fops = {
134096 + .owner = THIS_MODULE,
134097 + .open = testwrite_cgr_cgrid_open,
134098 + .read = seq_read,
134099 + .write = testwrite_cgr_cgrid_write,
134100 + .release = single_release,
134101 +};
134102 +
134103 +/*******************************************************************************
134104 + * Query Congestion State
134105 + ******************************************************************************/
134106 +static int query_congestion_show(struct seq_file *file, void *offset)
134107 +{
134108 + int ret;
134109 + struct qm_mcr_querycongestion cs;
134110 + int i, j, in_cong = 0;
134111 + u32 mask;
134112 +
134113 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
134114 + ret = qman_query_congestion(&cs);
134115 + if (ret)
134116 + return ret;
134117 + seq_puts(file, "Query Congestion Result\n");
134118 + for (i = 0; i < 8; i++) {
134119 + mask = 0x80000000;
134120 + for (j = 0; j < 32; j++) {
134121 + if (cs.state.__state[i] & mask) {
134122 + in_cong = 1;
134123 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
134124 + "in congestion");
134125 + }
134126 + mask >>= 1;
134127 + }
134128 + }
134129 + if (!in_cong)
134130 + seq_puts(file, " All congestion groups not congested.\n");
134131 + return 0;
134132 +}
134133 +
134134 +static int query_congestion_open(struct inode *inode, struct file *file)
134135 +{
134136 + return single_open(file, query_congestion_show, NULL);
134137 +}
134138 +
134139 +static const struct file_operations query_congestion_fops = {
134140 + .owner = THIS_MODULE,
134141 + .open = query_congestion_open,
134142 + .read = seq_read,
134143 + .release = single_release,
134144 +};
134145 +
134146 +/*******************************************************************************
134147 + * Query CCGR
134148 + ******************************************************************************/
134149 +struct query_ccgr_s {
134150 + u32 ccgid;
134151 +};
134152 +static struct query_ccgr_s query_ccgr_data;
134153 +
134154 +static int query_ccgr_show(struct seq_file *file, void *offset)
134155 +{
134156 + int ret;
134157 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
134158 + struct qm_mcc_ceetm_ccgr_query query_opts;
134159 + int i, j;
134160 + u32 mask;
134161 +
134162 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
134163 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
134164 +
134165 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134166 + return -EINVAL;
134167 +
134168 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
134169 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
134170 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
134171 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
134172 + if (ret)
134173 + return ret;
134174 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
134175 + query_opts.dcpid);
134176 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134177 + ccgr_query.cm_query.wr_parm_g.MA,
134178 + ccgr_query.cm_query.wr_parm_g.Mn,
134179 + ccgr_query.cm_query.wr_parm_g.SA,
134180 + ccgr_query.cm_query.wr_parm_g.Sn,
134181 + ccgr_query.cm_query.wr_parm_g.Pn);
134182 +
134183 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134184 + ccgr_query.cm_query.wr_parm_y.MA,
134185 + ccgr_query.cm_query.wr_parm_y.Mn,
134186 + ccgr_query.cm_query.wr_parm_y.SA,
134187 + ccgr_query.cm_query.wr_parm_y.Sn,
134188 + ccgr_query.cm_query.wr_parm_y.Pn);
134189 +
134190 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
134191 + ccgr_query.cm_query.wr_parm_r.MA,
134192 + ccgr_query.cm_query.wr_parm_r.Mn,
134193 + ccgr_query.cm_query.wr_parm_r.SA,
134194 + ccgr_query.cm_query.wr_parm_r.Sn,
134195 + ccgr_query.cm_query.wr_parm_r.Pn);
134196 +
134197 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
134198 + ccgr_query.cm_query.ctl_wr_en_g,
134199 + ccgr_query.cm_query.ctl_wr_en_y,
134200 + ccgr_query.cm_query.ctl_wr_en_r);
134201 +
134202 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
134203 + seq_puts(file, " cscn_targ_dcp:\n");
134204 + mask = 0x80000000;
134205 + for (i = 0; i < 32; i++) {
134206 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
134207 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
134208 + mask >>= 1;
134209 + }
134210 +
134211 + seq_puts(file, " cscn_targ_swp:\n");
134212 + for (i = 0; i < 4; i++) {
134213 + mask = 0x80000000;
134214 + for (j = 0; j < 32; j++) {
134215 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
134216 + seq_printf(file, " send CSCN to swp"
134217 + "%u\n", (127 - (i * 32) - j));
134218 + mask >>= 1;
134219 + }
134220 + }
134221 +
134222 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
134223 +
134224 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
134225 + ccgr_query.cm_query.cs_thres.TA,
134226 + ccgr_query.cm_query.cs_thres.Tn);
134227 +
134228 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
134229 + ccgr_query.cm_query.cs_thres_x.TA,
134230 + ccgr_query.cm_query.cs_thres_x.Tn);
134231 +
134232 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
134233 + ccgr_query.cm_query.td_thres.TA,
134234 + ccgr_query.cm_query.td_thres.Tn);
134235 +
134236 + seq_printf(file, " mode: %s\n",
134237 + (ccgr_query.cm_query.ctl_mode &
134238 + QMAN_CGR_MODE_FRAME) ?
134239 + "frame count" : "byte count");
134240 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
134241 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
134242 +
134243 + return 0;
134244 +}
134245 +
134246 +static int query_ccgr_open(struct inode *inode, struct file *file)
134247 +{
134248 + return single_open(file, query_ccgr_show, NULL);
134249 +}
134250 +
134251 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
134252 + size_t count, loff_t *off)
134253 +{
134254 + int ret;
134255 + unsigned long val;
134256 +
134257 + ret = user_input_convert(buf, count, &val);
134258 + if (ret)
134259 + return ret;
134260 + query_ccgr_data.ccgid = val;
134261 + return count;
134262 +}
134263 +
134264 +static const struct file_operations query_ccgr_fops = {
134265 + .owner = THIS_MODULE,
134266 + .open = query_ccgr_open,
134267 + .read = seq_read,
134268 + .write = query_ccgr_write,
134269 + .release = single_release,
134270 +};
134271 +/*******************************************************************************
134272 + * QMan register
134273 + ******************************************************************************/
134274 +struct qman_register_s {
134275 + u32 val;
134276 +};
134277 +static struct qman_register_s qman_register_data;
134278 +
134279 +static void init_ccsrmempeek(void)
134280 +{
134281 + struct device_node *dn;
134282 + const u32 *regaddr_p;
134283 +
134284 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
134285 + if (!dn) {
134286 + pr_info("No fsl,qman node\n");
134287 + return;
134288 + }
134289 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
134290 + if (!regaddr_p) {
134291 + of_node_put(dn);
134292 + return;
134293 + }
134294 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
134295 + of_node_put(dn);
134296 +}
134297 +/* This function provides access to QMan ccsr memory map */
134298 +static int qman_ccsrmempeek(u32 *val, u32 offset)
134299 +{
134300 + void __iomem *addr;
134301 + u64 phys_addr;
134302 +
134303 + if (!qman_ccsr_start)
134304 + return -EINVAL;
134305 +
134306 + if (offset > (qman_ccsr_size - sizeof(u32)))
134307 + return -EINVAL;
134308 +
134309 + phys_addr = qman_ccsr_start + offset;
134310 + addr = ioremap(phys_addr, sizeof(u32));
134311 + if (!addr) {
134312 + pr_err("ccsrmempeek, ioremap failed\n");
134313 + return -EINVAL;
134314 + }
134315 + *val = in_be32(addr);
134316 + iounmap(addr);
134317 + return 0;
134318 +}
134319 +
134320 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
134321 +{
134322 + u32 b;
134323 +
134324 + qman_ccsrmempeek(&b, qman_register_data.val);
134325 + seq_printf(file, "QMan register offset = 0x%x\n",
134326 + qman_register_data.val);
134327 + seq_printf(file, "value = 0x%08x\n", b);
134328 +
134329 + return 0;
134330 +}
134331 +
134332 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
134333 +{
134334 + return single_open(file, qman_ccsrmempeek_show, NULL);
134335 +}
134336 +
134337 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
134338 + size_t count, loff_t *off)
134339 +{
134340 + int ret;
134341 + unsigned long val;
134342 +
134343 + ret = user_input_convert(buf, count, &val);
134344 + if (ret)
134345 + return ret;
134346 + /* multiple of 4 */
134347 + if (val > (qman_ccsr_size - sizeof(u32))) {
134348 + pr_info("Input 0x%lx > 0x%llx\n",
134349 + val, (qman_ccsr_size - sizeof(u32)));
134350 + return -EINVAL;
134351 + }
134352 + if (val & 0x3) {
134353 + pr_info("Input 0x%lx not multiple of 4\n", val);
134354 + return -EINVAL;
134355 + }
134356 + qman_register_data.val = val;
134357 + return count;
134358 +}
134359 +
134360 +static const struct file_operations qman_ccsrmempeek_fops = {
134361 + .owner = THIS_MODULE,
134362 + .open = qman_ccsrmempeek_open,
134363 + .read = seq_read,
134364 + .write = qman_ccsrmempeek_write,
134365 +};
134366 +
134367 +/*******************************************************************************
134368 + * QMan state
134369 + ******************************************************************************/
134370 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
134371 +{
134372 + struct qm_mcr_queryfq_np np;
134373 + struct qman_fq fq;
134374 + struct line_buffer_fq line_buf;
134375 + int ret, i;
134376 + u8 *state = file->private;
134377 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134378 +
134379 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134380 + memset(&line_buf, 0, sizeof(line_buf));
134381 +
134382 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
134383 +
134384 + for (i = 1; i < fqid_max; i++) {
134385 + fq.fqid = i;
134386 + ret = qman_query_fq_np(&fq, &np);
134387 + if (ret)
134388 + return ret;
134389 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
134390 + add_to_line_buffer(&line_buf, fq.fqid, file);
134391 + /* Keep a summary count of all states */
134392 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134393 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134394 + }
134395 + flush_line_buffer(&line_buf, file);
134396 +
134397 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134398 + seq_printf(file, "%s count = %u\n", state_txt[i],
134399 + qm_fq_state_cnt[i]);
134400 + }
134401 + return 0;
134402 +}
134403 +
134404 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
134405 +{
134406 + return single_open(file, qman_fqd_state_show, inode->i_private);
134407 +}
134408 +
134409 +static const struct file_operations qman_fqd_state_fops = {
134410 + .owner = THIS_MODULE,
134411 + .open = qman_fqd_state_open,
134412 + .read = seq_read,
134413 +};
134414 +
134415 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
134416 +{
134417 + struct qm_fqd fqd;
134418 + struct qman_fq fq;
134419 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
134420 + int ret, i;
134421 + struct mask_filter_s *data = file->private;
134422 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
134423 + struct line_buffer_fq line_buf;
134424 +
134425 + memset(&line_buf, 0, sizeof(line_buf));
134426 + seq_printf(file, "List of fq ids with: %s :%s\n",
134427 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
134428 + for (i = 1; i < fqid_max; i++) {
134429 + fq.fqid = i;
134430 + memset(&fqd, 0, sizeof(struct qm_fqd));
134431 + ret = qman_query_fq(&fq, &fqd);
134432 + if (ret)
134433 + return ret;
134434 + if (data->filter) {
134435 + if (fqd.fq_ctrl & data->mask)
134436 + add_to_line_buffer(&line_buf, fq.fqid, file);
134437 + } else {
134438 + if (!(fqd.fq_ctrl & data->mask))
134439 + add_to_line_buffer(&line_buf, fq.fqid, file);
134440 + }
134441 + if (fqd.fq_ctrl & data->mask)
134442 + fq_en_cnt++;
134443 + else
134444 + fq_di_cnt++;
134445 + }
134446 + flush_line_buffer(&line_buf, file);
134447 +
134448 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
134449 + ctrl_txt, fq_en_cnt);
134450 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
134451 + ctrl_txt, fq_di_cnt);
134452 + return 0;
134453 +}
134454 +
134455 +/*******************************************************************************
134456 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
134457 + ******************************************************************************/
134458 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
134459 +{
134460 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
134461 +}
134462 +
134463 +static const struct file_operations qman_fqd_ctrl_fops = {
134464 + .owner = THIS_MODULE,
134465 + .open = qman_fqd_ctrl_open,
134466 + .read = seq_read,
134467 +};
134468 +
134469 +/*******************************************************************************
134470 + * QMan ctrl summary
134471 + ******************************************************************************/
134472 +/*******************************************************************************
134473 + * QMan summary state
134474 + ******************************************************************************/
134475 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
134476 +{
134477 + struct qm_mcr_queryfq_np np;
134478 + struct qman_fq fq;
134479 + int ret, i;
134480 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
134481 +
134482 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
134483 +
134484 + for (i = 1; i < fqid_max; i++) {
134485 + fq.fqid = i;
134486 + ret = qman_query_fq_np(&fq, &np);
134487 + if (ret)
134488 + return ret;
134489 + /* Keep a summary count of all states */
134490 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
134491 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
134492 + }
134493 +
134494 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
134495 + seq_printf(file, "%s count = %u\n", state_txt[i],
134496 + qm_fq_state_cnt[i]);
134497 + }
134498 + return 0;
134499 +}
134500 +
134501 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
134502 +{
134503 + struct qm_fqd fqd;
134504 + struct qman_fq fq;
134505 + int ret, i , j;
134506 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
134507 +
134508 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
134509 +
134510 + for (i = 1; i < fqid_max; i++) {
134511 + memset(&fqd, 0, sizeof(struct qm_fqd));
134512 + fq.fqid = i;
134513 + ret = qman_query_fq(&fq, &fqd);
134514 + if (ret)
134515 + return ret;
134516 + /* Keep a summary count of all states */
134517 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
134518 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
134519 + mask_filter[j].mask)
134520 + qm_prog_cnt[j/2]++;
134521 + }
134522 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
134523 + seq_printf(file, "%s count = %u\n",
134524 + get_fqd_ctrl_text(mask_filter[i*2].mask),
134525 + qm_prog_cnt[i]);
134526 + }
134527 + return 0;
134528 +}
134529 +
134530 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
134531 +{
134532 + int ret;
134533 +
134534 + /* Display summary of non programmable fields */
134535 + ret = qman_fqd_non_prog_summary_show(file, offset);
134536 + if (ret)
134537 + return ret;
134538 + seq_puts(file, "-----------------------------------------\n");
134539 + /* Display programmable fields */
134540 + ret = qman_fqd_prog_summary_show(file, offset);
134541 + if (ret)
134542 + return ret;
134543 + return 0;
134544 +}
134545 +
134546 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
134547 +{
134548 + return single_open(file, qman_fqd_summary_show, NULL);
134549 +}
134550 +
134551 +static const struct file_operations qman_fqd_summary_fops = {
134552 + .owner = THIS_MODULE,
134553 + .open = qman_fqd_summary_open,
134554 + .read = seq_read,
134555 +};
134556 +
134557 +/*******************************************************************************
134558 + * QMan destination work queue
134559 + ******************************************************************************/
134560 +struct qman_dest_wq_s {
134561 + u16 wq_id;
134562 +};
134563 +static struct qman_dest_wq_s qman_dest_wq_data = {
134564 + .wq_id = 0,
134565 +};
134566 +
134567 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
134568 +{
134569 + struct qm_fqd fqd;
134570 + struct qman_fq fq;
134571 + int ret, i;
134572 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
134573 + struct line_buffer_fq line_buf;
134574 +
134575 + memset(&line_buf, 0, sizeof(line_buf));
134576 + /* use vmalloc : need to allocate large memory region and don't
134577 + * require the memory to be physically contiguous. */
134578 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
134579 + if (!wq)
134580 + return -ENOMEM;
134581 +
134582 + seq_printf(file, "List of fq ids with destination work queue id"
134583 + " = 0x%x\n", wq_id);
134584 +
134585 + for (i = 1; i < fqid_max; i++) {
134586 + fq.fqid = i;
134587 + memset(&fqd, 0, sizeof(struct qm_fqd));
134588 + ret = qman_query_fq(&fq, &fqd);
134589 + if (ret) {
134590 + vfree(wq);
134591 + return ret;
134592 + }
134593 + if (wq_id == fqd.dest_wq)
134594 + add_to_line_buffer(&line_buf, fq.fqid, file);
134595 + wq[fqd.dest_wq]++;
134596 + }
134597 + flush_line_buffer(&line_buf, file);
134598 +
134599 + seq_puts(file, "Summary of all FQD destination work queue values\n");
134600 + for (i = 0; i < 0xFFFF; i++) {
134601 + if (wq[i])
134602 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
134603 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
134604 + }
134605 + vfree(wq);
134606 + return 0;
134607 +}
134608 +
134609 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
134610 + size_t count, loff_t *off)
134611 +{
134612 + int ret;
134613 + unsigned long val;
134614 +
134615 + ret = user_input_convert(buf, count, &val);
134616 + if (ret)
134617 + return ret;
134618 + if (val > 0xFFFF)
134619 + return -EINVAL;
134620 + qman_dest_wq_data.wq_id = val;
134621 + return count;
134622 +}
134623 +
134624 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
134625 +{
134626 + return single_open(file, qman_fqd_dest_wq_show, NULL);
134627 +}
134628 +
134629 +static const struct file_operations qman_fqd_dest_wq_fops = {
134630 + .owner = THIS_MODULE,
134631 + .open = qman_fqd_dest_wq_open,
134632 + .read = seq_read,
134633 + .write = qman_fqd_dest_wq_write,
134634 +};
134635 +
134636 +/*******************************************************************************
134637 + * QMan Intra-Class Scheduling Credit
134638 + ******************************************************************************/
134639 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
134640 +{
134641 + struct qm_fqd fqd;
134642 + struct qman_fq fq;
134643 + int ret, i;
134644 + u32 fq_cnt = 0;
134645 + struct line_buffer_fq line_buf;
134646 +
134647 + memset(&line_buf, 0, sizeof(line_buf));
134648 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
134649 + "\n");
134650 +
134651 + for (i = 1; i < fqid_max; i++) {
134652 + fq.fqid = i;
134653 + memset(&fqd, 0, sizeof(struct qm_fqd));
134654 + ret = qman_query_fq(&fq, &fqd);
134655 + if (ret)
134656 + return ret;
134657 + if (fqd.ics_cred > 0) {
134658 + add_to_line_buffer(&line_buf, fq.fqid, file);
134659 + fq_cnt++;
134660 + }
134661 + }
134662 + flush_line_buffer(&line_buf, file);
134663 +
134664 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
134665 + return 0;
134666 +}
134667 +
134668 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
134669 +{
134670 + return single_open(file, qman_fqd_cred_show, NULL);
134671 +}
134672 +
134673 +static const struct file_operations qman_fqd_cred_fops = {
134674 + .owner = THIS_MODULE,
134675 + .open = qman_fqd_cred_open,
134676 + .read = seq_read,
134677 +};
134678 +
134679 +/*******************************************************************************
134680 + * Class Queue Fields
134681 + ******************************************************************************/
134682 +struct query_cq_fields_data_s {
134683 + u32 cqid;
134684 +};
134685 +
134686 +static struct query_cq_fields_data_s query_cq_fields_data = {
134687 + .cqid = 1,
134688 +};
134689 +
134690 +static int query_cq_fields_show(struct seq_file *file, void *offset)
134691 +{
134692 + int ret;
134693 + struct qm_mcr_ceetm_cq_query query_result;
134694 + unsigned int cqid;
134695 + unsigned int portal;
134696 +
134697 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
134698 + return -EINVAL;
134699 +
134700 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
134701 + portal = query_cq_fields_data.cqid >> 24;
134702 + if (portal > qm_dc_portal_fman1)
134703 + return -EINVAL;
134704 +
134705 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
134706 + if (ret)
134707 + return ret;
134708 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
134709 + cqid, portal);
134710 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
134711 + seq_printf(file, " state: %u\n", query_result.state);
134712 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
134713 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
134714 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
134715 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
134716 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
134717 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
134718 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
134719 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
134720 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
134721 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
134722 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
134723 +
134724 + return 0;
134725 +}
134726 +
134727 +static int query_cq_fields_open(struct inode *inode,
134728 + struct file *file)
134729 +{
134730 + return single_open(file, query_cq_fields_show, NULL);
134731 +}
134732 +
134733 +static ssize_t query_cq_fields_write(struct file *f,
134734 + const char __user *buf, size_t count, loff_t *off)
134735 +{
134736 + int ret;
134737 + unsigned long val;
134738 +
134739 + ret = user_input_convert(buf, count, &val);
134740 + if (ret)
134741 + return ret;
134742 + query_cq_fields_data.cqid = (u32)val;
134743 + return count;
134744 +}
134745 +
134746 +static const struct file_operations query_cq_fields_fops = {
134747 + .owner = THIS_MODULE,
134748 + .open = query_cq_fields_open,
134749 + .read = seq_read,
134750 + .write = query_cq_fields_write,
134751 + .release = single_release,
134752 +};
134753 +
134754 +/*******************************************************************************
134755 + * READ CEETM_XSFDR_IN_USE
134756 + ******************************************************************************/
134757 +struct query_ceetm_xsfdr_data_s {
134758 + enum qm_dc_portal dcp_portal;
134759 +};
134760 +
134761 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
134762 +
134763 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
134764 +{
134765 + int ret;
134766 + unsigned int xsfdr_in_use;
134767 + enum qm_dc_portal portal;
134768 +
134769 +
134770 + if (qman_ip_rev < QMAN_REV31)
134771 + return -EINVAL;
134772 +
134773 + portal = query_ceetm_xsfdr_data.dcp_portal;
134774 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
134775 + if (ret) {
134776 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
134777 + portal);
134778 + return ret;
134779 + }
134780 +
134781 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
134782 + (xsfdr_in_use & 0x1FFF));
134783 + return 0;
134784 +}
134785 +
134786 +static int query_ceetm_xsfdr_open(struct inode *inode,
134787 + struct file *file)
134788 +{
134789 + return single_open(file, query_ceetm_xsfdr_show, NULL);
134790 +}
134791 +
134792 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
134793 + const char __user *buf, size_t count, loff_t *off)
134794 +{
134795 + int ret;
134796 + unsigned long val;
134797 +
134798 + ret = user_input_convert(buf, count, &val);
134799 + if (ret)
134800 + return ret;
134801 + if (val > qm_dc_portal_fman1)
134802 + return -EINVAL;
134803 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
134804 + return count;
134805 +}
134806 +
134807 +static const struct file_operations query_ceetm_xsfdr_fops = {
134808 + .owner = THIS_MODULE,
134809 + .open = query_ceetm_xsfdr_open,
134810 + .read = seq_read,
134811 + .write = query_ceetm_xsfdr_write,
134812 + .release = single_release,
134813 +};
134814 +
134815 +/* helper macros used in qman_debugfs_module_init */
134816 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
134817 + do { \
134818 + d = debugfs_create_file(name, \
134819 + mode, parent, \
134820 + data, \
134821 + fops); \
134822 + if (d == NULL) { \
134823 + ret = -ENOMEM; \
134824 + goto _return; \
134825 + } \
134826 + } while (0)
134827 +
134828 +/* dfs_root as parent */
134829 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
134830 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
134831 +
134832 +/* fqd_root as parent */
134833 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
134834 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
134835 +
134836 +/* fqd state */
134837 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
134838 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
134839 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
134840 +
134841 +static int __init qman_debugfs_module_init(void)
134842 +{
134843 + int ret = 0;
134844 + struct dentry *d, *fqd_root;
134845 + u32 reg;
134846 +
134847 + fqid_max = 0;
134848 + init_ccsrmempeek();
134849 + if (qman_ccsr_start) {
134850 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
134851 + /* extract the size of the FQD window */
134852 + reg = reg & 0x3f;
134853 + /* calculate valid frame queue descriptor range */
134854 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
134855 + }
134856 + }
134857 + dfs_root = debugfs_create_dir("qman", NULL);
134858 + fqd_root = debugfs_create_dir("fqd", dfs_root);
134859 + if (dfs_root == NULL || fqd_root == NULL) {
134860 + ret = -ENOMEM;
134861 + pr_err("Cannot create qman/fqd debugfs dir\n");
134862 + goto _return;
134863 + }
134864 + if (fqid_max) {
134865 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
134866 + NULL, &qman_ccsrmempeek_fops);
134867 + }
134868 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
134869 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
134870 +
134871 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
134872 + &query_fq_fields_data, &query_fq_fields_fops);
134873 +
134874 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
134875 + &query_wq_lengths_data, &query_wq_lengths_fops);
134876 +
134877 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
134878 + &query_cgr_data, &query_cgr_fops);
134879 +
134880 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
134881 + NULL, &query_congestion_fops);
134882 +
134883 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
134884 + NULL, &testwrite_cgr_fops);
134885 +
134886 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
134887 + NULL, &teswrite_cgr_cgrid_fops);
134888 +
134889 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
134890 + NULL, &teswrite_cgr_ibcnt_fops);
134891 +
134892 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
134893 + &query_ccgr_data, &query_ccgr_fops);
134894 + /* Create files with fqd_root as parent */
134895 +
134896 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
134897 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
134898 +
134899 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
134900 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
134901 + &qman_fqd_state_fops);
134902 +
134903 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
134904 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
134905 + &qman_fqd_state_fops);
134906 +
134907 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
134908 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
134909 + &qman_fqd_state_fops);
134910 +
134911 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
134912 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
134913 + &qman_fqd_state_fops);
134914 +
134915 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
134916 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
134917 + &qman_fqd_state_fops);
134918 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
134919 + &query_cq_fields_data, &query_cq_fields_fops);
134920 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
134921 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
134922 +
134923 +
134924 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
134925 +
134926 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
134927 +
134928 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
134929 +
134930 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
134931 +
134932 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
134933 +
134934 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
134935 +
134936 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
134937 +
134938 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
134939 +
134940 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
134941 +
134942 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
134943 +
134944 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
134945 +
134946 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
134947 +
134948 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
134949 +
134950 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
134951 +
134952 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
134953 +
134954 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
134955 +
134956 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
134957 +
134958 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
134959 +
134960 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
134961 + NULL, &qman_fqd_summary_fops);
134962 +
134963 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
134964 + NULL, &qman_fqd_dest_wq_fops);
134965 +
134966 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
134967 + NULL, &qman_fqd_cred_fops);
134968 +
134969 + return 0;
134970 +
134971 +_return:
134972 + debugfs_remove_recursive(dfs_root);
134973 + return ret;
134974 +}
134975 +
134976 +static void __exit qman_debugfs_module_exit(void)
134977 +{
134978 + debugfs_remove_recursive(dfs_root);
134979 +}
134980 +
134981 +module_init(qman_debugfs_module_init);
134982 +module_exit(qman_debugfs_module_exit);
134983 +MODULE_LICENSE("Dual BSD/GPL");
134984 --- /dev/null
134985 +++ b/drivers/staging/fsl_qbman/qman_driver.c
134986 @@ -0,0 +1,977 @@
134987 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
134988 + *
134989 + * Redistribution and use in source and binary forms, with or without
134990 + * modification, are permitted provided that the following conditions are met:
134991 + * * Redistributions of source code must retain the above copyright
134992 + * notice, this list of conditions and the following disclaimer.
134993 + * * Redistributions in binary form must reproduce the above copyright
134994 + * notice, this list of conditions and the following disclaimer in the
134995 + * documentation and/or other materials provided with the distribution.
134996 + * * Neither the name of Freescale Semiconductor nor the
134997 + * names of its contributors may be used to endorse or promote products
134998 + * derived from this software without specific prior written permission.
134999 + *
135000 + *
135001 + * ALTERNATIVELY, this software may be distributed under the terms of the
135002 + * GNU General Public License ("GPL") as published by the Free Software
135003 + * Foundation, either version 2 of that License or (at your option) any
135004 + * later version.
135005 + *
135006 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135007 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135008 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135009 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135010 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135011 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135012 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135013 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135014 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135015 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135016 + */
135017 +
135018 +#include "qman_private.h"
135019 +
135020 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
135021 +#ifdef CONFIG_HOTPLUG_CPU
135022 +#include <linux/cpu.h>
135023 +#endif
135024 +
135025 +/* Global variable containing revision id (even on non-control plane systems
135026 + * where CCSR isn't available) */
135027 +u16 qman_ip_rev;
135028 +EXPORT_SYMBOL(qman_ip_rev);
135029 +u8 qman_ip_cfg;
135030 +EXPORT_SYMBOL(qman_ip_cfg);
135031 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
135032 +EXPORT_SYMBOL(qm_channel_pool1);
135033 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
135034 +EXPORT_SYMBOL(qm_channel_caam);
135035 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
135036 +EXPORT_SYMBOL(qm_channel_pme);
135037 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
135038 +EXPORT_SYMBOL(qm_channel_dce);
135039 +u16 qman_portal_max;
135040 +EXPORT_SYMBOL(qman_portal_max);
135041 +
135042 +u32 qman_clk;
135043 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
135044 +/* the qman ceetm instances on the given SoC */
135045 +u8 num_ceetms;
135046 +
135047 +/* For these variables, and the portal-initialisation logic, the
135048 + * comments in bman_driver.c apply here so won't be repeated. */
135049 +static struct qman_portal *shared_portals[NR_CPUS];
135050 +static int num_shared_portals;
135051 +static int shared_portals_idx;
135052 +static LIST_HEAD(unused_pcfgs);
135053 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
135054 +
135055 +/* A SDQCR mask comprising all the available/visible pool channels */
135056 +static u32 pools_sdqcr;
135057 +
135058 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
135059 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
135060 +#define STR_FQID_RANGE "fsl,fqid-range"
135061 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
135062 +#define STR_CGRID_RANGE "fsl,cgrid-range"
135063 +
135064 +/* A "fsl,fqid-range" node; release the given range to the allocator */
135065 +static __init int fsl_fqid_range_init(struct device_node *node)
135066 +{
135067 + int ret;
135068 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
135069 + if (!range) {
135070 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
135071 + return -EINVAL;
135072 + }
135073 + if (ret != 8) {
135074 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
135075 + return -EINVAL;
135076 + }
135077 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135078 + pr_info("Qman: FQID allocator includes range %d:%d\n",
135079 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135080 + return 0;
135081 +}
135082 +
135083 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
135084 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
135085 +{
135086 + int ret;
135087 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135088 + if (!chanid) {
135089 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135090 + return -EINVAL;
135091 + }
135092 + if (ret != 8) {
135093 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135094 + return -EINVAL;
135095 + }
135096 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
135097 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
135098 + return 0;
135099 +}
135100 +
135101 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
135102 +static __init int fsl_pool_channel_range_init(struct device_node *node)
135103 +{
135104 + int ret;
135105 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
135106 + if (!chanid) {
135107 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
135108 + return -EINVAL;
135109 + }
135110 + if (ret != 8) {
135111 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
135112 + return -EINVAL;
135113 + }
135114 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135115 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
135116 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
135117 + return 0;
135118 +}
135119 +
135120 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
135121 +static __init int fsl_cgrid_range_init(struct device_node *node)
135122 +{
135123 + struct qman_cgr cgr;
135124 + int ret, errors = 0;
135125 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
135126 + if (!range) {
135127 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
135128 + return -EINVAL;
135129 + }
135130 + if (ret != 8) {
135131 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
135132 + return -EINVAL;
135133 + }
135134 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135135 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
135136 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135137 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
135138 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
135139 + if (ret)
135140 + errors++;
135141 + }
135142 + if (errors)
135143 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
135144 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
135145 + return 0;
135146 +}
135147 +
135148 +static __init int fsl_ceetm_init(struct device_node *node)
135149 +{
135150 + enum qm_dc_portal dcp_portal;
135151 + struct qm_ceetm_sp *sp;
135152 + struct qm_ceetm_lni *lni;
135153 + int ret, i;
135154 + const u32 *range;
135155 +
135156 + /* Find LFQID range */
135157 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
135158 + if (!range) {
135159 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
135160 + node->full_name);
135161 + return -EINVAL;
135162 + }
135163 + if (ret != 8) {
135164 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
135165 + " %s\n", node->full_name);
135166 + return -EINVAL;
135167 + }
135168 +
135169 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
135170 + if (dcp_portal > qm_dc_portal_fman1) {
135171 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
135172 + return -EINVAL;
135173 + }
135174 +
135175 + if (dcp_portal == qm_dc_portal_fman0)
135176 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135177 + if (dcp_portal == qm_dc_portal_fman1)
135178 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135179 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
135180 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135181 +
135182 + qman_ceetms[dcp_portal].idx = dcp_portal;
135183 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
135184 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
135185 +
135186 + /* Find Sub-portal range */
135187 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
135188 + if (!range) {
135189 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
135190 + return -EINVAL;
135191 + }
135192 + if (ret != 8) {
135193 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
135194 + node->full_name);
135195 + return -EINVAL;
135196 + }
135197 +
135198 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135199 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
135200 + if (!sp) {
135201 + pr_err("Can't alloc memory for sub-portal %d\n",
135202 + range[0] + i);
135203 + return -ENOMEM;
135204 + }
135205 + sp->idx = be32_to_cpu(range[0]) + i;
135206 + sp->dcp_idx = dcp_portal;
135207 + sp->is_claimed = 0;
135208 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
135209 + sp++;
135210 + }
135211 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
135212 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135213 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
135214 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
135215 +
135216 + /* Find LNI range */
135217 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
135218 + if (!range) {
135219 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
135220 + return -EINVAL;
135221 + }
135222 + if (ret != 8) {
135223 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
135224 + node->full_name);
135225 + return -EINVAL;
135226 + }
135227 +
135228 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
135229 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
135230 + if (!lni) {
135231 + pr_err("Can't alloc memory for LNI %d\n",
135232 + range[0] + i);
135233 + return -ENOMEM;
135234 + }
135235 + lni->idx = be32_to_cpu(range[0]) + i;
135236 + lni->dcp_idx = dcp_portal;
135237 + lni->is_claimed = 0;
135238 + INIT_LIST_HEAD(&lni->channels);
135239 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
135240 + lni++;
135241 + }
135242 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
135243 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
135244 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
135245 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
135246 +
135247 + /* Find CEETM channel range */
135248 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
135249 + if (!range) {
135250 + pr_err("No fsl,ceetm-channel-range in node %s\n",
135251 + node->full_name);
135252 + return -EINVAL;
135253 + }
135254 + if (ret != 8) {
135255 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
135256 + "%s\n", node->full_name);
135257 + return -EINVAL;
135258 + }
135259 +
135260 + if (dcp_portal == qm_dc_portal_fman0)
135261 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135262 + if (dcp_portal == qm_dc_portal_fman1)
135263 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135264 + pr_debug("Qman: The channel allocator of CEETM %d includes"
135265 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
135266 +
135267 + /* Set CEETM PRES register */
135268 + ret = qman_ceetm_set_prescaler(dcp_portal);
135269 + if (ret)
135270 + return ret;
135271 + return 0;
135272 +}
135273 +
135274 +static void qman_get_ip_revision(struct device_node *dn)
135275 +{
135276 + u16 ip_rev = 0;
135277 + u8 ip_cfg = QMAN_REV_CFG_0;
135278 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135279 + if (!of_device_is_available(dn))
135280 + continue;
135281 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
135282 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
135283 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
135284 + BUG_ON(1);
135285 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
135286 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
135287 + ip_rev = QMAN_REV11;
135288 + qman_portal_max = 10;
135289 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
135290 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
135291 + ip_rev = QMAN_REV12;
135292 + qman_portal_max = 10;
135293 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
135294 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
135295 + ip_rev = QMAN_REV20;
135296 + qman_portal_max = 3;
135297 + } else if (of_device_is_compatible(dn,
135298 + "fsl,qman-portal-3.0.0")) {
135299 + ip_rev = QMAN_REV30;
135300 + qman_portal_max = 50;
135301 + } else if (of_device_is_compatible(dn,
135302 + "fsl,qman-portal-3.0.1")) {
135303 + ip_rev = QMAN_REV30;
135304 + qman_portal_max = 25;
135305 + ip_cfg = QMAN_REV_CFG_1;
135306 + } else if (of_device_is_compatible(dn,
135307 + "fsl,qman-portal-3.1.0")) {
135308 + ip_rev = QMAN_REV31;
135309 + qman_portal_max = 50;
135310 + } else if (of_device_is_compatible(dn,
135311 + "fsl,qman-portal-3.1.1")) {
135312 + ip_rev = QMAN_REV31;
135313 + qman_portal_max = 25;
135314 + ip_cfg = QMAN_REV_CFG_1;
135315 + } else if (of_device_is_compatible(dn,
135316 + "fsl,qman-portal-3.1.2")) {
135317 + ip_rev = QMAN_REV31;
135318 + qman_portal_max = 18;
135319 + ip_cfg = QMAN_REV_CFG_2;
135320 + } else if (of_device_is_compatible(dn,
135321 + "fsl,qman-portal-3.1.3")) {
135322 + ip_rev = QMAN_REV31;
135323 + qman_portal_max = 10;
135324 + ip_cfg = QMAN_REV_CFG_3;
135325 + } else if (of_device_is_compatible(dn,
135326 + "fsl,qman-portal-3.2.0")) {
135327 + ip_rev = QMAN_REV32;
135328 + qman_portal_max = 10;
135329 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
135330 + } else if (of_device_is_compatible(dn,
135331 + "fsl,qman-portal-3.2.1")) {
135332 + ip_rev = QMAN_REV32;
135333 + qman_portal_max = 10;
135334 + ip_cfg = QMAN_REV_CFG_3;
135335 + } else {
135336 + pr_warn("unknown QMan version in portal node,"
135337 + "default to rev1.1\n");
135338 + ip_rev = QMAN_REV11;
135339 + qman_portal_max = 10;
135340 + }
135341 +
135342 + if (!qman_ip_rev) {
135343 + if (ip_rev) {
135344 + qman_ip_rev = ip_rev;
135345 + qman_ip_cfg = ip_cfg;
135346 + } else {
135347 + pr_warn("unknown Qman version,"
135348 + " default to rev1.1\n");
135349 + qman_ip_rev = QMAN_REV11;
135350 + qman_ip_cfg = QMAN_REV_CFG_0;
135351 + }
135352 + } else if (ip_rev && (qman_ip_rev != ip_rev))
135353 + pr_warn("Revision=0x%04x, but portal '%s' has"
135354 + " 0x%04x\n",
135355 + qman_ip_rev, dn->full_name, ip_rev);
135356 + if (qman_ip_rev == ip_rev)
135357 + break;
135358 + }
135359 +}
135360 +
135361 +/* Parse a portal node, perform generic mapping duties and return the config. It
135362 + * is not known at this stage for what purpose (or even if) the portal will be
135363 + * used. */
135364 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
135365 +{
135366 + struct qm_portal_config *pcfg;
135367 + const u32 *index_p;
135368 + u32 index, channel;
135369 + int irq, ret;
135370 + resource_size_t len;
135371 +
135372 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
135373 + if (!pcfg) {
135374 + pr_err("can't allocate portal config");
135375 + return NULL;
135376 + }
135377 +
135378 + /*
135379 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
135380 + * 'struct device' in order to get the PAMU stashing setup and the QMan
135381 + * portal [driver] won't function at all without ring stashing
135382 + *
135383 + * Making the QMan portal driver nice and proper is part of the
135384 + * upstreaming effort
135385 + */
135386 + pcfg->dev.bus = &platform_bus_type;
135387 + pcfg->dev.of_node = node;
135388 +#ifdef CONFIG_FSL_PAMU
135389 + pcfg->dev.archdata.iommu_domain = NULL;
135390 +#endif
135391 +
135392 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
135393 + &pcfg->addr_phys[DPA_PORTAL_CE]);
135394 + if (ret) {
135395 + pr_err("Can't get %s property '%s'\n", node->full_name,
135396 + "reg::CE");
135397 + goto err;
135398 + }
135399 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
135400 + &pcfg->addr_phys[DPA_PORTAL_CI]);
135401 + if (ret) {
135402 + pr_err("Can't get %s property '%s'\n", node->full_name,
135403 + "reg::CI");
135404 + goto err;
135405 + }
135406 + index_p = of_get_property(node, "cell-index", &ret);
135407 + if (!index_p || (ret != 4)) {
135408 + pr_err("Can't get %s property '%s'\n", node->full_name,
135409 + "cell-index");
135410 + goto err;
135411 + }
135412 + index = be32_to_cpu(*index_p);
135413 + if (index >= qman_portal_max) {
135414 + pr_err("QMan portal index %d is beyond max (%d)\n",
135415 + index, qman_portal_max);
135416 + goto err;
135417 + }
135418 +
135419 + channel = index + QM_CHANNEL_SWPORTAL0;
135420 + pcfg->public_cfg.channel = channel;
135421 + pcfg->public_cfg.cpu = -1;
135422 + irq = irq_of_parse_and_map(node, 0);
135423 + if (irq == 0) {
135424 + pr_err("Can't get %s property '%s'\n", node->full_name,
135425 + "interrupts");
135426 + goto err;
135427 + }
135428 + pcfg->public_cfg.irq = irq;
135429 + pcfg->public_cfg.index = index;
135430 +#ifdef CONFIG_FSL_QMAN_CONFIG
135431 + /* We need the same LIODN offset for all portals */
135432 + qman_liodn_fixup(pcfg->public_cfg.channel);
135433 +#endif
135434 +
135435 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
135436 + if (len != (unsigned long)len)
135437 + goto err;
135438 +
135439 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
135440 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
135441 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135442 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
135443 +
135444 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
135445 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135446 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
135447 +#else
135448 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
135449 + pcfg->addr_phys[DPA_PORTAL_CE].start,
135450 + (unsigned long)len,
135451 + 0);
135452 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
135453 + pcfg->addr_phys[DPA_PORTAL_CI].start,
135454 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
135455 + _PAGE_GUARDED | _PAGE_NO_CACHE);
135456 +#endif
135457 + return pcfg;
135458 +err:
135459 + kfree(pcfg);
135460 + return NULL;
135461 +}
135462 +
135463 +static struct qm_portal_config *get_pcfg(struct list_head *list)
135464 +{
135465 + struct qm_portal_config *pcfg;
135466 + if (list_empty(list))
135467 + return NULL;
135468 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
135469 + list_del(&pcfg->list);
135470 + return pcfg;
135471 +}
135472 +
135473 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
135474 +{
135475 + struct qm_portal_config *pcfg;
135476 + if (list_empty(list))
135477 + return NULL;
135478 + list_for_each_entry(pcfg, list, list) {
135479 + if (pcfg->public_cfg.index == idx) {
135480 + list_del(&pcfg->list);
135481 + return pcfg;
135482 + }
135483 + }
135484 + return NULL;
135485 +}
135486 +
135487 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
135488 +{
135489 +#ifdef CONFIG_FSL_PAMU
135490 + int ret;
135491 + int window_count = 1;
135492 + struct iommu_domain_geometry geom_attr;
135493 + struct pamu_stash_attribute stash_attr;
135494 +
135495 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
135496 + if (!pcfg->iommu_domain) {
135497 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
135498 + __func__);
135499 + goto _no_iommu;
135500 + }
135501 + geom_attr.aperture_start = 0;
135502 + geom_attr.aperture_end =
135503 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
135504 + geom_attr.force_aperture = true;
135505 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
135506 + &geom_attr);
135507 + if (ret < 0) {
135508 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135509 + __func__, ret);
135510 + goto _iommu_domain_free;
135511 + }
135512 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
135513 + &window_count);
135514 + if (ret < 0) {
135515 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135516 + __func__, ret);
135517 + goto _iommu_domain_free;
135518 + }
135519 + stash_attr.cpu = cpu;
135520 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135521 + /* set stash information for the window */
135522 + stash_attr.window = 0;
135523 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135524 + DOMAIN_ATTR_FSL_PAMU_STASH,
135525 + &stash_attr);
135526 + if (ret < 0) {
135527 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135528 + __func__, ret);
135529 + goto _iommu_domain_free;
135530 + }
135531 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
135532 + IOMMU_READ | IOMMU_WRITE);
135533 + if (ret < 0) {
135534 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
135535 + __func__, ret);
135536 + goto _iommu_domain_free;
135537 + }
135538 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
135539 + if (ret < 0) {
135540 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
135541 + __func__, ret);
135542 + goto _iommu_domain_free;
135543 + }
135544 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135545 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
135546 + &window_count);
135547 + if (ret < 0) {
135548 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
135549 + __func__, ret);
135550 + goto _iommu_detach_device;
135551 + }
135552 +
135553 +_no_iommu:
135554 +#endif
135555 +#ifdef CONFIG_FSL_QMAN_CONFIG
135556 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135557 +#endif
135558 + pr_warn("Failed to set QMan portal's stash request queue\n");
135559 +
135560 + return;
135561 +
135562 +#ifdef CONFIG_FSL_PAMU
135563 +_iommu_detach_device:
135564 + iommu_detach_device(pcfg->iommu_domain, NULL);
135565 +_iommu_domain_free:
135566 + iommu_domain_free(pcfg->iommu_domain);
135567 +#endif
135568 +}
135569 +
135570 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
135571 +{
135572 + struct qm_portal_config *ret;
135573 + spin_lock(&unused_pcfgs_lock);
135574 + if (idx == QBMAN_ANY_PORTAL_IDX)
135575 + ret = get_pcfg(&unused_pcfgs);
135576 + else
135577 + ret = get_pcfg_idx(&unused_pcfgs, idx);
135578 + spin_unlock(&unused_pcfgs_lock);
135579 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
135580 + * set the portal to use the stashing request queue corresonding to the
135581 + * cpu as well. The user-space driver assumption is that the pthread has
135582 + * to already be affine to one cpu only before opening a portal. If that
135583 + * check is circumvented, the only risk is a performance degradation -
135584 + * stashing will go to whatever cpu they happened to be running on when
135585 + * opening the device file, and if that isn't the cpu they subsequently
135586 + * bind to and do their polling on, tough. */
135587 + if (ret)
135588 + portal_set_cpu(ret, hard_smp_processor_id());
135589 + return ret;
135590 +}
135591 +
135592 +struct qm_portal_config *qm_get_unused_portal(void)
135593 +{
135594 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
135595 +}
135596 +
135597 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
135598 +{
135599 + spin_lock(&unused_pcfgs_lock);
135600 + list_add(&pcfg->list, &unused_pcfgs);
135601 + spin_unlock(&unused_pcfgs_lock);
135602 +}
135603 +
135604 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
135605 +{
135606 + struct qman_portal *p;
135607 +
135608 + pcfg->iommu_domain = NULL;
135609 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
135610 + p = qman_create_affine_portal(pcfg, NULL);
135611 + if (p) {
135612 + u32 irq_sources = 0;
135613 + /* Determine what should be interrupt-vs-poll driven */
135614 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
135615 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
135616 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
135617 +#endif
135618 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
135619 + irq_sources |= QM_PIRQ_DQRI;
135620 +#endif
135621 + qman_p_irqsource_add(p, irq_sources);
135622 + pr_info("Qman portal %sinitialised, cpu %d\n",
135623 + pcfg->public_cfg.is_shared ? "(shared) " : "",
135624 + pcfg->public_cfg.cpu);
135625 + } else
135626 + pr_crit("Qman portal failure on cpu %d\n",
135627 + pcfg->public_cfg.cpu);
135628 + return p;
135629 +}
135630 +
135631 +static void init_slave(int cpu)
135632 +{
135633 + struct qman_portal *p;
135634 + struct cpumask oldmask = current->cpus_allowed;
135635 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
135636 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
135637 + if (!p)
135638 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
135639 + else
135640 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
135641 + set_cpus_allowed_ptr(current, &oldmask);
135642 + if (shared_portals_idx >= num_shared_portals)
135643 + shared_portals_idx = 0;
135644 +}
135645 +
135646 +static struct cpumask want_unshared __initdata;
135647 +static struct cpumask want_shared __initdata;
135648 +
135649 +static int __init parse_qportals(char *str)
135650 +{
135651 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
135652 + "qportals");
135653 +}
135654 +__setup("qportals=", parse_qportals);
135655 +
135656 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
135657 + unsigned int cpu)
135658 +{
135659 +#ifdef CONFIG_FSL_PAMU
135660 + struct pamu_stash_attribute stash_attr;
135661 + int ret;
135662 +
135663 + if (pcfg->iommu_domain) {
135664 + stash_attr.cpu = cpu;
135665 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
135666 + /* set stash information for the window */
135667 + stash_attr.window = 0;
135668 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
135669 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
135670 + if (ret < 0) {
135671 + pr_err("Failed to update pamu stash setting\n");
135672 + return;
135673 + }
135674 + }
135675 +#endif
135676 +#ifdef CONFIG_FSL_QMAN_CONFIG
135677 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
135678 + pr_warn("Failed to update portal's stash request queue\n");
135679 +#endif
135680 +}
135681 +
135682 +static int qman_offline_cpu(unsigned int cpu)
135683 +{
135684 + struct qman_portal *p;
135685 + const struct qm_portal_config *pcfg;
135686 + p = (struct qman_portal *)affine_portals[cpu];
135687 + if (p) {
135688 + pcfg = qman_get_qm_portal_config(p);
135689 + if (pcfg) {
135690 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
135691 + qman_portal_update_sdest(pcfg, 0);
135692 + }
135693 + }
135694 + return 0;
135695 +}
135696 +
135697 +#ifdef CONFIG_HOTPLUG_CPU
135698 +static int qman_online_cpu(unsigned int cpu)
135699 +{
135700 + struct qman_portal *p;
135701 + const struct qm_portal_config *pcfg;
135702 + p = (struct qman_portal *)affine_portals[cpu];
135703 + if (p) {
135704 + pcfg = qman_get_qm_portal_config(p);
135705 + if (pcfg) {
135706 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
135707 + qman_portal_update_sdest(pcfg, cpu);
135708 + }
135709 + }
135710 + return 0;
135711 +}
135712 +
135713 +static int qman_hotplug_cpu_callback(struct notifier_block *nfb,
135714 + unsigned long action, void *hcpu)
135715 +{
135716 + unsigned int cpu = (unsigned long)hcpu;
135717 +
135718 + switch (action) {
135719 + case CPU_ONLINE:
135720 + case CPU_ONLINE_FROZEN:
135721 + qman_online_cpu(cpu);
135722 + break;
135723 + case CPU_DOWN_PREPARE:
135724 + case CPU_DOWN_PREPARE_FROZEN:
135725 + qman_offline_cpu(cpu);
135726 + default:
135727 + break;
135728 + }
135729 + return NOTIFY_OK;
135730 +}
135731 +
135732 +static struct notifier_block qman_hotplug_cpu_notifier = {
135733 + .notifier_call = qman_hotplug_cpu_callback,
135734 +};
135735 +#endif /* CONFIG_HOTPLUG_CPU */
135736 +
135737 +__init int qman_init(void)
135738 +{
135739 + struct cpumask slave_cpus;
135740 + struct cpumask unshared_cpus = *cpu_none_mask;
135741 + struct cpumask shared_cpus = *cpu_none_mask;
135742 + LIST_HEAD(unshared_pcfgs);
135743 + LIST_HEAD(shared_pcfgs);
135744 + struct device_node *dn;
135745 + struct qm_portal_config *pcfg;
135746 + struct qman_portal *p;
135747 + int cpu, ret;
135748 + const u32 *clk;
135749 + struct cpumask offline_cpus;
135750 +
135751 + /* Initialise the Qman (CCSR) device */
135752 + for_each_compatible_node(dn, NULL, "fsl,qman") {
135753 + if (!qman_init_ccsr(dn))
135754 + pr_info("Qman err interrupt handler present\n");
135755 + else
135756 + pr_err("Qman CCSR setup failed\n");
135757 +
135758 + clk = of_get_property(dn, "clock-frequency", NULL);
135759 + if (!clk)
135760 + pr_warn("Can't find Qman clock frequency\n");
135761 + else
135762 + qman_clk = be32_to_cpu(*clk);
135763 + }
135764 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
135765 + /* Setup lookup table for FQ demux */
135766 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
135767 + if (ret)
135768 + return ret;
135769 +#endif
135770 +
135771 + /* Get qman ip revision */
135772 + qman_get_ip_revision(dn);
135773 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
135774 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
135775 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
135776 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
135777 + }
135778 +
135779 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
135780 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
135781 +
135782 + /*
135783 + * Parse the ceetm node to get how many ceetm instances are supported
135784 + * on the current silicon. num_ceetms must be confirmed before portals
135785 + * are intiailized.
135786 + */
135787 + num_ceetms = 0;
135788 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
135789 + num_ceetms++;
135790 +
135791 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
135792 + * are initialised.) */
135793 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135794 + ret = fsl_pool_channel_range_sdqcr(dn);
135795 + if (ret)
135796 + return ret;
135797 + }
135798 +
135799 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
135800 + /* Initialise portals. See bman_driver.c for comments */
135801 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
135802 + if (!of_device_is_available(dn))
135803 + continue;
135804 + pcfg = parse_pcfg(dn);
135805 + if (pcfg) {
135806 + pcfg->public_cfg.pools = pools_sdqcr;
135807 + list_add_tail(&pcfg->list, &unused_pcfgs);
135808 + }
135809 + }
135810 + for_each_possible_cpu(cpu) {
135811 + if (cpumask_test_cpu(cpu, &want_shared)) {
135812 + pcfg = get_pcfg(&unused_pcfgs);
135813 + if (!pcfg)
135814 + break;
135815 + pcfg->public_cfg.cpu = cpu;
135816 + list_add_tail(&pcfg->list, &shared_pcfgs);
135817 + cpumask_set_cpu(cpu, &shared_cpus);
135818 + }
135819 + if (cpumask_test_cpu(cpu, &want_unshared)) {
135820 + if (cpumask_test_cpu(cpu, &shared_cpus))
135821 + continue;
135822 + pcfg = get_pcfg(&unused_pcfgs);
135823 + if (!pcfg)
135824 + break;
135825 + pcfg->public_cfg.cpu = cpu;
135826 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135827 + cpumask_set_cpu(cpu, &unshared_cpus);
135828 + }
135829 + }
135830 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
135831 + for_each_online_cpu(cpu) {
135832 + pcfg = get_pcfg(&unused_pcfgs);
135833 + if (!pcfg)
135834 + break;
135835 + pcfg->public_cfg.cpu = cpu;
135836 + list_add_tail(&pcfg->list, &unshared_pcfgs);
135837 + cpumask_set_cpu(cpu, &unshared_cpus);
135838 + }
135839 + }
135840 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
135841 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
135842 + if (cpumask_empty(&slave_cpus)) {
135843 + if (!list_empty(&shared_pcfgs)) {
135844 + cpumask_or(&unshared_cpus, &unshared_cpus,
135845 + &shared_cpus);
135846 + cpumask_clear(&shared_cpus);
135847 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
135848 + INIT_LIST_HEAD(&shared_pcfgs);
135849 + }
135850 + } else {
135851 + if (list_empty(&shared_pcfgs)) {
135852 + pcfg = get_pcfg(&unshared_pcfgs);
135853 + if (!pcfg) {
135854 + pr_crit("No QMan portals available!\n");
135855 + return 0;
135856 + }
135857 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
135858 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
135859 + list_add_tail(&pcfg->list, &shared_pcfgs);
135860 + }
135861 + }
135862 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
135863 + pcfg->public_cfg.is_shared = 0;
135864 + p = init_pcfg(pcfg);
135865 + if (!p) {
135866 + pr_crit("Unable to configure portals\n");
135867 + return 0;
135868 + }
135869 + }
135870 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
135871 + pcfg->public_cfg.is_shared = 1;
135872 + p = init_pcfg(pcfg);
135873 + if (p)
135874 + shared_portals[num_shared_portals++] = p;
135875 + }
135876 + if (!cpumask_empty(&slave_cpus))
135877 + for_each_cpu(cpu, &slave_cpus)
135878 + init_slave(cpu);
135879 + pr_info("Qman portals initialised\n");
135880 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
135881 + for_each_cpu(cpu, &offline_cpus)
135882 + qman_offline_cpu(cpu);
135883 +#ifdef CONFIG_HOTPLUG_CPU
135884 + register_hotcpu_notifier(&qman_hotplug_cpu_notifier);
135885 +#endif
135886 + return 0;
135887 +}
135888 +
135889 +__init int qman_resource_init(void)
135890 +{
135891 + struct device_node *dn;
135892 + int ret;
135893 +
135894 + /* Initialise FQID allocation ranges */
135895 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
135896 + ret = fsl_fqid_range_init(dn);
135897 + if (ret)
135898 + return ret;
135899 + }
135900 + /* Initialise CGRID allocation ranges */
135901 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
135902 + ret = fsl_cgrid_range_init(dn);
135903 + if (ret)
135904 + return ret;
135905 + }
135906 + /* Parse pool channels into the allocator. (Must happen after portals
135907 + * are initialised.) */
135908 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
135909 + ret = fsl_pool_channel_range_init(dn);
135910 + if (ret)
135911 + return ret;
135912 + }
135913 +
135914 + /* Parse CEETM */
135915 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
135916 + ret = fsl_ceetm_init(dn);
135917 + if (ret)
135918 + return ret;
135919 + }
135920 + return 0;
135921 +}
135922 +
135923 +#ifdef CONFIG_SUSPEND
135924 +void suspend_unused_qportal(void)
135925 +{
135926 + struct qm_portal_config *pcfg;
135927 +
135928 + if (list_empty(&unused_pcfgs))
135929 + return;
135930 +
135931 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135932 +#ifdef CONFIG_PM_DEBUG
135933 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
135934 +#endif
135935 + /* save isdr, disable all via isdr, clear isr */
135936 + pcfg->saved_isdr =
135937 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135938 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135939 + 0xe08);
135940 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
135941 + 0xe00);
135942 + }
135943 + return;
135944 +}
135945 +
135946 +void resume_unused_qportal(void)
135947 +{
135948 + struct qm_portal_config *pcfg;
135949 +
135950 + if (list_empty(&unused_pcfgs))
135951 + return;
135952 +
135953 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
135954 +#ifdef CONFIG_PM_DEBUG
135955 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
135956 +#endif
135957 + /* restore isdr */
135958 + __raw_writel(pcfg->saved_isdr,
135959 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
135960 + }
135961 + return;
135962 +}
135963 +#endif
135964 --- /dev/null
135965 +++ b/drivers/staging/fsl_qbman/qman_high.c
135966 @@ -0,0 +1,5652 @@
135967 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
135968 + *
135969 + * Redistribution and use in source and binary forms, with or without
135970 + * modification, are permitted provided that the following conditions are met:
135971 + * * Redistributions of source code must retain the above copyright
135972 + * notice, this list of conditions and the following disclaimer.
135973 + * * Redistributions in binary form must reproduce the above copyright
135974 + * notice, this list of conditions and the following disclaimer in the
135975 + * documentation and/or other materials provided with the distribution.
135976 + * * Neither the name of Freescale Semiconductor nor the
135977 + * names of its contributors may be used to endorse or promote products
135978 + * derived from this software without specific prior written permission.
135979 + *
135980 + *
135981 + * ALTERNATIVELY, this software may be distributed under the terms of the
135982 + * GNU General Public License ("GPL") as published by the Free Software
135983 + * Foundation, either version 2 of that License or (at your option) any
135984 + * later version.
135985 + *
135986 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135987 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135988 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135989 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135990 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135991 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135992 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135993 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135994 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135995 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135996 + */
135997 +
135998 +#include "qman_low.h"
135999 +
136000 +/* Compilation constants */
136001 +#define DQRR_MAXFILL 15
136002 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
136003 +#define IRQNAME "QMan portal %d"
136004 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
136005 +
136006 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
136007 + * positive, and rounding to the closest value if it's zero. NB, this macro
136008 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
136009 + * that are compatible with this. NB, these arguments should not be expressions
136010 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
136011 + * in "some_value++" as a parameter to the macro! */
136012 +#define ROUNDING(n, d, r) \
136013 + (((r) < 0) ? div64_u64((n), (d)) : \
136014 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
136015 + div64_u64(((n) + ((d) / 2)), (d))))
136016 +
136017 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
136018 + * inter-processor locking only. Note, FQLOCK() is always called either under a
136019 + * local_irq_save() or from interrupt context - hence there's no need for irq
136020 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
136021 + * the "irq en/disable" machinery isn't recursive...). */
136022 +#define FQLOCK(fq) \
136023 + do { \
136024 + struct qman_fq *__fq478 = (fq); \
136025 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136026 + spin_lock(&__fq478->fqlock); \
136027 + } while (0)
136028 +#define FQUNLOCK(fq) \
136029 + do { \
136030 + struct qman_fq *__fq478 = (fq); \
136031 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
136032 + spin_unlock(&__fq478->fqlock); \
136033 + } while (0)
136034 +
136035 +static inline void fq_set(struct qman_fq *fq, u32 mask)
136036 +{
136037 + set_bits(mask, &fq->flags);
136038 +}
136039 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
136040 +{
136041 + clear_bits(mask, &fq->flags);
136042 +}
136043 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
136044 +{
136045 + return fq->flags & mask;
136046 +}
136047 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
136048 +{
136049 + return !(fq->flags & mask);
136050 +}
136051 +
136052 +struct qman_portal {
136053 + struct qm_portal p;
136054 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
136055 + unsigned long irq_sources;
136056 + u32 use_eqcr_ci_stashing;
136057 + u32 slowpoll; /* only used when interrupts are off */
136058 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
136059 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136060 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
136061 +#endif
136062 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136063 + raw_spinlock_t sharing_lock; /* only used if is_shared */
136064 + int is_shared;
136065 + struct qman_portal *sharing_redirect;
136066 +#endif
136067 + u32 sdqcr;
136068 + int dqrr_disable_ref;
136069 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
136070 + * handler is called instead. */
136071 + qman_cb_dc_ern cb_dc_ern;
136072 + /* When the cpu-affine portal is activated, this is non-NULL */
136073 + const struct qm_portal_config *config;
136074 + /* This is needed for providing a non-NULL device to dma_map_***() */
136075 + struct platform_device *pdev;
136076 + struct dpa_rbtree retire_table;
136077 + char irqname[MAX_IRQNAME];
136078 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
136079 + struct qman_cgrs *cgrs;
136080 + /* linked-list of CSCN handlers. */
136081 + struct list_head cgr_cbs;
136082 + /* list lock */
136083 + spinlock_t cgr_lock;
136084 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
136085 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
136086 + /* 256-element array, each is a linked-list of CCSCN handlers. */
136087 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
136088 + /* list lock */
136089 + spinlock_t ccgr_lock;
136090 + /* track if memory was allocated by the driver */
136091 + u8 alloced;
136092 + /* power management data */
136093 + u32 save_isdr;
136094 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
136095 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
136096 + * do byte swaps of DQRR read only memory. First entry must be aligned
136097 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
136098 + * address (6 bits for address shift + 4 bits for the DQRR size).
136099 + */
136100 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
136101 +#endif
136102 +};
136103 +
136104 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136105 +#define PORTAL_IRQ_LOCK(p, irqflags) \
136106 + do { \
136107 + if ((p)->is_shared) \
136108 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
136109 + else \
136110 + local_irq_save(irqflags); \
136111 + } while (0)
136112 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
136113 + do { \
136114 + if ((p)->is_shared) \
136115 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
136116 + irqflags); \
136117 + else \
136118 + local_irq_restore(irqflags); \
136119 + } while (0)
136120 +#else
136121 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
136122 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
136123 +#endif
136124 +
136125 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
136126 + * not have a portal-specific handler. */
136127 +static qman_cb_dc_ern cb_dc_ern;
136128 +
136129 +static cpumask_t affine_mask;
136130 +static DEFINE_SPINLOCK(affine_mask_lock);
136131 +static u16 affine_channels[NR_CPUS];
136132 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
136133 +void *affine_portals[NR_CPUS];
136134 +
136135 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
136136 +static inline struct qman_portal *get_raw_affine_portal(void)
136137 +{
136138 + return &get_cpu_var(qman_affine_portal);
136139 +}
136140 +/* For ops that can redirect, this obtains the portal to use */
136141 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136142 +static inline struct qman_portal *get_affine_portal(void)
136143 +{
136144 + struct qman_portal *p = get_raw_affine_portal();
136145 + if (p->sharing_redirect)
136146 + return p->sharing_redirect;
136147 + return p;
136148 +}
136149 +#else
136150 +#define get_affine_portal() get_raw_affine_portal()
136151 +#endif
136152 +/* For every "get", there must be a "put" */
136153 +static inline void put_affine_portal(void)
136154 +{
136155 + put_cpu_var(qman_affine_portal);
136156 +}
136157 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
136158 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
136159 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
136160 + * context to remain as non-atomic during poll-triggered callbacks as it was
136161 + * when the poll API was first called (eg. NAPI), so we go out of our way in
136162 + * this case to not disable pre-emption. */
136163 +static inline struct qman_portal *get_poll_portal(void)
136164 +{
136165 + return &get_cpu_var(qman_affine_portal);
136166 +}
136167 +#define put_poll_portal()
136168 +
136169 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
136170 + * retirement notifications (the fact they are sometimes h/w-consumed means that
136171 + * contextB isn't always a s/w demux - and as we can't know which case it is
136172 + * when looking at the notification, we have to use the slow lookup for all of
136173 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
136174 + * (though at most one of them should be the consumer), so this table isn't for
136175 + * all FQs - FQs are added when retirement commands are issued, and removed when
136176 + * they complete, which also massively reduces the size of this table. */
136177 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
136178 +
136179 +/* This is what everything can wait on, even if it migrates to a different cpu
136180 + * to the one whose affine portal it is waiting on. */
136181 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
136182 +
136183 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
136184 +{
136185 + int ret = fqtree_push(&p->retire_table, fq);
136186 + if (ret)
136187 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
136188 + return ret;
136189 +}
136190 +
136191 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
136192 +{
136193 + fqtree_del(&p->retire_table, fq);
136194 +}
136195 +
136196 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
136197 +{
136198 + return fqtree_find(&p->retire_table, fqid);
136199 +}
136200 +
136201 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
136202 +static void **qman_fq_lookup_table;
136203 +static size_t qman_fq_lookup_table_size;
136204 +
136205 +int qman_setup_fq_lookup_table(size_t num_entries)
136206 +{
136207 + num_entries++;
136208 + /* Allocate 1 more entry since the first entry is not used */
136209 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
136210 + if (!qman_fq_lookup_table) {
136211 + pr_err("QMan: Could not allocate fq lookup table\n");
136212 + return -ENOMEM;
136213 + }
136214 + qman_fq_lookup_table_size = num_entries;
136215 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
136216 + qman_fq_lookup_table,
136217 + (unsigned long)qman_fq_lookup_table_size);
136218 + return 0;
136219 +}
136220 +
136221 +/* global structure that maintains fq object mapping */
136222 +static DEFINE_SPINLOCK(fq_hash_table_lock);
136223 +
136224 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
136225 +{
136226 + u32 i;
136227 +
136228 + spin_lock(&fq_hash_table_lock);
136229 + /* Can't use index zero because this has special meaning
136230 + * in context_b field. */
136231 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
136232 + if (qman_fq_lookup_table[i] == NULL) {
136233 + *entry = i;
136234 + qman_fq_lookup_table[i] = fq;
136235 + spin_unlock(&fq_hash_table_lock);
136236 + return 0;
136237 + }
136238 + }
136239 + spin_unlock(&fq_hash_table_lock);
136240 + return -ENOMEM;
136241 +}
136242 +
136243 +static void clear_fq_table_entry(u32 entry)
136244 +{
136245 + spin_lock(&fq_hash_table_lock);
136246 + BUG_ON(entry >= qman_fq_lookup_table_size);
136247 + qman_fq_lookup_table[entry] = NULL;
136248 + spin_unlock(&fq_hash_table_lock);
136249 +}
136250 +
136251 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
136252 +{
136253 + BUG_ON(entry >= qman_fq_lookup_table_size);
136254 + return qman_fq_lookup_table[entry];
136255 +}
136256 +#endif
136257 +
136258 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
136259 +{
136260 + /* Byteswap the FQD to HW format */
136261 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
136262 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
136263 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
136264 + fqd->context_b = cpu_to_be32(fqd->context_b);
136265 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
136266 +}
136267 +
136268 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
136269 +{
136270 + /* Byteswap the FQD to CPU format */
136271 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
136272 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
136273 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
136274 + fqd->context_b = be32_to_cpu(fqd->context_b);
136275 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
136276 +}
136277 +
136278 +/* Swap a 40 bit address */
136279 +static inline u64 cpu_to_be40(u64 in)
136280 +{
136281 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136282 + return in;
136283 +#else
136284 + u64 out = 0;
136285 + u8 *p = (u8 *) &out;
136286 + p[0] = in >> 32;
136287 + p[1] = in >> 24;
136288 + p[2] = in >> 16;
136289 + p[3] = in >> 8;
136290 + p[4] = in >> 0;
136291 + return out;
136292 +#endif
136293 +}
136294 +static inline u64 be40_to_cpu(u64 in)
136295 +{
136296 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136297 + return in;
136298 +#else
136299 + u64 out = 0;
136300 + u8 *pout = (u8 *) &out;
136301 + u8 *pin = (u8 *) &in;
136302 + pout[0] = pin[4];
136303 + pout[1] = pin[3];
136304 + pout[2] = pin[2];
136305 + pout[3] = pin[1];
136306 + pout[4] = pin[0];
136307 + return out;
136308 +#endif
136309 +}
136310 +
136311 +/* Swap a 24 bit value */
136312 +static inline u32 cpu_to_be24(u32 in)
136313 +{
136314 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136315 + return in;
136316 +#else
136317 + u32 out = 0;
136318 + u8 *p = (u8 *) &out;
136319 + p[0] = in >> 16;
136320 + p[1] = in >> 8;
136321 + p[2] = in >> 0;
136322 + return out;
136323 +#endif
136324 +}
136325 +
136326 +static inline u32 be24_to_cpu(u32 in)
136327 +{
136328 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136329 + return in;
136330 +#else
136331 + u32 out = 0;
136332 + u8 *pout = (u8 *) &out;
136333 + u8 *pin = (u8 *) &in;
136334 + pout[0] = pin[2];
136335 + pout[1] = pin[1];
136336 + pout[2] = pin[0];
136337 + return out;
136338 +#endif
136339 +}
136340 +
136341 +static inline u64 be48_to_cpu(u64 in)
136342 +{
136343 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
136344 + return in;
136345 +#else
136346 + u64 out = 0;
136347 + u8 *pout = (u8 *) &out;
136348 + u8 *pin = (u8 *) &in;
136349 +
136350 + pout[0] = pin[5];
136351 + pout[1] = pin[4];
136352 + pout[2] = pin[3];
136353 + pout[3] = pin[2];
136354 + pout[4] = pin[1];
136355 + pout[5] = pin[0];
136356 + return out;
136357 +#endif
136358 +}
136359 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
136360 +{
136361 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
136362 + fd->status = cpu_to_be32(fd->status);
136363 + fd->opaque = cpu_to_be32(fd->opaque);
136364 +}
136365 +
136366 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
136367 +{
136368 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
136369 + fd->status = be32_to_cpu(fd->status);
136370 + fd->opaque = be32_to_cpu(fd->opaque);
136371 +}
136372 +
136373 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
136374 +{
136375 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
136376 + cq_query->state = be16_to_cpu(cq_query->state);
136377 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
136378 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
136379 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
136380 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
136381 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
136382 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
136383 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
136384 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
136385 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
136386 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
136387 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
136388 +}
136389 +
136390 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
136391 +{
136392 + int i;
136393 +
136394 + ccgr_q->cm_query.cs_thres.hword =
136395 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
136396 + ccgr_q->cm_query.cs_thres_x.hword =
136397 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
136398 + ccgr_q->cm_query.td_thres.hword =
136399 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
136400 + ccgr_q->cm_query.wr_parm_g.word =
136401 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
136402 + ccgr_q->cm_query.wr_parm_y.word =
136403 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
136404 + ccgr_q->cm_query.wr_parm_r.word =
136405 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
136406 + ccgr_q->cm_query.cscn_targ_dcp =
136407 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
136408 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
136409 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
136410 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
136411 + ccgr_q->cm_query.cscn_targ_swp[i] =
136412 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
136413 +}
136414 +
136415 +/* In the case that slow- and fast-path handling are both done by qman_poll()
136416 + * (ie. because there is no interrupt handling), we ought to balance how often
136417 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
136418 + * sources, so we call the fast poll 'n' times before calling the slow poll
136419 + * once. The idle decrementer constant is used when the last slow-poll detected
136420 + * no work to do, and the busy decrementer constant when the last slow-poll had
136421 + * work to do. */
136422 +#define SLOW_POLL_IDLE 1000
136423 +#define SLOW_POLL_BUSY 10
136424 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
136425 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
136426 + unsigned int poll_limit);
136427 +
136428 +/* Portal interrupt handler */
136429 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
136430 +{
136431 + struct qman_portal *p = ptr;
136432 + /*
136433 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
136434 + * it could race against a Query Congestion State command also given
136435 + * as part of the handling of this interrupt source. We mustn't
136436 + * clear it a second time in this top-level function.
136437 + */
136438 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
136439 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
136440 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
136441 + /* DQRR-handling if it's interrupt-driven */
136442 + if (is & QM_PIRQ_DQRI)
136443 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
136444 + /* Handling of anything else that's interrupt-driven */
136445 + clear |= __poll_portal_slow(p, is);
136446 + qm_isr_status_clear(&p->p, clear);
136447 + return IRQ_HANDLED;
136448 +}
136449 +
136450 +/* This inner version is used privately by qman_create_affine_portal(), as well
136451 + * as by the exported qman_stop_dequeues(). */
136452 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
136453 +{
136454 + unsigned long irqflags __maybe_unused;
136455 + PORTAL_IRQ_LOCK(p, irqflags);
136456 + if (!(p->dqrr_disable_ref++))
136457 + qm_dqrr_set_maxfill(&p->p, 0);
136458 + PORTAL_IRQ_UNLOCK(p, irqflags);
136459 +}
136460 +
136461 +static int drain_mr_fqrni(struct qm_portal *p)
136462 +{
136463 + const struct qm_mr_entry *msg;
136464 +loop:
136465 + msg = qm_mr_current(p);
136466 + if (!msg) {
136467 + /* if MR was full and h/w had other FQRNI entries to produce, we
136468 + * need to allow it time to produce those entries once the
136469 + * existing entries are consumed. A worst-case situation
136470 + * (fully-loaded system) means h/w sequencers may have to do 3-4
136471 + * other things before servicing the portal's MR pump, each of
136472 + * which (if slow) may take ~50 qman cycles (which is ~200
136473 + * processor cycles). So rounding up and then multiplying this
136474 + * worst-case estimate by a factor of 10, just to be
136475 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
136476 + * one entry at a time, so h/w has an opportunity to produce new
136477 + * entries well before the ring has been fully consumed, so
136478 + * we're being *really* paranoid here. */
136479 + u64 now, then = mfatb();
136480 + do {
136481 + now = mfatb();
136482 + } while ((then + 10000) > now);
136483 + msg = qm_mr_current(p);
136484 + if (!msg)
136485 + return 0;
136486 + }
136487 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
136488 + /* We aren't draining anything but FQRNIs */
136489 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
136490 + return -1;
136491 + }
136492 + qm_mr_next(p);
136493 + qm_mr_cci_consume(p, 1);
136494 + goto loop;
136495 +}
136496 +
136497 +#ifdef CONFIG_SUSPEND
136498 +static int _qman_portal_suspend_noirq(struct device *dev)
136499 +{
136500 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136501 +#ifdef CONFIG_PM_DEBUG
136502 + struct platform_device *pdev = to_platform_device(dev);
136503 +#endif
136504 +
136505 + p->save_isdr = qm_isr_disable_read(&p->p);
136506 + qm_isr_disable_write(&p->p, 0xffffffff);
136507 + qm_isr_status_clear(&p->p, 0xffffffff);
136508 +#ifdef CONFIG_PM_DEBUG
136509 + pr_info("Suspend for %s\n", pdev->name);
136510 +#endif
136511 + return 0;
136512 +}
136513 +
136514 +static int _qman_portal_resume_noirq(struct device *dev)
136515 +{
136516 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
136517 +
136518 + /* restore isdr */
136519 + qm_isr_disable_write(&p->p, p->save_isdr);
136520 + return 0;
136521 +}
136522 +#else
136523 +#define _qman_portal_suspend_noirq NULL
136524 +#define _qman_portal_resume_noirq NULL
136525 +#endif
136526 +
136527 +struct dev_pm_domain qman_portal_device_pm_domain = {
136528 + .ops = {
136529 + USE_PLATFORM_PM_SLEEP_OPS
136530 + .suspend_noirq = _qman_portal_suspend_noirq,
136531 + .resume_noirq = _qman_portal_resume_noirq,
136532 + }
136533 +};
136534 +
136535 +struct qman_portal *qman_create_portal(
136536 + struct qman_portal *portal,
136537 + const struct qm_portal_config *config,
136538 + const struct qman_cgrs *cgrs)
136539 +{
136540 + struct qm_portal *__p;
136541 + char buf[16];
136542 + int ret;
136543 + u32 isdr;
136544 +
136545 + if (!portal) {
136546 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
136547 + if (!portal)
136548 + return portal;
136549 + portal->alloced = 1;
136550 + } else
136551 + portal->alloced = 0;
136552 +
136553 + __p = &portal->p;
136554 +
136555 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
136556 + /* PAMU is required for stashing */
136557 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
136558 + 1 : 0);
136559 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136560 + portal->use_eqcr_ci_stashing = 1;
136561 +#else
136562 + portal->use_eqcr_ci_stashing = 0;
136563 +#endif
136564 +
136565 + /* prep the low-level portal struct with the mapped addresses from the
136566 + * config, everything that follows depends on it and "config" is more
136567 + * for (de)reference... */
136568 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
136569 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
136570 + /*
136571 + * If CI-stashing is used, the current defaults use a threshold of 3,
136572 + * and stash with high-than-DQRR priority.
136573 + */
136574 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
136575 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
136576 + pr_err("Qman EQCR initialisation failed\n");
136577 + goto fail_eqcr;
136578 + }
136579 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
136580 + qm_dqrr_cdc, DQRR_MAXFILL)) {
136581 + pr_err("Qman DQRR initialisation failed\n");
136582 + goto fail_dqrr;
136583 + }
136584 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
136585 + pr_err("Qman MR initialisation failed\n");
136586 + goto fail_mr;
136587 + }
136588 + if (qm_mc_init(__p)) {
136589 + pr_err("Qman MC initialisation failed\n");
136590 + goto fail_mc;
136591 + }
136592 + if (qm_isr_init(__p)) {
136593 + pr_err("Qman ISR initialisation failed\n");
136594 + goto fail_isr;
136595 + }
136596 + /* static interrupt-gating controls */
136597 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
136598 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
136599 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
136600 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
136601 + if (!portal->cgrs)
136602 + goto fail_cgrs;
136603 + /* initial snapshot is no-depletion */
136604 + qman_cgrs_init(&portal->cgrs[1]);
136605 + if (cgrs)
136606 + portal->cgrs[0] = *cgrs;
136607 + else
136608 + /* if the given mask is NULL, assume all CGRs can be seen */
136609 + qman_cgrs_fill(&portal->cgrs[0]);
136610 + INIT_LIST_HEAD(&portal->cgr_cbs);
136611 + spin_lock_init(&portal->cgr_lock);
136612 + if (num_ceetms) {
136613 + for (ret = 0; ret < num_ceetms; ret++) {
136614 + portal->ccgrs[ret] = kmalloc(2 *
136615 + sizeof(struct qman_ccgrs), GFP_KERNEL);
136616 + if (!portal->ccgrs[ret])
136617 + goto fail_ccgrs;
136618 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
136619 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
136620 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
136621 + }
136622 + }
136623 + spin_lock_init(&portal->ccgr_lock);
136624 + portal->bits = 0;
136625 + portal->slowpoll = 0;
136626 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
136627 + portal->eqci_owned = NULL;
136628 +#endif
136629 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136630 + raw_spin_lock_init(&portal->sharing_lock);
136631 + portal->is_shared = config->public_cfg.is_shared;
136632 + portal->sharing_redirect = NULL;
136633 +#endif
136634 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
136635 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
136636 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
136637 + portal->dqrr_disable_ref = 0;
136638 + portal->cb_dc_ern = NULL;
136639 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
136640 + portal->pdev = platform_device_alloc(buf, -1);
136641 + if (!portal->pdev) {
136642 + pr_err("qman_portal - platform_device_alloc() failed\n");
136643 + goto fail_devalloc;
136644 + }
136645 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
136646 + portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
136647 + portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
136648 +#else
136649 + if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
136650 + pr_err("qman_portal - dma_set_mask() failed\n");
136651 + goto fail_devadd;
136652 + }
136653 +#endif
136654 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
136655 + portal->pdev->dev.platform_data = portal;
136656 + ret = platform_device_add(portal->pdev);
136657 + if (ret) {
136658 + pr_err("qman_portal - platform_device_add() failed\n");
136659 + goto fail_devadd;
136660 + }
136661 + dpa_rbtree_init(&portal->retire_table);
136662 + isdr = 0xffffffff;
136663 + qm_isr_disable_write(__p, isdr);
136664 + portal->irq_sources = 0;
136665 + qm_isr_enable_write(__p, portal->irq_sources);
136666 + qm_isr_status_clear(__p, 0xffffffff);
136667 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
136668 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
136669 + portal)) {
136670 + pr_err("request_irq() failed\n");
136671 + goto fail_irq;
136672 + }
136673 + if ((config->public_cfg.cpu != -1) &&
136674 + irq_can_set_affinity(config->public_cfg.irq) &&
136675 + irq_set_affinity(config->public_cfg.irq,
136676 + cpumask_of(config->public_cfg.cpu))) {
136677 + pr_err("irq_set_affinity() failed\n");
136678 + goto fail_affinity;
136679 + }
136680 +
136681 + /* Need EQCR to be empty before continuing */
136682 + isdr ^= QM_PIRQ_EQCI;
136683 + qm_isr_disable_write(__p, isdr);
136684 + ret = qm_eqcr_get_fill(__p);
136685 + if (ret) {
136686 + pr_err("Qman EQCR unclean\n");
136687 + goto fail_eqcr_empty;
136688 + }
136689 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
136690 + qm_isr_disable_write(__p, isdr);
136691 + if (qm_dqrr_current(__p) != NULL) {
136692 + pr_err("Qman DQRR unclean\n");
136693 + qm_dqrr_cdc_consume_n(__p, 0xffff);
136694 + }
136695 + if (qm_mr_current(__p) != NULL) {
136696 + /* special handling, drain just in case it's a few FQRNIs */
136697 + if (drain_mr_fqrni(__p)) {
136698 + const struct qm_mr_entry *e = qm_mr_current(__p);
136699 + /*
136700 + * Message ring cannot be empty no need to check
136701 + * qm_mr_current returned successfully
136702 + */
136703 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
136704 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
136705 + goto fail_dqrr_mr_empty;
136706 + }
136707 + }
136708 + /* Success */
136709 + portal->config = config;
136710 + qm_isr_disable_write(__p, 0);
136711 + qm_isr_uninhibit(__p);
136712 + /* Write a sane SDQCR */
136713 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
136714 + return portal;
136715 +fail_dqrr_mr_empty:
136716 +fail_eqcr_empty:
136717 +fail_affinity:
136718 + free_irq(config->public_cfg.irq, portal);
136719 +fail_irq:
136720 + platform_device_del(portal->pdev);
136721 +fail_devadd:
136722 + platform_device_put(portal->pdev);
136723 +fail_devalloc:
136724 + if (num_ceetms)
136725 + for (ret = 0; ret < num_ceetms; ret++)
136726 + kfree(portal->ccgrs[ret]);
136727 +fail_ccgrs:
136728 + kfree(portal->cgrs);
136729 +fail_cgrs:
136730 + qm_isr_finish(__p);
136731 +fail_isr:
136732 + qm_mc_finish(__p);
136733 +fail_mc:
136734 + qm_mr_finish(__p);
136735 +fail_mr:
136736 + qm_dqrr_finish(__p);
136737 +fail_dqrr:
136738 + qm_eqcr_finish(__p);
136739 +fail_eqcr:
136740 + if (portal->alloced)
136741 + kfree(portal);
136742 + return NULL;
136743 +}
136744 +
136745 +struct qman_portal *qman_create_affine_portal(
136746 + const struct qm_portal_config *config,
136747 + const struct qman_cgrs *cgrs)
136748 +{
136749 + struct qman_portal *res;
136750 + struct qman_portal *portal;
136751 +
136752 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
136753 + res = qman_create_portal(portal, config, cgrs);
136754 + if (res) {
136755 + spin_lock(&affine_mask_lock);
136756 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
136757 + affine_channels[config->public_cfg.cpu] =
136758 + config->public_cfg.channel;
136759 + affine_portals[config->public_cfg.cpu] = portal;
136760 + spin_unlock(&affine_mask_lock);
136761 + }
136762 + return res;
136763 +}
136764 +
136765 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
136766 + * these cases. */
136767 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
136768 + int cpu)
136769 +{
136770 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136771 + struct qman_portal *p;
136772 + p = &per_cpu(qman_affine_portal, cpu);
136773 + /* Check that we don't already have our own portal */
136774 + BUG_ON(p->config);
136775 + /* Check that we aren't already slaving to another portal */
136776 + BUG_ON(p->is_shared);
136777 + /* Check that 'redirect' is prepared to have us */
136778 + BUG_ON(!redirect->config->public_cfg.is_shared);
136779 + /* These are the only elements to initialise when redirecting */
136780 + p->irq_sources = 0;
136781 + p->sharing_redirect = redirect;
136782 + affine_portals[cpu] = p;
136783 + return p;
136784 +#else
136785 + BUG();
136786 + return NULL;
136787 +#endif
136788 +}
136789 +
136790 +void qman_destroy_portal(struct qman_portal *qm)
136791 +{
136792 + const struct qm_portal_config *pcfg;
136793 + int i;
136794 +
136795 + /* Stop dequeues on the portal */
136796 + qm_dqrr_sdqcr_set(&qm->p, 0);
136797 +
136798 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
136799 + * something related to QM_PIRQ_EQCI, this may need fixing.
136800 + * Also, due to the prefetching model used for CI updates in the enqueue
136801 + * path, this update will only invalidate the CI cacheline *after*
136802 + * working on it, so we need to call this twice to ensure a full update
136803 + * irrespective of where the enqueue processing was at when the teardown
136804 + * began. */
136805 + qm_eqcr_cce_update(&qm->p);
136806 + qm_eqcr_cce_update(&qm->p);
136807 + pcfg = qm->config;
136808 +
136809 + free_irq(pcfg->public_cfg.irq, qm);
136810 +
136811 + kfree(qm->cgrs);
136812 + if (num_ceetms)
136813 + for (i = 0; i < num_ceetms; i++)
136814 + kfree(qm->ccgrs[i]);
136815 + qm_isr_finish(&qm->p);
136816 + qm_mc_finish(&qm->p);
136817 + qm_mr_finish(&qm->p);
136818 + qm_dqrr_finish(&qm->p);
136819 + qm_eqcr_finish(&qm->p);
136820 +
136821 + platform_device_del(qm->pdev);
136822 + platform_device_put(qm->pdev);
136823 +
136824 + qm->config = NULL;
136825 + if (qm->alloced)
136826 + kfree(qm);
136827 +}
136828 +
136829 +const struct qm_portal_config *qman_destroy_affine_portal(void)
136830 +{
136831 + /* We don't want to redirect if we're a slave, use "raw" */
136832 + struct qman_portal *qm = get_raw_affine_portal();
136833 + const struct qm_portal_config *pcfg;
136834 + int cpu;
136835 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
136836 + if (qm->sharing_redirect) {
136837 + qm->sharing_redirect = NULL;
136838 + put_affine_portal();
136839 + return NULL;
136840 + }
136841 + qm->is_shared = 0;
136842 +#endif
136843 + pcfg = qm->config;
136844 + cpu = pcfg->public_cfg.cpu;
136845 +
136846 + qman_destroy_portal(qm);
136847 +
136848 + spin_lock(&affine_mask_lock);
136849 + cpumask_clear_cpu(cpu, &affine_mask);
136850 + spin_unlock(&affine_mask_lock);
136851 + put_affine_portal();
136852 + return pcfg;
136853 +}
136854 +
136855 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
136856 +{
136857 + return &p->config->public_cfg;
136858 +}
136859 +EXPORT_SYMBOL(qman_p_get_portal_config);
136860 +
136861 +const struct qman_portal_config *qman_get_portal_config(void)
136862 +{
136863 + struct qman_portal *p = get_affine_portal();
136864 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
136865 + put_affine_portal();
136866 + return ret;
136867 +}
136868 +EXPORT_SYMBOL(qman_get_portal_config);
136869 +
136870 +/* Inline helper to reduce nesting in __poll_portal_slow() */
136871 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
136872 + const struct qm_mr_entry *msg, u8 verb)
136873 +{
136874 + FQLOCK(fq);
136875 + switch (verb) {
136876 + case QM_MR_VERB_FQRL:
136877 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
136878 + fq_clear(fq, QMAN_FQ_STATE_ORL);
136879 + table_del_fq(p, fq);
136880 + break;
136881 + case QM_MR_VERB_FQRN:
136882 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
136883 + (fq->state == qman_fq_state_sched));
136884 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
136885 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
136886 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
136887 + fq_set(fq, QMAN_FQ_STATE_NE);
136888 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
136889 + fq_set(fq, QMAN_FQ_STATE_ORL);
136890 + else
136891 + table_del_fq(p, fq);
136892 + fq->state = qman_fq_state_retired;
136893 + break;
136894 + case QM_MR_VERB_FQPN:
136895 + DPA_ASSERT(fq->state == qman_fq_state_sched);
136896 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
136897 + fq->state = qman_fq_state_parked;
136898 + }
136899 + FQUNLOCK(fq);
136900 +}
136901 +
136902 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
136903 +{
136904 + const struct qm_mr_entry *msg;
136905 + struct qm_mr_entry swapped_msg;
136906 + int k;
136907 +
136908 + if (is & QM_PIRQ_CSCI) {
136909 + struct qman_cgrs rr, c;
136910 + struct qm_mc_result *mcr;
136911 + struct qman_cgr *cgr;
136912 + unsigned long irqflags __maybe_unused;
136913 +
136914 + spin_lock_irqsave(&p->cgr_lock, irqflags);
136915 + /*
136916 + * The CSCI bit must be cleared _before_ issuing the
136917 + * Query Congestion State command, to ensure that a long
136918 + * CGR State Change callback cannot miss an intervening
136919 + * state change.
136920 + */
136921 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
136922 + qm_mc_start(&p->p);
136923 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
136924 + while (!(mcr = qm_mc_result(&p->p)))
136925 + cpu_relax();
136926 + for (k = 0; k < 8; k++)
136927 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
136928 + mcr->querycongestion.state.__state[k]);
136929 + /* mask out the ones I'm not interested in */
136930 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
136931 + &mcr->querycongestion.state, &p->cgrs[0]);
136932 + /* check previous snapshot for delta, enter/exit congestion */
136933 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
136934 + /* update snapshot */
136935 + qman_cgrs_cp(&p->cgrs[1], &rr);
136936 + /* Invoke callback */
136937 + list_for_each_entry(cgr, &p->cgr_cbs, node)
136938 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
136939 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
136940 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
136941 + }
136942 + if (is & QM_PIRQ_CCSCI) {
136943 + struct qman_ccgrs rr, c, congestion_result;
136944 + struct qm_mc_result *mcr;
136945 + struct qm_mc_command *mcc;
136946 + struct qm_ceetm_ccg *ccg;
136947 + unsigned long irqflags __maybe_unused;
136948 + int i, j;
136949 +
136950 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
136951 + /*
136952 + * The CCSCI bit must be cleared _before_ issuing the
136953 + * Query Congestion State command, to ensure that a long
136954 + * CCGR State Change callback cannot miss an intervening
136955 + * state change.
136956 + */
136957 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
136958 +
136959 + for (i = 0; i < num_ceetms; i++) {
136960 + for (j = 0; j < 2; j++) {
136961 + mcc = qm_mc_start(&p->p);
136962 + mcc->ccgr_query.ccgrid = cpu_to_be16(
136963 + CEETM_QUERY_CONGESTION_STATE | j);
136964 + mcc->ccgr_query.dcpid = i;
136965 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
136966 + while (!(mcr = qm_mc_result(&p->p)))
136967 + cpu_relax();
136968 + for (k = 0; k < 8; k++)
136969 + mcr->ccgr_query.congestion_state.state.
136970 + __state[k] = be32_to_cpu(
136971 + mcr->ccgr_query.
136972 + congestion_state.state.
136973 + __state[k]);
136974 + congestion_result.q[j] =
136975 + mcr->ccgr_query.congestion_state.state;
136976 + }
136977 + /* mask out the ones I'm not interested in */
136978 + qman_ccgrs_and(&rr, &congestion_result,
136979 + &p->ccgrs[i][0]);
136980 + /*
136981 + * check previous snapshot for delta, enter/exit
136982 + * congestion.
136983 + */
136984 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
136985 + /* update snapshot */
136986 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
136987 + /* Invoke callback */
136988 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
136989 + if (ccg->cb && qman_ccgrs_get(&c,
136990 + (ccg->parent->idx << 4) | ccg->idx))
136991 + ccg->cb(ccg, ccg->cb_ctx,
136992 + qman_ccgrs_get(&rr,
136993 + (ccg->parent->idx << 4)
136994 + | ccg->idx));
136995 + }
136996 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
136997 + }
136998 +
136999 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137000 + if (is & QM_PIRQ_EQCI) {
137001 + unsigned long irqflags;
137002 + PORTAL_IRQ_LOCK(p, irqflags);
137003 + p->eqci_owned = NULL;
137004 + PORTAL_IRQ_UNLOCK(p, irqflags);
137005 + wake_up(&affine_queue);
137006 + }
137007 +#endif
137008 +
137009 + if (is & QM_PIRQ_EQRI) {
137010 + unsigned long irqflags __maybe_unused;
137011 + PORTAL_IRQ_LOCK(p, irqflags);
137012 + qm_eqcr_cce_update(&p->p);
137013 + qm_eqcr_set_ithresh(&p->p, 0);
137014 + PORTAL_IRQ_UNLOCK(p, irqflags);
137015 + wake_up(&affine_queue);
137016 + }
137017 +
137018 + if (is & QM_PIRQ_MRI) {
137019 + struct qman_fq *fq;
137020 + u8 verb, num = 0;
137021 +mr_loop:
137022 + qm_mr_pvb_update(&p->p);
137023 + msg = qm_mr_current(&p->p);
137024 + if (!msg)
137025 + goto mr_done;
137026 + swapped_msg = *msg;
137027 + hw_fd_to_cpu(&swapped_msg.ern.fd);
137028 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
137029 + /* The message is a software ERN iff the 0x20 bit is set */
137030 + if (verb & 0x20) {
137031 + switch (verb) {
137032 + case QM_MR_VERB_FQRNI:
137033 + /* nada, we drop FQRNIs on the floor */
137034 + break;
137035 + case QM_MR_VERB_FQRN:
137036 + case QM_MR_VERB_FQRL:
137037 + /* Lookup in the retirement table */
137038 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
137039 + BUG_ON(!fq);
137040 + fq_state_change(p, fq, &swapped_msg, verb);
137041 + if (fq->cb.fqs)
137042 + fq->cb.fqs(p, fq, &swapped_msg);
137043 + break;
137044 + case QM_MR_VERB_FQPN:
137045 + /* Parked */
137046 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137047 + fq = get_fq_table_entry(
137048 + be32_to_cpu(msg->fq.contextB));
137049 +#else
137050 + fq = (void *)(uintptr_t)
137051 + be32_to_cpu(msg->fq.contextB);
137052 +#endif
137053 + fq_state_change(p, fq, msg, verb);
137054 + if (fq->cb.fqs)
137055 + fq->cb.fqs(p, fq, &swapped_msg);
137056 + break;
137057 + case QM_MR_VERB_DC_ERN:
137058 + /* DCP ERN */
137059 + if (p->cb_dc_ern)
137060 + p->cb_dc_ern(p, msg);
137061 + else if (cb_dc_ern)
137062 + cb_dc_ern(p, msg);
137063 + else {
137064 + static int warn_once;
137065 + if (!warn_once) {
137066 + pr_crit("Leaking DCP ERNs!\n");
137067 + warn_once = 1;
137068 + }
137069 + }
137070 + break;
137071 + default:
137072 + pr_crit("Invalid MR verb 0x%02x\n", verb);
137073 + }
137074 + } else {
137075 + /* Its a software ERN */
137076 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137077 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
137078 +#else
137079 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
137080 +#endif
137081 + fq->cb.ern(p, fq, &swapped_msg);
137082 + }
137083 + num++;
137084 + qm_mr_next(&p->p);
137085 + goto mr_loop;
137086 +mr_done:
137087 + qm_mr_cci_consume(&p->p, num);
137088 + }
137089 + /*
137090 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
137091 + * processing. If that interrupt source has meanwhile been re-asserted,
137092 + * we mustn't clear it here (or in the top-level interrupt handler).
137093 + */
137094 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
137095 +}
137096 +
137097 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
137098 + * inlined. */
137099 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
137100 +{
137101 + p->vdqcr_owned = NULL;
137102 + FQLOCK(fq);
137103 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
137104 + FQUNLOCK(fq);
137105 + wake_up(&affine_queue);
137106 +}
137107 +
137108 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
137109 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
137110 + const struct qm_dqrr_entry *src)
137111 +{
137112 + int i = 0;
137113 + const u64 *s64 = (u64*)src;
137114 + u64 *d64 = (u64*)dst;
137115 +
137116 + /* DQRR only has 32 bytes of valid data so only need to
137117 + * copy 4 - 64 bit values */
137118 + *d64 = *s64;
137119 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137120 + {
137121 + u32 res, zero = 0;
137122 + /* Create a dependancy after copying first bytes ensures no wrap
137123 + transaction generated to QBMan */
137124 + /* Logical AND the value pointed to by s64 with 0x0 and
137125 + store the result in res */
137126 + asm volatile("and %[result], %[in1], %[in2]"
137127 + : [result] "=r" (res)
137128 + : [in1] "r" (zero), [in2] "r" (*s64)
137129 + : "memory");
137130 + /* Add res to s64 - this creates a dependancy on the result of
137131 + reading the value of s64 before the next read. The side
137132 + effect of this is that the core must stall until the first
137133 + aligned read is complete therefore preventing a WRAP
137134 + transaction to be seen by the QBMan */
137135 + asm volatile("add %[result], %[in1], %[in2]"
137136 + : [result] "=r" (s64)
137137 + : [in1] "r" (res), [in2] "r" (s64)
137138 + : "memory");
137139 + }
137140 +#endif
137141 + /* Copy the last 3 64 bit parts */
137142 + d64++; s64++;
137143 + for (;i<3; i++)
137144 + *d64++ = *s64++;
137145 +}
137146 +
137147 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
137148 + * that would conflict with other things if they ran at the same time on the
137149 + * same cpu are;
137150 + *
137151 + * (i) setting/clearing vdqcr_owned, and
137152 + * (ii) clearing the NE (Not Empty) flag.
137153 + *
137154 + * Both are safe. Because;
137155 + *
137156 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
137157 + * vdqcr_owned field (which it does before setting VDQCR), and
137158 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
137159 + * done so that we can't interfere.
137160 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
137161 + * with (i) that API prevents us from interfering until it's safe.
137162 + *
137163 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
137164 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
137165 + * advantage comes from this function not having to "lock" anything at all.
137166 + *
137167 + * Note also that the callbacks are invoked at points which are safe against the
137168 + * above potential conflicts, but that this function itself is not re-entrant
137169 + * (this is because the function tracks one end of each FIFO in the portal and
137170 + * we do *not* want to lock that). So the consequence is that it is safe for
137171 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
137172 + * sole API that could be invoking the callback through this function).
137173 + */
137174 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
137175 + unsigned int poll_limit)
137176 +{
137177 + const struct qm_dqrr_entry *dq;
137178 + struct qman_fq *fq;
137179 + enum qman_cb_dqrr_result res;
137180 + unsigned int limit = 0;
137181 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137182 + struct qm_dqrr_entry *shadow;
137183 + const struct qm_dqrr_entry *orig_dq;
137184 +#endif
137185 +loop:
137186 + qm_dqrr_pvb_update(&p->p);
137187 + dq = qm_dqrr_current(&p->p);
137188 + if (!dq)
137189 + goto done;
137190 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137191 + /* If running on an LE system the fields of the
137192 + dequeue entry must be swapped. Because the
137193 + QMan HW will ignore writes the DQRR entry is
137194 + copied and the index stored within the copy */
137195 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
137196 + /* Use safe copy here to avoid WRAP transaction */
137197 + safe_copy_dqrr(shadow, dq);
137198 + orig_dq = dq;
137199 + dq = shadow;
137200 + shadow->fqid = be32_to_cpu(shadow->fqid);
137201 + shadow->contextB = be32_to_cpu(shadow->contextB);
137202 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
137203 + hw_fd_to_cpu(&shadow->fd);
137204 +#endif
137205 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
137206 + /* VDQCR: don't trust contextB as the FQ may have been
137207 + * configured for h/w consumption and we're draining it
137208 + * post-retirement. */
137209 + fq = p->vdqcr_owned;
137210 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
137211 + * to check for clearing it when doing volatile dequeues. It's
137212 + * one less thing to check in the critical path (SDQCR). */
137213 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
137214 + fq_clear(fq, QMAN_FQ_STATE_NE);
137215 + /* this is duplicated from the SDQCR code, but we have stuff to
137216 + * do before *and* after this callback, and we don't want
137217 + * multiple if()s in the critical path (SDQCR). */
137218 + res = fq->cb.dqrr(p, fq, dq);
137219 + if (res == qman_cb_dqrr_stop)
137220 + goto done;
137221 + /* Check for VDQCR completion */
137222 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
137223 + clear_vdqcr(p, fq);
137224 + } else {
137225 + /* SDQCR: contextB points to the FQ */
137226 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137227 + fq = get_fq_table_entry(dq->contextB);
137228 +#else
137229 + fq = (void *)(uintptr_t)dq->contextB;
137230 +#endif
137231 + /* Now let the callback do its stuff */
137232 + res = fq->cb.dqrr(p, fq, dq);
137233 +
137234 + /* The callback can request that we exit without consuming this
137235 + * entry nor advancing; */
137236 + if (res == qman_cb_dqrr_stop)
137237 + goto done;
137238 + }
137239 + /* Interpret 'dq' from a driver perspective. */
137240 + /* Parking isn't possible unless HELDACTIVE was set. NB,
137241 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
137242 + * check for HELDACTIVE to cover both. */
137243 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
137244 + (res != qman_cb_dqrr_park));
137245 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137246 + if (res != qman_cb_dqrr_defer)
137247 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
137248 + (res == qman_cb_dqrr_park));
137249 +#else
137250 + /* Defer just means "skip it, I'll consume it myself later on" */
137251 + if (res != qman_cb_dqrr_defer)
137252 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
137253 +#endif
137254 + /* Move forward */
137255 + qm_dqrr_next(&p->p);
137256 + /* Entry processed and consumed, increment our counter. The callback can
137257 + * request that we exit after consuming the entry, and we also exit if
137258 + * we reach our processing limit, so loop back only if neither of these
137259 + * conditions is met. */
137260 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
137261 + goto loop;
137262 +done:
137263 + return limit;
137264 +}
137265 +
137266 +u32 qman_irqsource_get(void)
137267 +{
137268 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
137269 + * should shut the user out if they are not the primary CPU hosting the
137270 + * portal. That's why we use the "raw" interface. */
137271 + struct qman_portal *p = get_raw_affine_portal();
137272 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
137273 + put_affine_portal();
137274 + return ret;
137275 +}
137276 +EXPORT_SYMBOL(qman_irqsource_get);
137277 +
137278 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
137279 +{
137280 + __maybe_unused unsigned long irqflags;
137281 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137282 + if (p->sharing_redirect)
137283 + return -EINVAL;
137284 + else
137285 +#endif
137286 + {
137287 + bits = bits & QM_PIRQ_VISIBLE;
137288 + PORTAL_IRQ_LOCK(p, irqflags);
137289 +
137290 + /* Clear any previously remaining interrupt conditions in
137291 + * QCSP_ISR. This prevents raising a false interrupt when
137292 + * interrupt conditions are enabled in QCSP_IER.
137293 + */
137294 + qm_isr_status_clear(&p->p, bits);
137295 + set_bits(bits, &p->irq_sources);
137296 + qm_isr_enable_write(&p->p, p->irq_sources);
137297 + PORTAL_IRQ_UNLOCK(p, irqflags);
137298 + }
137299 + return 0;
137300 +}
137301 +EXPORT_SYMBOL(qman_p_irqsource_add);
137302 +
137303 +int qman_irqsource_add(u32 bits __maybe_unused)
137304 +{
137305 + struct qman_portal *p = get_raw_affine_portal();
137306 + int ret;
137307 + ret = qman_p_irqsource_add(p, bits);
137308 + put_affine_portal();
137309 + return ret;
137310 +}
137311 +EXPORT_SYMBOL(qman_irqsource_add);
137312 +
137313 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
137314 +{
137315 + __maybe_unused unsigned long irqflags;
137316 + u32 ier;
137317 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137318 + if (p->sharing_redirect) {
137319 + put_affine_portal();
137320 + return -EINVAL;
137321 + }
137322 +#endif
137323 + /* Our interrupt handler only processes+clears status register bits that
137324 + * are in p->irq_sources. As we're trimming that mask, if one of them
137325 + * were to assert in the status register just before we remove it from
137326 + * the enable register, there would be an interrupt-storm when we
137327 + * release the IRQ lock. So we wait for the enable register update to
137328 + * take effect in h/w (by reading it back) and then clear all other bits
137329 + * in the status register. Ie. we clear them from ISR once it's certain
137330 + * IER won't allow them to reassert. */
137331 + PORTAL_IRQ_LOCK(p, irqflags);
137332 + bits &= QM_PIRQ_VISIBLE;
137333 + clear_bits(bits, &p->irq_sources);
137334 + qm_isr_enable_write(&p->p, p->irq_sources);
137335 +
137336 + ier = qm_isr_enable_read(&p->p);
137337 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
137338 + * data-dependency, ie. to protect against re-ordering. */
137339 + qm_isr_status_clear(&p->p, ~ier);
137340 + PORTAL_IRQ_UNLOCK(p, irqflags);
137341 + return 0;
137342 +}
137343 +EXPORT_SYMBOL(qman_p_irqsource_remove);
137344 +
137345 +int qman_irqsource_remove(u32 bits)
137346 +{
137347 + struct qman_portal *p = get_raw_affine_portal();
137348 + int ret;
137349 + ret = qman_p_irqsource_remove(p, bits);
137350 + put_affine_portal();
137351 + return ret;
137352 +}
137353 +EXPORT_SYMBOL(qman_irqsource_remove);
137354 +
137355 +const cpumask_t *qman_affine_cpus(void)
137356 +{
137357 + return &affine_mask;
137358 +}
137359 +EXPORT_SYMBOL(qman_affine_cpus);
137360 +
137361 +u16 qman_affine_channel(int cpu)
137362 +{
137363 + if (cpu < 0) {
137364 + struct qman_portal *portal = get_raw_affine_portal();
137365 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137366 + BUG_ON(portal->sharing_redirect);
137367 +#endif
137368 + cpu = portal->config->public_cfg.cpu;
137369 + put_affine_portal();
137370 + }
137371 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
137372 + return affine_channels[cpu];
137373 +}
137374 +EXPORT_SYMBOL(qman_affine_channel);
137375 +
137376 +void *qman_get_affine_portal(int cpu)
137377 +{
137378 + return affine_portals[cpu];
137379 +}
137380 +EXPORT_SYMBOL(qman_get_affine_portal);
137381 +
137382 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
137383 +{
137384 + int ret;
137385 +
137386 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137387 + if (unlikely(p->sharing_redirect))
137388 + ret = -EINVAL;
137389 + else
137390 +#endif
137391 + {
137392 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
137393 + ret = __poll_portal_fast(p, limit);
137394 + }
137395 + return ret;
137396 +}
137397 +EXPORT_SYMBOL(qman_p_poll_dqrr);
137398 +
137399 +int qman_poll_dqrr(unsigned int limit)
137400 +{
137401 + struct qman_portal *p = get_poll_portal();
137402 + int ret;
137403 + ret = qman_p_poll_dqrr(p, limit);
137404 + put_poll_portal();
137405 + return ret;
137406 +}
137407 +EXPORT_SYMBOL(qman_poll_dqrr);
137408 +
137409 +u32 qman_p_poll_slow(struct qman_portal *p)
137410 +{
137411 + u32 ret;
137412 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137413 + if (unlikely(p->sharing_redirect))
137414 + ret = (u32)-1;
137415 + else
137416 +#endif
137417 + {
137418 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137419 + ret = __poll_portal_slow(p, is);
137420 + qm_isr_status_clear(&p->p, ret);
137421 + }
137422 + return ret;
137423 +}
137424 +EXPORT_SYMBOL(qman_p_poll_slow);
137425 +
137426 +u32 qman_poll_slow(void)
137427 +{
137428 + struct qman_portal *p = get_poll_portal();
137429 + u32 ret;
137430 + ret = qman_p_poll_slow(p);
137431 + put_poll_portal();
137432 + return ret;
137433 +}
137434 +EXPORT_SYMBOL(qman_poll_slow);
137435 +
137436 +/* Legacy wrapper */
137437 +void qman_p_poll(struct qman_portal *p)
137438 +{
137439 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137440 + if (unlikely(p->sharing_redirect))
137441 + return;
137442 +#endif
137443 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
137444 + if (!(p->slowpoll--)) {
137445 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
137446 + u32 active = __poll_portal_slow(p, is);
137447 + if (active) {
137448 + qm_isr_status_clear(&p->p, active);
137449 + p->slowpoll = SLOW_POLL_BUSY;
137450 + } else
137451 + p->slowpoll = SLOW_POLL_IDLE;
137452 + }
137453 + }
137454 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
137455 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
137456 +}
137457 +EXPORT_SYMBOL(qman_p_poll);
137458 +
137459 +void qman_poll(void)
137460 +{
137461 + struct qman_portal *p = get_poll_portal();
137462 + qman_p_poll(p);
137463 + put_poll_portal();
137464 +}
137465 +EXPORT_SYMBOL(qman_poll);
137466 +
137467 +void qman_p_stop_dequeues(struct qman_portal *p)
137468 +{
137469 + qman_stop_dequeues_ex(p);
137470 +}
137471 +EXPORT_SYMBOL(qman_p_stop_dequeues);
137472 +
137473 +void qman_stop_dequeues(void)
137474 +{
137475 + struct qman_portal *p = get_affine_portal();
137476 + qman_p_stop_dequeues(p);
137477 + put_affine_portal();
137478 +}
137479 +EXPORT_SYMBOL(qman_stop_dequeues);
137480 +
137481 +void qman_p_start_dequeues(struct qman_portal *p)
137482 +{
137483 + unsigned long irqflags __maybe_unused;
137484 + PORTAL_IRQ_LOCK(p, irqflags);
137485 + DPA_ASSERT(p->dqrr_disable_ref > 0);
137486 + if (!(--p->dqrr_disable_ref))
137487 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
137488 + PORTAL_IRQ_UNLOCK(p, irqflags);
137489 +}
137490 +EXPORT_SYMBOL(qman_p_start_dequeues);
137491 +
137492 +void qman_start_dequeues(void)
137493 +{
137494 + struct qman_portal *p = get_affine_portal();
137495 + qman_p_start_dequeues(p);
137496 + put_affine_portal();
137497 +}
137498 +EXPORT_SYMBOL(qman_start_dequeues);
137499 +
137500 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
137501 +{
137502 + unsigned long irqflags __maybe_unused;
137503 + PORTAL_IRQ_LOCK(p, irqflags);
137504 + pools &= p->config->public_cfg.pools;
137505 + p->sdqcr |= pools;
137506 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137507 + PORTAL_IRQ_UNLOCK(p, irqflags);
137508 +}
137509 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
137510 +
137511 +void qman_static_dequeue_add(u32 pools)
137512 +{
137513 + struct qman_portal *p = get_affine_portal();
137514 + qman_p_static_dequeue_add(p, pools);
137515 + put_affine_portal();
137516 +}
137517 +EXPORT_SYMBOL(qman_static_dequeue_add);
137518 +
137519 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
137520 +{
137521 + unsigned long irqflags __maybe_unused;
137522 + PORTAL_IRQ_LOCK(p, irqflags);
137523 + pools &= p->config->public_cfg.pools;
137524 + p->sdqcr &= ~pools;
137525 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
137526 + PORTAL_IRQ_UNLOCK(p, irqflags);
137527 +}
137528 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
137529 +
137530 +void qman_static_dequeue_del(u32 pools)
137531 +{
137532 + struct qman_portal *p = get_affine_portal();
137533 + qman_p_static_dequeue_del(p, pools);
137534 + put_affine_portal();
137535 +}
137536 +EXPORT_SYMBOL(qman_static_dequeue_del);
137537 +
137538 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
137539 +{
137540 + return p->sdqcr;
137541 +}
137542 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
137543 +
137544 +u32 qman_static_dequeue_get(void)
137545 +{
137546 + struct qman_portal *p = get_affine_portal();
137547 + u32 ret = qman_p_static_dequeue_get(p);
137548 + put_affine_portal();
137549 + return ret;
137550 +}
137551 +EXPORT_SYMBOL(qman_static_dequeue_get);
137552 +
137553 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
137554 + int park_request)
137555 +{
137556 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
137557 +}
137558 +EXPORT_SYMBOL(qman_p_dca);
137559 +
137560 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
137561 +{
137562 + struct qman_portal *p = get_affine_portal();
137563 + qman_p_dca(p, dq, park_request);
137564 + put_affine_portal();
137565 +}
137566 +EXPORT_SYMBOL(qman_dca);
137567 +
137568 +/*******************/
137569 +/* Frame queue API */
137570 +/*******************/
137571 +
137572 +static const char *mcr_result_str(u8 result)
137573 +{
137574 + switch (result) {
137575 + case QM_MCR_RESULT_NULL:
137576 + return "QM_MCR_RESULT_NULL";
137577 + case QM_MCR_RESULT_OK:
137578 + return "QM_MCR_RESULT_OK";
137579 + case QM_MCR_RESULT_ERR_FQID:
137580 + return "QM_MCR_RESULT_ERR_FQID";
137581 + case QM_MCR_RESULT_ERR_FQSTATE:
137582 + return "QM_MCR_RESULT_ERR_FQSTATE";
137583 + case QM_MCR_RESULT_ERR_NOTEMPTY:
137584 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
137585 + case QM_MCR_RESULT_PENDING:
137586 + return "QM_MCR_RESULT_PENDING";
137587 + case QM_MCR_RESULT_ERR_BADCOMMAND:
137588 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
137589 + }
137590 + return "<unknown MCR result>";
137591 +}
137592 +
137593 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
137594 +{
137595 + struct qm_fqd fqd;
137596 + struct qm_mcr_queryfq_np np;
137597 + struct qm_mc_command *mcc;
137598 + struct qm_mc_result *mcr;
137599 + struct qman_portal *p;
137600 + unsigned long irqflags __maybe_unused;
137601 +
137602 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
137603 + int ret = qman_alloc_fqid(&fqid);
137604 + if (ret)
137605 + return ret;
137606 + }
137607 + spin_lock_init(&fq->fqlock);
137608 + fq->fqid = fqid;
137609 + fq->flags = flags;
137610 + fq->state = qman_fq_state_oos;
137611 + fq->cgr_groupid = 0;
137612 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137613 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
137614 + return -ENOMEM;
137615 +#endif
137616 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
137617 + return 0;
137618 + /* Everything else is AS_IS support */
137619 + p = get_affine_portal();
137620 + PORTAL_IRQ_LOCK(p, irqflags);
137621 + mcc = qm_mc_start(&p->p);
137622 + mcc->queryfq.fqid = cpu_to_be32(fqid);
137623 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
137624 + while (!(mcr = qm_mc_result(&p->p)))
137625 + cpu_relax();
137626 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
137627 + if (mcr->result != QM_MCR_RESULT_OK) {
137628 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
137629 + goto err;
137630 + }
137631 + fqd = mcr->queryfq.fqd;
137632 + hw_fqd_to_cpu(&fqd);
137633 + mcc = qm_mc_start(&p->p);
137634 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
137635 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
137636 + while (!(mcr = qm_mc_result(&p->p)))
137637 + cpu_relax();
137638 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
137639 + if (mcr->result != QM_MCR_RESULT_OK) {
137640 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
137641 + goto err;
137642 + }
137643 + np = mcr->queryfq_np;
137644 + /* Phew, have queryfq and queryfq_np results, stitch together
137645 + * the FQ object from those. */
137646 + fq->cgr_groupid = fqd.cgid;
137647 + switch (np.state & QM_MCR_NP_STATE_MASK) {
137648 + case QM_MCR_NP_STATE_OOS:
137649 + break;
137650 + case QM_MCR_NP_STATE_RETIRED:
137651 + fq->state = qman_fq_state_retired;
137652 + if (np.frm_cnt)
137653 + fq_set(fq, QMAN_FQ_STATE_NE);
137654 + break;
137655 + case QM_MCR_NP_STATE_TEN_SCHED:
137656 + case QM_MCR_NP_STATE_TRU_SCHED:
137657 + case QM_MCR_NP_STATE_ACTIVE:
137658 + fq->state = qman_fq_state_sched;
137659 + if (np.state & QM_MCR_NP_STATE_R)
137660 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137661 + break;
137662 + case QM_MCR_NP_STATE_PARKED:
137663 + fq->state = qman_fq_state_parked;
137664 + break;
137665 + default:
137666 + DPA_ASSERT(NULL == "invalid FQ state");
137667 + }
137668 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
137669 + fq->state |= QMAN_FQ_STATE_CGR_EN;
137670 + PORTAL_IRQ_UNLOCK(p, irqflags);
137671 + put_affine_portal();
137672 + return 0;
137673 +err:
137674 + PORTAL_IRQ_UNLOCK(p, irqflags);
137675 + put_affine_portal();
137676 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
137677 + qman_release_fqid(fqid);
137678 + return -EIO;
137679 +}
137680 +EXPORT_SYMBOL(qman_create_fq);
137681 +
137682 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
137683 +{
137684 +
137685 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
137686 + * quiesced. Instead, run some checks. */
137687 + switch (fq->state) {
137688 + case qman_fq_state_parked:
137689 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
137690 + case qman_fq_state_oos:
137691 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
137692 + qman_release_fqid(fq->fqid);
137693 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137694 + clear_fq_table_entry(fq->key);
137695 +#endif
137696 + return;
137697 + default:
137698 + break;
137699 + }
137700 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
137701 +}
137702 +EXPORT_SYMBOL(qman_destroy_fq);
137703 +
137704 +u32 qman_fq_fqid(struct qman_fq *fq)
137705 +{
137706 + return fq->fqid;
137707 +}
137708 +EXPORT_SYMBOL(qman_fq_fqid);
137709 +
137710 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
137711 +{
137712 + if (state)
137713 + *state = fq->state;
137714 + if (flags)
137715 + *flags = fq->flags;
137716 +}
137717 +EXPORT_SYMBOL(qman_fq_state);
137718 +
137719 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
137720 +{
137721 + struct qm_mc_command *mcc;
137722 + struct qm_mc_result *mcr;
137723 + struct qman_portal *p;
137724 + unsigned long irqflags __maybe_unused;
137725 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137726 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
137727 +
137728 + if ((fq->state != qman_fq_state_oos) &&
137729 + (fq->state != qman_fq_state_parked))
137730 + return -EINVAL;
137731 +#ifdef CONFIG_FSL_DPA_CHECKING
137732 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137733 + return -EINVAL;
137734 +#endif
137735 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
137736 + /* And can't be set at the same time as TDTHRESH */
137737 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
137738 + return -EINVAL;
137739 + }
137740 + /* Issue an INITFQ_[PARKED|SCHED] management command */
137741 + p = get_affine_portal();
137742 + PORTAL_IRQ_LOCK(p, irqflags);
137743 + FQLOCK(fq);
137744 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137745 + ((fq->state != qman_fq_state_oos) &&
137746 + (fq->state != qman_fq_state_parked)))) {
137747 + FQUNLOCK(fq);
137748 + PORTAL_IRQ_UNLOCK(p, irqflags);
137749 + put_affine_portal();
137750 + return -EBUSY;
137751 + }
137752 + mcc = qm_mc_start(&p->p);
137753 + if (opts)
137754 + mcc->initfq = *opts;
137755 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
137756 + mcc->initfq.count = 0;
137757 +
137758 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
137759 + * demux pointer. Otherwise, the caller-provided value is allowed to
137760 + * stand, don't overwrite it. */
137761 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
137762 + dma_addr_t phys_fq;
137763 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
137764 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137765 + mcc->initfq.fqd.context_b = fq->key;
137766 +#else
137767 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
137768 +#endif
137769 + /* and the physical address - NB, if the user wasn't trying to
137770 + * set CONTEXTA, clear the stashing settings. */
137771 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
137772 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
137773 + memset(&mcc->initfq.fqd.context_a, 0,
137774 + sizeof(mcc->initfq.fqd.context_a));
137775 + } else {
137776 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
137777 + DMA_TO_DEVICE);
137778 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
137779 + }
137780 + }
137781 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
137782 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
137783 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
137784 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
137785 + mcc->initfq.fqd.dest.wq = 4;
137786 + }
137787 + }
137788 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
137789 + cpu_to_hw_fqd(&mcc->initfq.fqd);
137790 + qm_mc_commit(&p->p, myverb);
137791 + while (!(mcr = qm_mc_result(&p->p)))
137792 + cpu_relax();
137793 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
137794 + res = mcr->result;
137795 + if (res != QM_MCR_RESULT_OK) {
137796 + FQUNLOCK(fq);
137797 + PORTAL_IRQ_UNLOCK(p, irqflags);
137798 + put_affine_portal();
137799 + return -EIO;
137800 + }
137801 + if (opts) {
137802 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
137803 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
137804 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
137805 + else
137806 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
137807 + }
137808 + if (opts->we_mask & QM_INITFQ_WE_CGID)
137809 + fq->cgr_groupid = opts->fqd.cgid;
137810 + }
137811 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
137812 + qman_fq_state_sched : qman_fq_state_parked;
137813 + FQUNLOCK(fq);
137814 + PORTAL_IRQ_UNLOCK(p, irqflags);
137815 + put_affine_portal();
137816 + return 0;
137817 +}
137818 +EXPORT_SYMBOL(qman_init_fq);
137819 +
137820 +int qman_schedule_fq(struct qman_fq *fq)
137821 +{
137822 + struct qm_mc_command *mcc;
137823 + struct qm_mc_result *mcr;
137824 + struct qman_portal *p;
137825 + unsigned long irqflags __maybe_unused;
137826 + int ret = 0;
137827 + u8 res;
137828 +
137829 + if (fq->state != qman_fq_state_parked)
137830 + return -EINVAL;
137831 +#ifdef CONFIG_FSL_DPA_CHECKING
137832 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137833 + return -EINVAL;
137834 +#endif
137835 + /* Issue a ALTERFQ_SCHED management command */
137836 + p = get_affine_portal();
137837 + PORTAL_IRQ_LOCK(p, irqflags);
137838 + FQLOCK(fq);
137839 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137840 + (fq->state != qman_fq_state_parked))) {
137841 + ret = -EBUSY;
137842 + goto out;
137843 + }
137844 + mcc = qm_mc_start(&p->p);
137845 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137846 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
137847 + while (!(mcr = qm_mc_result(&p->p)))
137848 + cpu_relax();
137849 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
137850 + res = mcr->result;
137851 + if (res != QM_MCR_RESULT_OK) {
137852 + ret = -EIO;
137853 + goto out;
137854 + }
137855 + fq->state = qman_fq_state_sched;
137856 +out:
137857 + FQUNLOCK(fq);
137858 + PORTAL_IRQ_UNLOCK(p, irqflags);
137859 + put_affine_portal();
137860 + return ret;
137861 +}
137862 +EXPORT_SYMBOL(qman_schedule_fq);
137863 +
137864 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
137865 +{
137866 + struct qm_mc_command *mcc;
137867 + struct qm_mc_result *mcr;
137868 + struct qman_portal *p;
137869 + unsigned long irqflags __maybe_unused;
137870 + int rval;
137871 + u8 res;
137872 +
137873 + if ((fq->state != qman_fq_state_parked) &&
137874 + (fq->state != qman_fq_state_sched))
137875 + return -EINVAL;
137876 +#ifdef CONFIG_FSL_DPA_CHECKING
137877 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137878 + return -EINVAL;
137879 +#endif
137880 + p = get_affine_portal();
137881 + PORTAL_IRQ_LOCK(p, irqflags);
137882 + FQLOCK(fq);
137883 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
137884 + (fq->state == qman_fq_state_retired) ||
137885 + (fq->state == qman_fq_state_oos))) {
137886 + rval = -EBUSY;
137887 + goto out;
137888 + }
137889 + rval = table_push_fq(p, fq);
137890 + if (rval)
137891 + goto out;
137892 + mcc = qm_mc_start(&p->p);
137893 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137894 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
137895 + while (!(mcr = qm_mc_result(&p->p)))
137896 + cpu_relax();
137897 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
137898 + res = mcr->result;
137899 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
137900 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
137901 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
137902 + * friendly, otherwise the caller doesn't necessarily have a fully
137903 + * "retired" FQ on return even if the retirement was immediate. However
137904 + * this does mean some code duplication between here and
137905 + * fq_state_change(). */
137906 + if (likely(res == QM_MCR_RESULT_OK)) {
137907 + rval = 0;
137908 + /* Process 'fq' right away, we'll ignore FQRNI */
137909 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
137910 + fq_set(fq, QMAN_FQ_STATE_NE);
137911 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
137912 + fq_set(fq, QMAN_FQ_STATE_ORL);
137913 + else
137914 + table_del_fq(p, fq);
137915 + if (flags)
137916 + *flags = fq->flags;
137917 + fq->state = qman_fq_state_retired;
137918 + if (fq->cb.fqs) {
137919 + /* Another issue with supporting "immediate" retirement
137920 + * is that we're forced to drop FQRNIs, because by the
137921 + * time they're seen it may already be "too late" (the
137922 + * fq may have been OOS'd and free()'d already). But if
137923 + * the upper layer wants a callback whether it's
137924 + * immediate or not, we have to fake a "MR" entry to
137925 + * look like an FQRNI... */
137926 + struct qm_mr_entry msg;
137927 + msg.verb = QM_MR_VERB_FQRNI;
137928 + msg.fq.fqs = mcr->alterfq.fqs;
137929 + msg.fq.fqid = fq->fqid;
137930 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137931 + msg.fq.contextB = fq->key;
137932 +#else
137933 + msg.fq.contextB = (u32)(uintptr_t)fq;
137934 +#endif
137935 + fq->cb.fqs(p, fq, &msg);
137936 + }
137937 + } else if (res == QM_MCR_RESULT_PENDING) {
137938 + rval = 1;
137939 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
137940 + } else {
137941 + rval = -EIO;
137942 + table_del_fq(p, fq);
137943 + }
137944 +out:
137945 + FQUNLOCK(fq);
137946 + PORTAL_IRQ_UNLOCK(p, irqflags);
137947 + put_affine_portal();
137948 + return rval;
137949 +}
137950 +EXPORT_SYMBOL(qman_retire_fq);
137951 +
137952 +int qman_oos_fq(struct qman_fq *fq)
137953 +{
137954 + struct qm_mc_command *mcc;
137955 + struct qm_mc_result *mcr;
137956 + struct qman_portal *p;
137957 + unsigned long irqflags __maybe_unused;
137958 + int ret = 0;
137959 + u8 res;
137960 +
137961 + if (fq->state != qman_fq_state_retired)
137962 + return -EINVAL;
137963 +#ifdef CONFIG_FSL_DPA_CHECKING
137964 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
137965 + return -EINVAL;
137966 +#endif
137967 + p = get_affine_portal();
137968 + PORTAL_IRQ_LOCK(p, irqflags);
137969 + FQLOCK(fq);
137970 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
137971 + (fq->state != qman_fq_state_retired))) {
137972 + ret = -EBUSY;
137973 + goto out;
137974 + }
137975 + mcc = qm_mc_start(&p->p);
137976 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
137977 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
137978 + while (!(mcr = qm_mc_result(&p->p)))
137979 + cpu_relax();
137980 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
137981 + res = mcr->result;
137982 + if (res != QM_MCR_RESULT_OK) {
137983 + ret = -EIO;
137984 + goto out;
137985 + }
137986 + fq->state = qman_fq_state_oos;
137987 +out:
137988 + FQUNLOCK(fq);
137989 + PORTAL_IRQ_UNLOCK(p, irqflags);
137990 + put_affine_portal();
137991 + return ret;
137992 +}
137993 +EXPORT_SYMBOL(qman_oos_fq);
137994 +
137995 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
137996 +{
137997 + struct qm_mc_command *mcc;
137998 + struct qm_mc_result *mcr;
137999 + struct qman_portal *p;
138000 + unsigned long irqflags __maybe_unused;
138001 + int ret = 0;
138002 + u8 res;
138003 + u8 myverb;
138004 +
138005 + if ((fq->state == qman_fq_state_oos) ||
138006 + (fq->state == qman_fq_state_retired) ||
138007 + (fq->state == qman_fq_state_parked))
138008 + return -EINVAL;
138009 +
138010 +#ifdef CONFIG_FSL_DPA_CHECKING
138011 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
138012 + return -EINVAL;
138013 +#endif
138014 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
138015 + p = get_affine_portal();
138016 + PORTAL_IRQ_LOCK(p, irqflags);
138017 + FQLOCK(fq);
138018 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
138019 + (fq->state == qman_fq_state_parked) ||
138020 + (fq->state == qman_fq_state_oos) ||
138021 + (fq->state == qman_fq_state_retired))) {
138022 + ret = -EBUSY;
138023 + goto out;
138024 + }
138025 + mcc = qm_mc_start(&p->p);
138026 + mcc->alterfq.fqid = fq->fqid;
138027 + mcc->alterfq.count = 0;
138028 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
138029 +
138030 + qm_mc_commit(&p->p, myverb);
138031 + while (!(mcr = qm_mc_result(&p->p)))
138032 + cpu_relax();
138033 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138034 +
138035 + res = mcr->result;
138036 + if (res != QM_MCR_RESULT_OK) {
138037 + ret = -EIO;
138038 + goto out;
138039 + }
138040 +out:
138041 + FQUNLOCK(fq);
138042 + PORTAL_IRQ_UNLOCK(p, irqflags);
138043 + put_affine_portal();
138044 + return ret;
138045 +}
138046 +EXPORT_SYMBOL(qman_fq_flow_control);
138047 +
138048 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
138049 +{
138050 + struct qm_mc_command *mcc;
138051 + struct qm_mc_result *mcr;
138052 + struct qman_portal *p = get_affine_portal();
138053 + unsigned long irqflags __maybe_unused;
138054 + u8 res;
138055 +
138056 + PORTAL_IRQ_LOCK(p, irqflags);
138057 + mcc = qm_mc_start(&p->p);
138058 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138059 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
138060 + while (!(mcr = qm_mc_result(&p->p)))
138061 + cpu_relax();
138062 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
138063 + res = mcr->result;
138064 + if (res == QM_MCR_RESULT_OK)
138065 + *fqd = mcr->queryfq.fqd;
138066 + hw_fqd_to_cpu(fqd);
138067 + PORTAL_IRQ_UNLOCK(p, irqflags);
138068 + put_affine_portal();
138069 + if (res != QM_MCR_RESULT_OK)
138070 + return -EIO;
138071 + return 0;
138072 +}
138073 +EXPORT_SYMBOL(qman_query_fq);
138074 +
138075 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
138076 +{
138077 + struct qm_mc_command *mcc;
138078 + struct qm_mc_result *mcr;
138079 + struct qman_portal *p = get_affine_portal();
138080 + unsigned long irqflags __maybe_unused;
138081 + u8 res;
138082 +
138083 + PORTAL_IRQ_LOCK(p, irqflags);
138084 + mcc = qm_mc_start(&p->p);
138085 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
138086 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
138087 + while (!(mcr = qm_mc_result(&p->p)))
138088 + cpu_relax();
138089 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
138090 + res = mcr->result;
138091 + if (res == QM_MCR_RESULT_OK) {
138092 + *np = mcr->queryfq_np;
138093 + np->fqd_link = be24_to_cpu(np->fqd_link);
138094 + np->odp_seq = be16_to_cpu(np->odp_seq);
138095 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
138096 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
138097 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
138098 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
138099 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
138100 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
138101 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
138102 + np->ics_surp = be16_to_cpu(np->ics_surp);
138103 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
138104 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
138105 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
138106 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
138107 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
138108 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
138109 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
138110 + }
138111 + PORTAL_IRQ_UNLOCK(p, irqflags);
138112 + put_affine_portal();
138113 + if (res == QM_MCR_RESULT_ERR_FQID)
138114 + return -ERANGE;
138115 + else if (res != QM_MCR_RESULT_OK)
138116 + return -EIO;
138117 + return 0;
138118 +}
138119 +EXPORT_SYMBOL(qman_query_fq_np);
138120 +
138121 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
138122 +{
138123 + struct qm_mc_command *mcc;
138124 + struct qm_mc_result *mcr;
138125 + struct qman_portal *p = get_affine_portal();
138126 + unsigned long irqflags __maybe_unused;
138127 + u8 res, myverb;
138128 +
138129 + PORTAL_IRQ_LOCK(p, irqflags);
138130 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
138131 + QM_MCR_VERB_QUERYWQ;
138132 + mcc = qm_mc_start(&p->p);
138133 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
138134 + qm_mc_commit(&p->p, myverb);
138135 + while (!(mcr = qm_mc_result(&p->p)))
138136 + cpu_relax();
138137 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
138138 + res = mcr->result;
138139 + if (res == QM_MCR_RESULT_OK) {
138140 + int i, array_len;
138141 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
138142 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
138143 + for (i = 0; i < array_len; i++)
138144 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
138145 + }
138146 + PORTAL_IRQ_UNLOCK(p, irqflags);
138147 + put_affine_portal();
138148 + if (res != QM_MCR_RESULT_OK) {
138149 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
138150 + return -EIO;
138151 + }
138152 + return 0;
138153 +}
138154 +EXPORT_SYMBOL(qman_query_wq);
138155 +
138156 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
138157 + struct qm_mcr_cgrtestwrite *result)
138158 +{
138159 + struct qm_mc_command *mcc;
138160 + struct qm_mc_result *mcr;
138161 + struct qman_portal *p = get_affine_portal();
138162 + unsigned long irqflags __maybe_unused;
138163 + u8 res;
138164 +
138165 + PORTAL_IRQ_LOCK(p, irqflags);
138166 + mcc = qm_mc_start(&p->p);
138167 + mcc->cgrtestwrite.cgid = cgr->cgrid;
138168 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
138169 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
138170 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
138171 + while (!(mcr = qm_mc_result(&p->p)))
138172 + cpu_relax();
138173 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
138174 + res = mcr->result;
138175 + if (res == QM_MCR_RESULT_OK)
138176 + *result = mcr->cgrtestwrite;
138177 + PORTAL_IRQ_UNLOCK(p, irqflags);
138178 + put_affine_portal();
138179 + if (res != QM_MCR_RESULT_OK) {
138180 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
138181 + return -EIO;
138182 + }
138183 + return 0;
138184 +}
138185 +EXPORT_SYMBOL(qman_testwrite_cgr);
138186 +
138187 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
138188 +{
138189 + struct qm_mc_command *mcc;
138190 + struct qm_mc_result *mcr;
138191 + struct qman_portal *p = get_affine_portal();
138192 + unsigned long irqflags __maybe_unused;
138193 + u8 res;
138194 + int i;
138195 +
138196 + PORTAL_IRQ_LOCK(p, irqflags);
138197 + mcc = qm_mc_start(&p->p);
138198 + mcc->querycgr.cgid = cgr->cgrid;
138199 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
138200 + while (!(mcr = qm_mc_result(&p->p)))
138201 + cpu_relax();
138202 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
138203 + res = mcr->result;
138204 + if (res == QM_MCR_RESULT_OK)
138205 + *cgrd = mcr->querycgr;
138206 + PORTAL_IRQ_UNLOCK(p, irqflags);
138207 + put_affine_portal();
138208 + if (res != QM_MCR_RESULT_OK) {
138209 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
138210 + return -EIO;
138211 + }
138212 + cgrd->cgr.wr_parm_g.word =
138213 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
138214 + cgrd->cgr.wr_parm_y.word =
138215 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
138216 + cgrd->cgr.wr_parm_r.word =
138217 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
138218 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
138219 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
138220 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
138221 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
138222 + return 0;
138223 +}
138224 +EXPORT_SYMBOL(qman_query_cgr);
138225 +
138226 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
138227 +{
138228 + struct qm_mc_result *mcr;
138229 + struct qman_portal *p = get_affine_portal();
138230 + unsigned long irqflags __maybe_unused;
138231 + u8 res;
138232 + int i;
138233 +
138234 + PORTAL_IRQ_LOCK(p, irqflags);
138235 + qm_mc_start(&p->p);
138236 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138237 + while (!(mcr = qm_mc_result(&p->p)))
138238 + cpu_relax();
138239 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
138240 + QM_MCC_VERB_QUERYCONGESTION);
138241 + res = mcr->result;
138242 + if (res == QM_MCR_RESULT_OK)
138243 + memcpy_fromio(congestion, &mcr->querycongestion,
138244 + sizeof(*congestion));
138245 + PORTAL_IRQ_UNLOCK(p, irqflags);
138246 + put_affine_portal();
138247 + if (res != QM_MCR_RESULT_OK) {
138248 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
138249 + return -EIO;
138250 + }
138251 +
138252 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
138253 + be32_to_cpus(&congestion->state.__state[i]);
138254 + return 0;
138255 +}
138256 +EXPORT_SYMBOL(qman_query_congestion);
138257 +
138258 +/* internal function used as a wait_event() expression */
138259 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
138260 +{
138261 + unsigned long irqflags __maybe_unused;
138262 + int ret = -EBUSY;
138263 + PORTAL_IRQ_LOCK(p, irqflags);
138264 + if (!p->vdqcr_owned) {
138265 + FQLOCK(fq);
138266 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138267 + goto escape;
138268 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
138269 + FQUNLOCK(fq);
138270 + p->vdqcr_owned = fq;
138271 + ret = 0;
138272 + }
138273 +escape:
138274 + PORTAL_IRQ_UNLOCK(p, irqflags);
138275 + if (!ret)
138276 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
138277 + return ret;
138278 +}
138279 +
138280 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
138281 +{
138282 + int ret;
138283 + *p = get_affine_portal();
138284 + ret = set_p_vdqcr(*p, fq, vdqcr);
138285 + put_affine_portal();
138286 + return ret;
138287 +}
138288 +
138289 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138290 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
138291 + u32 vdqcr, u32 flags)
138292 +{
138293 + int ret = 0;
138294 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138295 + ret = wait_event_interruptible(affine_queue,
138296 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
138297 + else
138298 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
138299 + return ret;
138300 +}
138301 +
138302 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
138303 + u32 vdqcr, u32 flags)
138304 +{
138305 + int ret = 0;
138306 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138307 + ret = wait_event_interruptible(affine_queue,
138308 + !(ret = set_vdqcr(p, fq, vdqcr)));
138309 + else
138310 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
138311 + return ret;
138312 +}
138313 +#endif
138314 +
138315 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
138316 + u32 flags __maybe_unused, u32 vdqcr)
138317 +{
138318 + int ret;
138319 +
138320 + if ((fq->state != qman_fq_state_parked) &&
138321 + (fq->state != qman_fq_state_retired))
138322 + return -EINVAL;
138323 + if (vdqcr & QM_VDQCR_FQID_MASK)
138324 + return -EINVAL;
138325 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138326 + return -EBUSY;
138327 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138328 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138329 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138330 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
138331 + else
138332 +#endif
138333 + ret = set_p_vdqcr(p, fq, vdqcr);
138334 + if (ret)
138335 + return ret;
138336 + /* VDQCR is set */
138337 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138338 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138339 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138340 + /* NB: don't propagate any error - the caller wouldn't
138341 + * know whether the VDQCR was issued or not. A signal
138342 + * could arrive after returning anyway, so the caller
138343 + * can check signal_pending() if that's an issue. */
138344 + wait_event_interruptible(affine_queue,
138345 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138346 + else
138347 + wait_event(affine_queue,
138348 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138349 + }
138350 +#endif
138351 + return 0;
138352 +}
138353 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
138354 +
138355 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
138356 + u32 vdqcr)
138357 +{
138358 + struct qman_portal *p;
138359 + int ret;
138360 +
138361 + if ((fq->state != qman_fq_state_parked) &&
138362 + (fq->state != qman_fq_state_retired))
138363 + return -EINVAL;
138364 + if (vdqcr & QM_VDQCR_FQID_MASK)
138365 + return -EINVAL;
138366 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
138367 + return -EBUSY;
138368 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
138369 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138370 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
138371 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
138372 + else
138373 +#endif
138374 + ret = set_vdqcr(&p, fq, vdqcr);
138375 + if (ret)
138376 + return ret;
138377 + /* VDQCR is set */
138378 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138379 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
138380 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
138381 + /* NB: don't propagate any error - the caller wouldn't
138382 + * know whether the VDQCR was issued or not. A signal
138383 + * could arrive after returning anyway, so the caller
138384 + * can check signal_pending() if that's an issue. */
138385 + wait_event_interruptible(affine_queue,
138386 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138387 + else
138388 + wait_event(affine_queue,
138389 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
138390 + }
138391 +#endif
138392 + return 0;
138393 +}
138394 +EXPORT_SYMBOL(qman_volatile_dequeue);
138395 +
138396 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
138397 +{
138398 + if (avail)
138399 + qm_eqcr_cce_prefetch(&p->p);
138400 + else
138401 + qm_eqcr_cce_update(&p->p);
138402 +}
138403 +
138404 +int qman_eqcr_is_empty(void)
138405 +{
138406 + unsigned long irqflags __maybe_unused;
138407 + struct qman_portal *p = get_affine_portal();
138408 + u8 avail;
138409 +
138410 + PORTAL_IRQ_LOCK(p, irqflags);
138411 + update_eqcr_ci(p, 0);
138412 + avail = qm_eqcr_get_fill(&p->p);
138413 + PORTAL_IRQ_UNLOCK(p, irqflags);
138414 + put_affine_portal();
138415 + return avail == 0;
138416 +}
138417 +EXPORT_SYMBOL(qman_eqcr_is_empty);
138418 +
138419 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
138420 +{
138421 + if (affine) {
138422 + unsigned long irqflags __maybe_unused;
138423 + struct qman_portal *p = get_affine_portal();
138424 + PORTAL_IRQ_LOCK(p, irqflags);
138425 + p->cb_dc_ern = handler;
138426 + PORTAL_IRQ_UNLOCK(p, irqflags);
138427 + put_affine_portal();
138428 + } else
138429 + cb_dc_ern = handler;
138430 +}
138431 +EXPORT_SYMBOL(qman_set_dc_ern);
138432 +
138433 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
138434 + unsigned long *irqflags __maybe_unused,
138435 + struct qman_fq *fq,
138436 + const struct qm_fd *fd,
138437 + u32 flags)
138438 +{
138439 + struct qm_eqcr_entry *eq;
138440 + u8 avail;
138441 + PORTAL_IRQ_LOCK(p, (*irqflags));
138442 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138443 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138444 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138445 + if (p->eqci_owned) {
138446 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138447 + return NULL;
138448 + }
138449 + p->eqci_owned = fq;
138450 + }
138451 +#endif
138452 + if (p->use_eqcr_ci_stashing) {
138453 + /*
138454 + * The stashing case is easy, only update if we need to in
138455 + * order to try and liberate ring entries.
138456 + */
138457 + eq = qm_eqcr_start_stash(&p->p);
138458 + } else {
138459 + /*
138460 + * The non-stashing case is harder, need to prefetch ahead of
138461 + * time.
138462 + */
138463 + avail = qm_eqcr_get_avail(&p->p);
138464 + if (avail < 2)
138465 + update_eqcr_ci(p, avail);
138466 + eq = qm_eqcr_start_no_stash(&p->p);
138467 + }
138468 +
138469 + if (unlikely(!eq)) {
138470 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138471 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138472 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
138473 + p->eqci_owned = NULL;
138474 +#endif
138475 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
138476 + return NULL;
138477 + }
138478 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
138479 + eq->dca = QM_EQCR_DCA_ENABLE |
138480 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
138481 + QM_EQCR_DCA_PARK : 0) |
138482 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
138483 + eq->fqid = cpu_to_be32(fq->fqid);
138484 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138485 + eq->tag = cpu_to_be32(fq->key);
138486 +#else
138487 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
138488 +#endif
138489 + eq->fd = *fd;
138490 + cpu_to_hw_fd(&eq->fd);
138491 + return eq;
138492 +}
138493 +
138494 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
138495 + unsigned long *irqflags __maybe_unused,
138496 + struct qman_fq *fq,
138497 + const struct qm_fd *fd,
138498 + u32 flags)
138499 +{
138500 + struct qm_eqcr_entry *eq;
138501 + *p = get_affine_portal();
138502 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
138503 + if (!eq)
138504 + put_affine_portal();
138505 + return eq;
138506 +}
138507 +
138508 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138509 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
138510 + unsigned long *irqflags __maybe_unused,
138511 + struct qman_fq *fq,
138512 + const struct qm_fd *fd,
138513 + u32 flags)
138514 +{
138515 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
138516 + if (!eq)
138517 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
138518 + return eq;
138519 +}
138520 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
138521 + unsigned long *irqflags __maybe_unused,
138522 + struct qman_fq *fq,
138523 + const struct qm_fd *fd,
138524 + u32 flags)
138525 +{
138526 + struct qm_eqcr_entry *eq;
138527 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138528 + /* NB: return NULL if signal occurs before completion. Signal
138529 + * can occur during return. Caller must check for signal */
138530 + wait_event_interruptible(affine_queue,
138531 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138532 + else
138533 + wait_event(affine_queue,
138534 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
138535 + return eq;
138536 +}
138537 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
138538 + unsigned long *irqflags __maybe_unused,
138539 + struct qman_fq *fq,
138540 + const struct qm_fd *fd,
138541 + u32 flags)
138542 +{
138543 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
138544 + if (!eq)
138545 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
138546 + return eq;
138547 +}
138548 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
138549 + unsigned long *irqflags __maybe_unused,
138550 + struct qman_fq *fq,
138551 + const struct qm_fd *fd,
138552 + u32 flags)
138553 +{
138554 + struct qm_eqcr_entry *eq;
138555 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138556 + /* NB: return NULL if signal occurs before completion. Signal
138557 + * can occur during return. Caller must check for signal */
138558 + wait_event_interruptible(affine_queue,
138559 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138560 + else
138561 + wait_event(affine_queue,
138562 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
138563 + return eq;
138564 +}
138565 +#endif
138566 +
138567 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
138568 + const struct qm_fd *fd, u32 flags)
138569 +{
138570 + struct qm_eqcr_entry *eq;
138571 + unsigned long irqflags __maybe_unused;
138572 +
138573 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138574 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138575 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138576 + else
138577 +#endif
138578 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138579 + if (!eq)
138580 + return -EBUSY;
138581 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138582 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138583 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138584 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138585 + PORTAL_IRQ_UNLOCK(p, irqflags);
138586 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138587 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138588 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138589 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138590 + /* NB: return success even if signal occurs before
138591 + * condition is true. pvb_commit guarantees success */
138592 + wait_event_interruptible(affine_queue,
138593 + (p->eqci_owned != fq));
138594 + else
138595 + wait_event(affine_queue, (p->eqci_owned != fq));
138596 + }
138597 +#endif
138598 + return 0;
138599 +}
138600 +EXPORT_SYMBOL(qman_p_enqueue);
138601 +
138602 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
138603 +{
138604 + struct qman_portal *p;
138605 + struct qm_eqcr_entry *eq;
138606 + unsigned long irqflags __maybe_unused;
138607 +
138608 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138609 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138610 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138611 + else
138612 +#endif
138613 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138614 + if (!eq)
138615 + return -EBUSY;
138616 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138617 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138618 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138619 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138620 + PORTAL_IRQ_UNLOCK(p, irqflags);
138621 + put_affine_portal();
138622 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138623 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138624 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138625 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138626 + /* NB: return success even if signal occurs before
138627 + * condition is true. pvb_commit guarantees success */
138628 + wait_event_interruptible(affine_queue,
138629 + (p->eqci_owned != fq));
138630 + else
138631 + wait_event(affine_queue, (p->eqci_owned != fq));
138632 + }
138633 +#endif
138634 + return 0;
138635 +}
138636 +EXPORT_SYMBOL(qman_enqueue);
138637 +
138638 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
138639 + const struct qm_fd *fd, u32 flags,
138640 + struct qman_fq *orp, u16 orp_seqnum)
138641 +{
138642 + struct qm_eqcr_entry *eq;
138643 + unsigned long irqflags __maybe_unused;
138644 +
138645 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138646 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138647 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138648 + else
138649 +#endif
138650 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138651 + if (!eq)
138652 + return -EBUSY;
138653 + /* Process ORP-specifics here */
138654 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138655 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138656 + else {
138657 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138658 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138659 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138660 + else
138661 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138662 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138663 + }
138664 + eq->seqnum = cpu_to_be16(orp_seqnum);
138665 + eq->orp = cpu_to_be32(orp->fqid);
138666 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138667 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138668 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138669 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138670 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138671 + PORTAL_IRQ_UNLOCK(p, irqflags);
138672 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138673 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138674 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138675 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138676 + /* NB: return success even if signal occurs before
138677 + * condition is true. pvb_commit guarantees success */
138678 + wait_event_interruptible(affine_queue,
138679 + (p->eqci_owned != fq));
138680 + else
138681 + wait_event(affine_queue, (p->eqci_owned != fq));
138682 + }
138683 +#endif
138684 + return 0;
138685 +}
138686 +EXPORT_SYMBOL(qman_p_enqueue_orp);
138687 +
138688 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
138689 + struct qman_fq *orp, u16 orp_seqnum)
138690 +{
138691 + struct qman_portal *p;
138692 + struct qm_eqcr_entry *eq;
138693 + unsigned long irqflags __maybe_unused;
138694 +
138695 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138696 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138697 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138698 + else
138699 +#endif
138700 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138701 + if (!eq)
138702 + return -EBUSY;
138703 + /* Process ORP-specifics here */
138704 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
138705 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
138706 + else {
138707 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
138708 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
138709 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
138710 + else
138711 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
138712 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
138713 + }
138714 + eq->seqnum = cpu_to_be16(orp_seqnum);
138715 + eq->orp = cpu_to_be32(orp->fqid);
138716 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138717 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
138718 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
138719 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
138720 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138721 + PORTAL_IRQ_UNLOCK(p, irqflags);
138722 + put_affine_portal();
138723 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138724 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138725 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138726 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138727 + /* NB: return success even if signal occurs before
138728 + * condition is true. pvb_commit guarantees success */
138729 + wait_event_interruptible(affine_queue,
138730 + (p->eqci_owned != fq));
138731 + else
138732 + wait_event(affine_queue, (p->eqci_owned != fq));
138733 + }
138734 +#endif
138735 + return 0;
138736 +}
138737 +EXPORT_SYMBOL(qman_enqueue_orp);
138738 +
138739 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
138740 + const struct qm_fd *fd, u32 flags,
138741 + qman_cb_precommit cb, void *cb_arg)
138742 +{
138743 + struct qm_eqcr_entry *eq;
138744 + unsigned long irqflags __maybe_unused;
138745 +
138746 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138747 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138748 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
138749 + else
138750 +#endif
138751 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
138752 + if (!eq)
138753 + return -EBUSY;
138754 + /* invoke user supplied callback function before writing commit verb */
138755 + if (cb(cb_arg)) {
138756 + PORTAL_IRQ_UNLOCK(p, irqflags);
138757 + return -EINVAL;
138758 + }
138759 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138760 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138761 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138762 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138763 + PORTAL_IRQ_UNLOCK(p, irqflags);
138764 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138765 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138766 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138767 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138768 + /* NB: return success even if signal occurs before
138769 + * condition is true. pvb_commit guarantees success */
138770 + wait_event_interruptible(affine_queue,
138771 + (p->eqci_owned != fq));
138772 + else
138773 + wait_event(affine_queue, (p->eqci_owned != fq));
138774 + }
138775 +#endif
138776 + return 0;
138777 +}
138778 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
138779 +
138780 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
138781 + u32 flags, qman_cb_precommit cb, void *cb_arg)
138782 +{
138783 + struct qman_portal *p;
138784 + struct qm_eqcr_entry *eq;
138785 + unsigned long irqflags __maybe_unused;
138786 +
138787 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
138788 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
138789 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
138790 + else
138791 +#endif
138792 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
138793 + if (!eq)
138794 + return -EBUSY;
138795 + /* invoke user supplied callback function before writing commit verb */
138796 + if (cb(cb_arg)) {
138797 + PORTAL_IRQ_UNLOCK(p, irqflags);
138798 + put_affine_portal();
138799 + return -EINVAL;
138800 + }
138801 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
138802 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
138803 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
138804 + /* Factor the below out, it's used from qman_enqueue_orp() too */
138805 + PORTAL_IRQ_UNLOCK(p, irqflags);
138806 + put_affine_portal();
138807 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138808 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
138809 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
138810 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
138811 + /* NB: return success even if signal occurs before
138812 + * condition is true. pvb_commit guarantees success */
138813 + wait_event_interruptible(affine_queue,
138814 + (p->eqci_owned != fq));
138815 + else
138816 + wait_event(affine_queue, (p->eqci_owned != fq));
138817 + }
138818 +#endif
138819 + return 0;
138820 +}
138821 +EXPORT_SYMBOL(qman_enqueue_precommit);
138822 +
138823 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
138824 + struct qm_mcc_initcgr *opts)
138825 +{
138826 + struct qm_mc_command *mcc;
138827 + struct qm_mc_result *mcr;
138828 + struct qman_portal *p = get_affine_portal();
138829 + unsigned long irqflags __maybe_unused;
138830 + u8 res;
138831 + u8 verb = QM_MCC_VERB_MODIFYCGR;
138832 +
138833 + PORTAL_IRQ_LOCK(p, irqflags);
138834 + mcc = qm_mc_start(&p->p);
138835 + if (opts)
138836 + mcc->initcgr = *opts;
138837 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
138838 + mcc->initcgr.cgr.wr_parm_g.word =
138839 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
138840 + mcc->initcgr.cgr.wr_parm_y.word =
138841 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
138842 + mcc->initcgr.cgr.wr_parm_r.word =
138843 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
138844 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
138845 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
138846 +
138847 + mcc->initcgr.cgid = cgr->cgrid;
138848 + if (flags & QMAN_CGR_FLAG_USE_INIT)
138849 + verb = QM_MCC_VERB_INITCGR;
138850 + qm_mc_commit(&p->p, verb);
138851 + while (!(mcr = qm_mc_result(&p->p)))
138852 + cpu_relax();
138853 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
138854 + res = mcr->result;
138855 + PORTAL_IRQ_UNLOCK(p, irqflags);
138856 + put_affine_portal();
138857 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
138858 +}
138859 +EXPORT_SYMBOL(qman_modify_cgr);
138860 +
138861 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
138862 + QM_CHANNEL_SWPORTAL0))
138863 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
138864 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
138865 +
138866 +static u8 qman_cgr_cpus[__CGR_NUM];
138867 +
138868 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
138869 + struct qm_mcc_initcgr *opts)
138870 +{
138871 + unsigned long irqflags __maybe_unused;
138872 + struct qm_mcr_querycgr cgr_state;
138873 + struct qm_mcc_initcgr local_opts;
138874 + int ret;
138875 + struct qman_portal *p;
138876 +
138877 + /* We have to check that the provided CGRID is within the limits of the
138878 + * data-structures, for obvious reasons. However we'll let h/w take
138879 + * care of determining whether it's within the limits of what exists on
138880 + * the SoC. */
138881 + if (cgr->cgrid >= __CGR_NUM)
138882 + return -EINVAL;
138883 +
138884 + preempt_disable();
138885 + p = get_affine_portal();
138886 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
138887 + preempt_enable();
138888 +
138889 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138890 + cgr->chan = p->config->public_cfg.channel;
138891 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138892 +
138893 + /* if no opts specified, just add it to the list */
138894 + if (!opts)
138895 + goto add_list;
138896 +
138897 + ret = qman_query_cgr(cgr, &cgr_state);
138898 + if (ret)
138899 + goto release_lock;
138900 + if (opts)
138901 + local_opts = *opts;
138902 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138903 + local_opts.cgr.cscn_targ_upd_ctrl =
138904 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
138905 + else
138906 + /* Overwrite TARG */
138907 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138908 + TARG_MASK(p);
138909 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138910 +
138911 + /* send init if flags indicate so */
138912 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138913 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
138914 + else
138915 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138916 + if (ret)
138917 + goto release_lock;
138918 +add_list:
138919 + list_add(&cgr->node, &p->cgr_cbs);
138920 +
138921 + /* Determine if newly added object requires its callback to be called */
138922 + ret = qman_query_cgr(cgr, &cgr_state);
138923 + if (ret) {
138924 + /* we can't go back, so proceed and return success, but screen
138925 + * and wail to the log file */
138926 + pr_crit("CGR HW state partially modified\n");
138927 + ret = 0;
138928 + goto release_lock;
138929 + }
138930 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
138931 + cgr->cgrid))
138932 + cgr->cb(p, cgr, 1);
138933 +release_lock:
138934 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138935 + put_affine_portal();
138936 + return ret;
138937 +}
138938 +EXPORT_SYMBOL(qman_create_cgr);
138939 +
138940 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
138941 + struct qm_mcc_initcgr *opts)
138942 +{
138943 + unsigned long irqflags __maybe_unused;
138944 + struct qm_mcc_initcgr local_opts;
138945 + struct qm_mcr_querycgr cgr_state;
138946 + int ret;
138947 +
138948 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
138949 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
138950 + return -EINVAL;
138951 + }
138952 + /* We have to check that the provided CGRID is within the limits of the
138953 + * data-structures, for obvious reasons. However we'll let h/w take
138954 + * care of determining whether it's within the limits of what exists on
138955 + * the SoC.
138956 + */
138957 + if (cgr->cgrid >= __CGR_NUM)
138958 + return -EINVAL;
138959 +
138960 + ret = qman_query_cgr(cgr, &cgr_state);
138961 + if (ret)
138962 + return ret;
138963 +
138964 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
138965 + if (opts)
138966 + local_opts = *opts;
138967 +
138968 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
138969 + local_opts.cgr.cscn_targ_upd_ctrl =
138970 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
138971 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
138972 + else
138973 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
138974 + TARG_DCP_MASK(dcp_portal);
138975 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
138976 +
138977 + /* send init if flags indicate so */
138978 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
138979 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
138980 + &local_opts);
138981 + else
138982 + ret = qman_modify_cgr(cgr, 0, &local_opts);
138983 +
138984 + return ret;
138985 +}
138986 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
138987 +
138988 +int qman_delete_cgr(struct qman_cgr *cgr)
138989 +{
138990 + unsigned long irqflags __maybe_unused;
138991 + struct qm_mcr_querycgr cgr_state;
138992 + struct qm_mcc_initcgr local_opts;
138993 + int ret = 0;
138994 + struct qman_cgr *i;
138995 + struct qman_portal *p = get_affine_portal();
138996 +
138997 + if (cgr->chan != p->config->public_cfg.channel) {
138998 + pr_crit("Attempting to delete cgr from different portal "
138999 + "than it was create: create 0x%x, delete 0x%x\n",
139000 + cgr->chan, p->config->public_cfg.channel);
139001 + ret = -EINVAL;
139002 + goto put_portal;
139003 + }
139004 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
139005 + spin_lock_irqsave(&p->cgr_lock, irqflags);
139006 + list_del(&cgr->node);
139007 + /*
139008 + * If there are no other CGR objects for this CGRID in the list, update
139009 + * CSCN_TARG accordingly
139010 + */
139011 + list_for_each_entry(i, &p->cgr_cbs, node)
139012 + if ((i->cgrid == cgr->cgrid) && i->cb)
139013 + goto release_lock;
139014 + ret = qman_query_cgr(cgr, &cgr_state);
139015 + if (ret) {
139016 + /* add back to the list */
139017 + list_add(&cgr->node, &p->cgr_cbs);
139018 + goto release_lock;
139019 + }
139020 + /* Overwrite TARG */
139021 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
139022 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
139023 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
139024 + else
139025 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
139026 + ~(TARG_MASK(p));
139027 + ret = qman_modify_cgr(cgr, 0, &local_opts);
139028 + if (ret)
139029 + /* add back to the list */
139030 + list_add(&cgr->node, &p->cgr_cbs);
139031 +release_lock:
139032 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
139033 +put_portal:
139034 + put_affine_portal();
139035 + return ret;
139036 +}
139037 +EXPORT_SYMBOL(qman_delete_cgr);
139038 +
139039 +struct cgr_comp {
139040 + struct qman_cgr *cgr;
139041 + struct completion completion;
139042 +};
139043 +
139044 +static void qman_delete_cgr_smp_call(void *p)
139045 +{
139046 + qman_delete_cgr((struct qman_cgr *)p);
139047 +}
139048 +
139049 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
139050 +{
139051 + preempt_disable();
139052 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
139053 + smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
139054 + qman_delete_cgr_smp_call, cgr, true);
139055 + preempt_enable();
139056 + return;
139057 + }
139058 + qman_delete_cgr(cgr);
139059 + preempt_enable();
139060 +}
139061 +EXPORT_SYMBOL(qman_delete_cgr_safe);
139062 +
139063 +int qm_get_clock(u64 *clock_hz)
139064 +{
139065 + if (!qman_clk) {
139066 + pr_warn("Qman clock speed is unknown\n");
139067 + return -EINVAL;
139068 + }
139069 + *clock_hz = (u64)qman_clk;
139070 + return 0;
139071 +}
139072 +EXPORT_SYMBOL(qm_get_clock);
139073 +
139074 +int qm_set_clock(u64 clock_hz)
139075 +{
139076 + if (qman_clk)
139077 + return -1;
139078 + qman_clk = (u32)clock_hz;
139079 + return 0;
139080 +}
139081 +EXPORT_SYMBOL(qm_set_clock);
139082 +
139083 +/* CEETM management command */
139084 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
139085 +{
139086 + struct qm_mc_command *mcc;
139087 + struct qm_mc_result *mcr;
139088 + struct qman_portal *p;
139089 + unsigned long irqflags __maybe_unused;
139090 + u8 res;
139091 +
139092 + p = get_affine_portal();
139093 + PORTAL_IRQ_LOCK(p, irqflags);
139094 +
139095 + mcc = qm_mc_start(&p->p);
139096 + mcc->lfqmt_config = *opts;
139097 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
139098 + while (!(mcr = qm_mc_result(&p->p)))
139099 + cpu_relax();
139100 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139101 + QM_CEETM_VERB_LFQMT_CONFIG);
139102 + PORTAL_IRQ_UNLOCK(p, irqflags);
139103 + put_affine_portal();
139104 +
139105 + res = mcr->result;
139106 + if (res != QM_MCR_RESULT_OK) {
139107 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
139108 + return -EIO;
139109 + }
139110 + return 0;
139111 +}
139112 +
139113 +int qman_ceetm_query_lfqmt(int lfqid,
139114 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
139115 +{
139116 + struct qm_mc_command *mcc;
139117 + struct qm_mc_result *mcr;
139118 + struct qman_portal *p;
139119 + unsigned long irqflags __maybe_unused;
139120 + u8 res;
139121 +
139122 + p = get_affine_portal();
139123 + PORTAL_IRQ_LOCK(p, irqflags);
139124 +
139125 + mcc = qm_mc_start(&p->p);
139126 + mcc->lfqmt_query.lfqid = lfqid;
139127 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
139128 + while (!(mcr = qm_mc_result(&p->p)))
139129 + cpu_relax();
139130 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
139131 + res = mcr->result;
139132 + if (res == QM_MCR_RESULT_OK)
139133 + *lfqmt_query = mcr->lfqmt_query;
139134 +
139135 + PORTAL_IRQ_UNLOCK(p, irqflags);
139136 + put_affine_portal();
139137 + if (res != QM_MCR_RESULT_OK) {
139138 + pr_err("CEETM: QUERY LFQMT failed\n");
139139 + return -EIO;
139140 + }
139141 + return 0;
139142 +}
139143 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
139144 +
139145 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
139146 +{
139147 + struct qm_mc_command *mcc;
139148 + struct qm_mc_result *mcr;
139149 + struct qman_portal *p;
139150 + unsigned long irqflags __maybe_unused;
139151 + u8 res;
139152 +
139153 + p = get_affine_portal();
139154 + PORTAL_IRQ_LOCK(p, irqflags);
139155 +
139156 + mcc = qm_mc_start(&p->p);
139157 + mcc->cq_config = *opts;
139158 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
139159 + while (!(mcr = qm_mc_result(&p->p)))
139160 + cpu_relax();
139161 + res = mcr->result;
139162 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
139163 +
139164 + PORTAL_IRQ_UNLOCK(p, irqflags);
139165 + put_affine_portal();
139166 +
139167 + if (res != QM_MCR_RESULT_OK) {
139168 + pr_err("CEETM: CONFIGURE CQ failed\n");
139169 + return -EIO;
139170 + }
139171 + return 0;
139172 +}
139173 +
139174 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
139175 + struct qm_mcr_ceetm_cq_query *cq_query)
139176 +{
139177 + struct qm_mc_command *mcc;
139178 + struct qm_mc_result *mcr;
139179 + struct qman_portal *p;
139180 + unsigned long irqflags __maybe_unused;
139181 + u8 res;
139182 +
139183 + p = get_affine_portal();
139184 + PORTAL_IRQ_LOCK(p, irqflags);
139185 +
139186 + mcc = qm_mc_start(&p->p);
139187 + mcc->cq_query.cqid = cpu_to_be16(cqid);
139188 + mcc->cq_query.dcpid = dcpid;
139189 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
139190 + while (!(mcr = qm_mc_result(&p->p)))
139191 + cpu_relax();
139192 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
139193 + res = mcr->result;
139194 + if (res == QM_MCR_RESULT_OK) {
139195 + *cq_query = mcr->cq_query;
139196 + hw_cq_query_to_cpu(cq_query);
139197 + }
139198 +
139199 + PORTAL_IRQ_UNLOCK(p, irqflags);
139200 + put_affine_portal();
139201 +
139202 + if (res != QM_MCR_RESULT_OK) {
139203 + pr_err("CEETM: QUERY CQ failed\n");
139204 + return -EIO;
139205 + }
139206 +
139207 + return 0;
139208 +}
139209 +EXPORT_SYMBOL(qman_ceetm_query_cq);
139210 +
139211 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
139212 +{
139213 + struct qm_mc_command *mcc;
139214 + struct qm_mc_result *mcr;
139215 + struct qman_portal *p;
139216 + unsigned long irqflags __maybe_unused;
139217 + u8 res;
139218 +
139219 + p = get_affine_portal();
139220 + PORTAL_IRQ_LOCK(p, irqflags);
139221 +
139222 + mcc = qm_mc_start(&p->p);
139223 + mcc->dct_config = *opts;
139224 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
139225 + while (!(mcr = qm_mc_result(&p->p)))
139226 + cpu_relax();
139227 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
139228 + res = mcr->result;
139229 +
139230 + PORTAL_IRQ_UNLOCK(p, irqflags);
139231 + put_affine_portal();
139232 +
139233 + if (res != QM_MCR_RESULT_OK) {
139234 + pr_err("CEETM: CONFIGURE DCT failed\n");
139235 + return -EIO;
139236 + }
139237 + return 0;
139238 +}
139239 +
139240 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
139241 + struct qm_mcr_ceetm_dct_query *dct_query)
139242 +{
139243 + struct qm_mc_command *mcc;
139244 + struct qm_mc_result *mcr;
139245 + struct qman_portal *p = get_affine_portal();
139246 + unsigned long irqflags __maybe_unused;
139247 + u8 res;
139248 +
139249 + PORTAL_IRQ_LOCK(p, irqflags);
139250 +
139251 + mcc = qm_mc_start(&p->p);
139252 + mcc->dct_query = *opts;
139253 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
139254 + while (!(mcr = qm_mc_result(&p->p)))
139255 + cpu_relax();
139256 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
139257 + res = mcr->result;
139258 +
139259 + PORTAL_IRQ_UNLOCK(p, irqflags);
139260 + put_affine_portal();
139261 +
139262 + if (res != QM_MCR_RESULT_OK) {
139263 + pr_err("CEETM: QUERY DCT failed\n");
139264 + return -EIO;
139265 + }
139266 +
139267 + *dct_query = mcr->dct_query;
139268 + return 0;
139269 +}
139270 +
139271 +static int qman_ceetm_configure_class_scheduler(
139272 + struct qm_mcc_ceetm_class_scheduler_config *opts)
139273 +{
139274 + struct qm_mc_command *mcc;
139275 + struct qm_mc_result *mcr;
139276 + struct qman_portal *p;
139277 + unsigned long irqflags __maybe_unused;
139278 + u8 res;
139279 +
139280 + p = get_affine_portal();
139281 + PORTAL_IRQ_LOCK(p, irqflags);
139282 +
139283 + mcc = qm_mc_start(&p->p);
139284 + mcc->csch_config = *opts;
139285 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139286 + while (!(mcr = qm_mc_result(&p->p)))
139287 + cpu_relax();
139288 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139289 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
139290 + res = mcr->result;
139291 +
139292 + PORTAL_IRQ_UNLOCK(p, irqflags);
139293 + put_affine_portal();
139294 +
139295 + if (res != QM_MCR_RESULT_OK) {
139296 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
139297 + return -EIO;
139298 + }
139299 + return 0;
139300 +}
139301 +
139302 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
139303 + struct qm_mcr_ceetm_class_scheduler_query *query)
139304 +{
139305 + struct qm_mc_command *mcc;
139306 + struct qm_mc_result *mcr;
139307 + struct qman_portal *p;
139308 + unsigned long irqflags __maybe_unused;
139309 + u8 res;
139310 +
139311 + p = get_affine_portal();
139312 + PORTAL_IRQ_LOCK(p, irqflags);
139313 +
139314 + mcc = qm_mc_start(&p->p);
139315 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
139316 + mcc->csch_query.dcpid = channel->dcp_idx;
139317 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139318 + while (!(mcr = qm_mc_result(&p->p)))
139319 + cpu_relax();
139320 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139321 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
139322 + res = mcr->result;
139323 +
139324 + PORTAL_IRQ_UNLOCK(p, irqflags);
139325 + put_affine_portal();
139326 +
139327 + if (res != QM_MCR_RESULT_OK) {
139328 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
139329 + return -EIO;
139330 + }
139331 + *query = mcr->csch_query;
139332 + return 0;
139333 +}
139334 +
139335 +static int qman_ceetm_configure_mapping_shaper_tcfc(
139336 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
139337 +{
139338 + struct qm_mc_command *mcc;
139339 + struct qm_mc_result *mcr;
139340 + struct qman_portal *p;
139341 + unsigned long irqflags __maybe_unused;
139342 + u8 res;
139343 +
139344 + p = get_affine_portal();
139345 + PORTAL_IRQ_LOCK(p, irqflags);
139346 +
139347 + mcc = qm_mc_start(&p->p);
139348 + mcc->mst_config = *opts;
139349 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139350 + while (!(mcr = qm_mc_result(&p->p)))
139351 + cpu_relax();
139352 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139353 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
139354 + res = mcr->result;
139355 +
139356 + PORTAL_IRQ_UNLOCK(p, irqflags);
139357 + put_affine_portal();
139358 +
139359 + if (res != QM_MCR_RESULT_OK) {
139360 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
139361 + return -EIO;
139362 + }
139363 + return 0;
139364 +}
139365 +
139366 +static int qman_ceetm_query_mapping_shaper_tcfc(
139367 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
139368 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
139369 +{
139370 + struct qm_mc_command *mcc;
139371 + struct qm_mc_result *mcr;
139372 + struct qman_portal *p;
139373 + unsigned long irqflags __maybe_unused;
139374 + u8 res;
139375 +
139376 + p = get_affine_portal();
139377 + PORTAL_IRQ_LOCK(p, irqflags);
139378 +
139379 + mcc = qm_mc_start(&p->p);
139380 + mcc->mst_query = *opts;
139381 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139382 + while (!(mcr = qm_mc_result(&p->p)))
139383 + cpu_relax();
139384 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139385 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
139386 + res = mcr->result;
139387 +
139388 + PORTAL_IRQ_UNLOCK(p, irqflags);
139389 + put_affine_portal();
139390 +
139391 + if (res != QM_MCR_RESULT_OK) {
139392 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
139393 + return -EIO;
139394 + }
139395 +
139396 + *response = mcr->mst_query;
139397 + return 0;
139398 +}
139399 +
139400 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
139401 +{
139402 + struct qm_mc_command *mcc;
139403 + struct qm_mc_result *mcr;
139404 + struct qman_portal *p;
139405 + unsigned long irqflags __maybe_unused;
139406 + u8 res;
139407 +
139408 + p = get_affine_portal();
139409 + PORTAL_IRQ_LOCK(p, irqflags);
139410 +
139411 + mcc = qm_mc_start(&p->p);
139412 + mcc->ccgr_config = *opts;
139413 +
139414 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
139415 + while (!(mcr = qm_mc_result(&p->p)))
139416 + cpu_relax();
139417 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
139418 +
139419 + PORTAL_IRQ_UNLOCK(p, irqflags);
139420 + put_affine_portal();
139421 +
139422 + res = mcr->result;
139423 + if (res != QM_MCR_RESULT_OK) {
139424 + pr_err("CEETM: CONFIGURE CCGR failed\n");
139425 + return -EIO;
139426 + }
139427 + return 0;
139428 +}
139429 +
139430 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
139431 + struct qm_mcr_ceetm_ccgr_query *response)
139432 +{
139433 + struct qm_mc_command *mcc;
139434 + struct qm_mc_result *mcr;
139435 + struct qman_portal *p;
139436 + unsigned long irqflags __maybe_unused;
139437 + u8 res;
139438 +
139439 + p = get_affine_portal();
139440 + PORTAL_IRQ_LOCK(p, irqflags);
139441 +
139442 + mcc = qm_mc_start(&p->p);
139443 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
139444 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
139445 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
139446 +
139447 + while (!(mcr = qm_mc_result(&p->p)))
139448 + cpu_relax();
139449 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
139450 + res = mcr->result;
139451 + if (res == QM_MCR_RESULT_OK) {
139452 + *response = mcr->ccgr_query;
139453 + hw_ccgr_query_to_cpu(response);
139454 + }
139455 +
139456 + PORTAL_IRQ_UNLOCK(p, irqflags);
139457 + put_affine_portal();
139458 + if (res != QM_MCR_RESULT_OK) {
139459 + pr_err("CEETM: QUERY CCGR failed\n");
139460 + return -EIO;
139461 + }
139462 + return 0;
139463 +}
139464 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
139465 +
139466 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
139467 + u8 command_type, u16 xsfdr,
139468 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
139469 +{
139470 + struct qm_mc_command *mcc;
139471 + struct qm_mc_result *mcr;
139472 + struct qman_portal *p;
139473 + unsigned long irqflags __maybe_unused;
139474 + u8 res;
139475 +
139476 + p = get_affine_portal();
139477 + PORTAL_IRQ_LOCK(p, irqflags);
139478 +
139479 + mcc = qm_mc_start(&p->p);
139480 + switch (command_type) {
139481 + case 0:
139482 + case 1:
139483 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
139484 + break;
139485 + case 2:
139486 + mcc->cq_ppxr.xsfdr = xsfdr;
139487 + break;
139488 + default:
139489 + break;
139490 + }
139491 + mcc->cq_ppxr.ct = command_type;
139492 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
139493 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139494 + while (!(mcr = qm_mc_result(&p->p)))
139495 + cpu_relax();
139496 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139497 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
139498 +
139499 + PORTAL_IRQ_UNLOCK(p, irqflags);
139500 + put_affine_portal();
139501 +
139502 + res = mcr->result;
139503 + if (res != QM_MCR_RESULT_OK) {
139504 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
139505 + return -EIO;
139506 + }
139507 + *cq_ppxr = mcr->cq_ppxr;
139508 + return 0;
139509 +}
139510 +
139511 +static int qman_ceetm_query_statistics(u16 cid,
139512 + enum qm_dc_portal dcp_idx,
139513 + u16 command_type,
139514 + struct qm_mcr_ceetm_statistics_query *query_result)
139515 +{
139516 + struct qm_mc_command *mcc;
139517 + struct qm_mc_result *mcr;
139518 + struct qman_portal *p;
139519 + unsigned long irqflags __maybe_unused;
139520 + u8 res;
139521 +
139522 + p = get_affine_portal();
139523 + PORTAL_IRQ_LOCK(p, irqflags);
139524 +
139525 + mcc = qm_mc_start(&p->p);
139526 + mcc->stats_query_write.cid = cid;
139527 + mcc->stats_query_write.dcpid = dcp_idx;
139528 + mcc->stats_query_write.ct = command_type;
139529 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139530 +
139531 + while (!(mcr = qm_mc_result(&p->p)))
139532 + cpu_relax();
139533 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139534 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139535 +
139536 + PORTAL_IRQ_UNLOCK(p, irqflags);
139537 + put_affine_portal();
139538 +
139539 + res = mcr->result;
139540 + if (res != QM_MCR_RESULT_OK) {
139541 + pr_err("CEETM: STATISTICS QUERY failed\n");
139542 + return -EIO;
139543 + }
139544 + *query_result = mcr->stats_query;
139545 + return 0;
139546 +}
139547 +
139548 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
139549 + u16 command_type, u64 frame_count,
139550 + u64 byte_count)
139551 +{
139552 + struct qm_mc_command *mcc;
139553 + struct qm_mc_result *mcr;
139554 + struct qman_portal *p;
139555 + unsigned long irqflags __maybe_unused;
139556 + u8 res;
139557 +
139558 + p = get_affine_portal();
139559 + PORTAL_IRQ_LOCK(p, irqflags);
139560 +
139561 + mcc = qm_mc_start(&p->p);
139562 + mcc->stats_query_write.cid = cid;
139563 + mcc->stats_query_write.dcpid = dcp_idx;
139564 + mcc->stats_query_write.ct = command_type;
139565 + mcc->stats_query_write.frm_cnt = frame_count;
139566 + mcc->stats_query_write.byte_cnt = byte_count;
139567 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139568 +
139569 + while (!(mcr = qm_mc_result(&p->p)))
139570 + cpu_relax();
139571 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139572 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
139573 +
139574 + PORTAL_IRQ_UNLOCK(p, irqflags);
139575 + put_affine_portal();
139576 +
139577 + res = mcr->result;
139578 + if (res != QM_MCR_RESULT_OK) {
139579 + pr_err("CEETM: STATISTICS WRITE failed\n");
139580 + return -EIO;
139581 + }
139582 + return 0;
139583 +}
139584 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
139585 +
139586 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
139587 + int rounding)
139588 +{
139589 + u16 pres;
139590 + u64 temp;
139591 + u64 qman_freq;
139592 + int ret;
139593 +
139594 + /* Read PRES from CEET_CFG_PRES register */
139595 + ret = qman_ceetm_get_prescaler(&pres);
139596 + if (ret)
139597 + return -EINVAL;
139598 +
139599 + ret = qm_get_clock(&qman_freq);
139600 + if (ret)
139601 + return -EINVAL;
139602 +
139603 + /* token-rate = bytes-per-second * update-reference-period
139604 + *
139605 + * Where token-rate is N/8192 for a integer N, and
139606 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
139607 + * is the prescalar value and QHz is the QMan clock frequency.
139608 + * So:
139609 + *
139610 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
139611 + *
139612 + * Converting to bits-per-second gives;
139613 + *
139614 + * token-rate = (bps*2^19) / (PRES*QHZ)
139615 + * N = (bps*2^32) / (PRES*QHz)
139616 + *
139617 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
139618 + * (yet minimise rounding error if 'bps' is small), we reorganise
139619 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
139620 + * N = (((bps*2^16)/PRES)*2^16)/QHz
139621 + */
139622 + temp = ROUNDING((bps << 16), pres, rounding);
139623 + temp = ROUNDING((temp << 16), qman_freq, rounding);
139624 + token_rate->whole = temp >> 13;
139625 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
139626 + return 0;
139627 +}
139628 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
139629 +
139630 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
139631 + int rounding)
139632 +{
139633 + u16 pres;
139634 + u64 temp;
139635 + u64 qman_freq;
139636 + int ret;
139637 +
139638 + /* Read PRES from CEET_CFG_PRES register */
139639 + ret = qman_ceetm_get_prescaler(&pres);
139640 + if (ret)
139641 + return -EINVAL;
139642 +
139643 + ret = qm_get_clock(&qman_freq);
139644 + if (ret)
139645 + return -EINVAL;
139646 +
139647 + /* bytes-per-second = token-rate / update-reference-period
139648 + *
139649 + * where "token-rate" is N/8192 for an integer N, and
139650 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
139651 + * the prescalar value and QHz is the QMan clock frequency. So;
139652 + *
139653 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
139654 + * = N*PRES*QHz / (4194304*8192)
139655 + * = N*PRES*QHz / (2^35)
139656 + *
139657 + * Converting to bits-per-second gives;
139658 + *
139659 + * bps = N*PRES*QHZ / (2^32)
139660 + *
139661 + * Note, the numerator has a maximum width of 72 bits! So to
139662 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
139663 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
139664 + * multiplying by N (goes to maximum of 63 bits).
139665 + *
139666 + * temp = PRES*QHZ / (2^16)
139667 + * kbps = temp*N / (2^16)
139668 + */
139669 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
139670 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
139671 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
139672 + return 0;
139673 +}
139674 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
139675 +
139676 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
139677 + unsigned int sp_idx)
139678 +{
139679 + struct qm_ceetm_sp *p;
139680 +
139681 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
139682 + (dcp_idx == qm_dc_portal_fman1));
139683 +
139684 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
139685 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
139686 + qman_ceetms[dcp_idx].sp_range[1]))) {
139687 + pr_err("Sub-portal index doesn't exist\n");
139688 + return -EINVAL;
139689 + }
139690 +
139691 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
139692 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
139693 + p->is_claimed = 1;
139694 + *sp = p;
139695 + return 0;
139696 + }
139697 + }
139698 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
139699 + return -ENODEV;
139700 +}
139701 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
139702 +
139703 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
139704 +{
139705 + struct qm_ceetm_sp *p;
139706 +
139707 + if (sp->lni && sp->lni->is_claimed == 1) {
139708 + pr_err("The dependency of sub-portal has not been released!\n");
139709 + return -EBUSY;
139710 + }
139711 +
139712 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
139713 + if (p->idx == sp->idx) {
139714 + p->is_claimed = 0;
139715 + p->lni = NULL;
139716 + }
139717 + }
139718 + /* Disable CEETM mode of this sub-portal */
139719 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
139720 +
139721 + return 0;
139722 +}
139723 +EXPORT_SYMBOL(qman_ceetm_sp_release);
139724 +
139725 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
139726 + unsigned int lni_idx)
139727 +{
139728 + struct qm_ceetm_lni *p;
139729 +
139730 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
139731 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
139732 + qman_ceetms[dcp_idx].lni_range[1]))) {
139733 + pr_err("The lni index is out of range\n");
139734 + return -EINVAL;
139735 + }
139736 +
139737 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
139738 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
139739 + *lni = p;
139740 + p->is_claimed = 1;
139741 + return 0;
139742 + }
139743 + }
139744 +
139745 + pr_err("The LNI#%d is not available!\n", lni_idx);
139746 + return -EINVAL;
139747 +}
139748 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
139749 +
139750 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
139751 +{
139752 + struct qm_ceetm_lni *p;
139753 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139754 +
139755 + if (!list_empty(&lni->channels)) {
139756 + pr_err("The LNI dependencies are not released!\n");
139757 + return -EBUSY;
139758 + }
139759 +
139760 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
139761 + if (p->idx == lni->idx) {
139762 + p->shaper_enable = 0;
139763 + p->shaper_couple = 0;
139764 + p->cr_token_rate.whole = 0;
139765 + p->cr_token_rate.fraction = 0;
139766 + p->er_token_rate.whole = 0;
139767 + p->er_token_rate.fraction = 0;
139768 + p->cr_token_bucket_limit = 0;
139769 + p->er_token_bucket_limit = 0;
139770 + p->is_claimed = 0;
139771 + }
139772 + }
139773 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139774 + config_opts.dcpid = lni->dcp_idx;
139775 + memset(&config_opts.shaper_config, 0,
139776 + sizeof(config_opts.shaper_config));
139777 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139778 +}
139779 +EXPORT_SYMBOL(qman_ceetm_lni_release);
139780 +
139781 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
139782 +{
139783 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139784 +
139785 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139786 + config_opts.dcpid = sp->dcp_idx;
139787 + config_opts.sp_mapping.map_lni_id = lni->idx;
139788 + sp->lni = lni;
139789 +
139790 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
139791 + return -EINVAL;
139792 +
139793 + /* Enable CEETM mode for this sub-portal */
139794 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
139795 +}
139796 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
139797 +
139798 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
139799 +{
139800 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139801 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139802 +
139803 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
139804 + query_opts.dcpid = sp->dcp_idx;
139805 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
139806 + pr_err("Can't get SP <-> LNI mapping\n");
139807 + return -EINVAL;
139808 + }
139809 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
139810 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
139811 + return 0;
139812 +}
139813 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
139814 +
139815 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
139816 + int oal)
139817 +{
139818 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139819 +
139820 + if (lni->shaper_enable) {
139821 + pr_err("The shaper has already been enabled\n");
139822 + return -EINVAL;
139823 + }
139824 + lni->shaper_enable = 1;
139825 + lni->shaper_couple = coupled;
139826 + lni->oal = oal;
139827 +
139828 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139829 + config_opts.dcpid = lni->dcp_idx;
139830 + config_opts.shaper_config.cpl = coupled;
139831 + config_opts.shaper_config.oal = oal;
139832 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
139833 + << 13) | lni->cr_token_rate.fraction);
139834 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
139835 + << 13) | lni->er_token_rate.fraction);
139836 + config_opts.shaper_config.crtbl =
139837 + cpu_to_be16(lni->cr_token_bucket_limit);
139838 + config_opts.shaper_config.ertbl =
139839 + cpu_to_be16(lni->er_token_bucket_limit);
139840 + config_opts.shaper_config.mps = 60;
139841 +
139842 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139843 +}
139844 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
139845 +
139846 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
139847 +{
139848 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139849 +
139850 + if (!lni->shaper_enable) {
139851 + pr_err("The shaper has been disabled\n");
139852 + return -EINVAL;
139853 + }
139854 +
139855 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139856 + config_opts.dcpid = lni->dcp_idx;
139857 + config_opts.shaper_config.cpl = lni->shaper_couple;
139858 + config_opts.shaper_config.oal = lni->oal;
139859 + config_opts.shaper_config.crtbl =
139860 + cpu_to_be16(lni->cr_token_bucket_limit);
139861 + config_opts.shaper_config.ertbl =
139862 + cpu_to_be16(lni->er_token_bucket_limit);
139863 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
139864 + * disable the shaping.
139865 + */
139866 + config_opts.shaper_config.crtcr = 0xFFFFFF;
139867 + config_opts.shaper_config.ertcr = 0xFFFFFF;
139868 + config_opts.shaper_config.mps = 60;
139869 + lni->shaper_enable = 0;
139870 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139871 +}
139872 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
139873 +
139874 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
139875 +{
139876 + return lni->shaper_enable;
139877 +}
139878 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
139879 +
139880 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
139881 + const struct qm_ceetm_rate *token_rate,
139882 + u16 token_limit)
139883 +{
139884 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139885 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139886 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139887 + int ret;
139888 +
139889 + lni->cr_token_rate.whole = token_rate->whole;
139890 + lni->cr_token_rate.fraction = token_rate->fraction;
139891 + lni->cr_token_bucket_limit = token_limit;
139892 + if (!lni->shaper_enable)
139893 + return 0;
139894 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139895 + query_opts.dcpid = lni->dcp_idx;
139896 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139897 + &query_result);
139898 + if (ret) {
139899 + pr_err("Fail to get current LNI shaper setting\n");
139900 + return -EINVAL;
139901 + }
139902 +
139903 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139904 + config_opts.dcpid = lni->dcp_idx;
139905 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
139906 + | (token_rate->fraction));
139907 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
139908 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
139909 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
139910 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
139911 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
139912 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
139913 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
139914 +}
139915 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
139916 +
139917 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
139918 + u64 bps,
139919 + u16 token_limit)
139920 +{
139921 + struct qm_ceetm_rate token_rate;
139922 + int ret;
139923 +
139924 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
139925 + if (ret) {
139926 + pr_err("Can not convert bps to token rate\n");
139927 + return -EINVAL;
139928 + }
139929 +
139930 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
139931 +}
139932 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
139933 +
139934 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
139935 + struct qm_ceetm_rate *token_rate,
139936 + u16 *token_limit)
139937 +{
139938 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139939 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139940 + int ret;
139941 +
139942 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139943 + query_opts.dcpid = lni->dcp_idx;
139944 +
139945 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
139946 + if (ret) {
139947 + pr_err("The LNI CR rate or limit is not set\n");
139948 + return -EINVAL;
139949 + }
139950 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
139951 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
139952 + 0x1FFF;
139953 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
139954 + return 0;
139955 +}
139956 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
139957 +
139958 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
139959 + u64 *bps, u16 *token_limit)
139960 +{
139961 + struct qm_ceetm_rate token_rate;
139962 + int ret;
139963 +
139964 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
139965 + if (ret) {
139966 + pr_err("The LNI CR rate or limit is not available\n");
139967 + return -EINVAL;
139968 + }
139969 +
139970 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
139971 +}
139972 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
139973 +
139974 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
139975 + const struct qm_ceetm_rate *token_rate,
139976 + u16 token_limit)
139977 +{
139978 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
139979 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
139980 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
139981 + int ret;
139982 +
139983 + lni->er_token_rate.whole = token_rate->whole;
139984 + lni->er_token_rate.fraction = token_rate->fraction;
139985 + lni->er_token_bucket_limit = token_limit;
139986 + if (!lni->shaper_enable)
139987 + return 0;
139988 +
139989 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139990 + query_opts.dcpid = lni->dcp_idx;
139991 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
139992 + &query_result);
139993 + if (ret) {
139994 + pr_err("Fail to get current LNI shaper setting\n");
139995 + return -EINVAL;
139996 + }
139997 +
139998 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
139999 + config_opts.dcpid = lni->dcp_idx;
140000 + config_opts.shaper_config.ertcr = cpu_to_be24(
140001 + (token_rate->whole << 13) | (token_rate->fraction));
140002 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140003 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140004 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
140005 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140006 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140007 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
140008 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140009 +}
140010 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
140011 +
140012 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
140013 + u64 bps,
140014 + u16 token_limit)
140015 +{
140016 + struct qm_ceetm_rate token_rate;
140017 + int ret;
140018 +
140019 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140020 + if (ret) {
140021 + pr_err("Can not convert bps to token rate\n");
140022 + return -EINVAL;
140023 + }
140024 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
140025 +}
140026 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
140027 +
140028 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
140029 + struct qm_ceetm_rate *token_rate,
140030 + u16 *token_limit)
140031 +{
140032 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140033 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140034 + int ret;
140035 +
140036 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
140037 + query_opts.dcpid = lni->dcp_idx;
140038 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140039 + if (ret) {
140040 + pr_err("The LNI ER rate or limit is not set\n");
140041 + return -EINVAL;
140042 + }
140043 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140044 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140045 + 0x1FFF;
140046 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140047 + return 0;
140048 +}
140049 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
140050 +
140051 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
140052 + u64 *bps, u16 *token_limit)
140053 +{
140054 + struct qm_ceetm_rate token_rate;
140055 + int ret;
140056 +
140057 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
140058 + if (ret) {
140059 + pr_err("The LNI ER rate or limit is not available\n");
140060 + return -EINVAL;
140061 + }
140062 +
140063 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140064 +}
140065 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
140066 +
140067 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
140068 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
140069 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
140070 + unsigned int cq_level,
140071 + int traffic_class)
140072 +{
140073 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140074 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140075 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140076 + u64 lnitcfcc;
140077 +
140078 + if ((cq_level > 15) | (traffic_class > 7)) {
140079 + pr_err("The CQ or traffic class id is out of range\n");
140080 + return -EINVAL;
140081 + }
140082 +
140083 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140084 + query_opts.dcpid = lni->dcp_idx;
140085 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140086 + pr_err("Fail to query tcfcc\n");
140087 + return -EINVAL;
140088 + }
140089 +
140090 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
140091 + if (traffic_class == -1) {
140092 + /* disable tcfc for this CQ */
140093 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
140094 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140095 + } else {
140096 + lnitcfcc &= ~((u64)0xF <<
140097 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140098 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
140099 + traffic_class)) <<
140100 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
140101 + }
140102 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
140103 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140104 + config_opts.dcpid = lni->dcp_idx;
140105 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140106 +}
140107 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
140108 +
140109 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
140110 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
140111 + int *traffic_class)
140112 +{
140113 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140114 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140115 + int ret;
140116 + u8 lnitcfcc;
140117 +
140118 + if (cq_level > 15) {
140119 + pr_err("the CQ level is out of range\n");
140120 + return -EINVAL;
140121 + }
140122 +
140123 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
140124 + query_opts.dcpid = lni->dcp_idx;
140125 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140126 + if (ret)
140127 + return ret;
140128 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
140129 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
140130 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
140131 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
140132 + else
140133 + *traffic_class = -1;
140134 + return 0;
140135 +}
140136 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
140137 +
140138 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
140139 + struct qm_ceetm_lni *lni)
140140 +{
140141 + struct qm_ceetm_channel *p;
140142 + u32 channel_idx;
140143 + int ret = 0;
140144 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140145 +
140146 + if (lni->dcp_idx == qm_dc_portal_fman0) {
140147 + ret = qman_alloc_ceetm0_channel(&channel_idx);
140148 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
140149 + ret = qman_alloc_ceetm1_channel(&channel_idx);
140150 + } else {
140151 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140152 + lni->dcp_idx);
140153 + return -EINVAL;
140154 + }
140155 +
140156 + if (ret) {
140157 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
140158 + return -ENODEV;
140159 + }
140160 +
140161 + p = kzalloc(sizeof(*p), GFP_KERNEL);
140162 + if (!p)
140163 + return -ENOMEM;
140164 + p->idx = channel_idx;
140165 + p->dcp_idx = lni->dcp_idx;
140166 + p->lni_idx = lni->idx;
140167 + list_add_tail(&p->node, &lni->channels);
140168 + INIT_LIST_HEAD(&p->class_queues);
140169 + INIT_LIST_HEAD(&p->ccgs);
140170 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140171 + channel_idx);
140172 + config_opts.dcpid = lni->dcp_idx;
140173 + config_opts.channel_mapping.map_lni_id = lni->idx;
140174 + config_opts.channel_mapping.map_shaped = 0;
140175 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140176 + pr_err("Can't map channel#%d for LNI#%d\n",
140177 + channel_idx, lni->idx);
140178 + return -EINVAL;
140179 + }
140180 + *channel = p;
140181 + return 0;
140182 +}
140183 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
140184 +
140185 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
140186 +{
140187 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140188 + if (!list_empty(&channel->class_queues)) {
140189 + pr_err("CEETM channel#%d has class queue unreleased!\n",
140190 + channel->idx);
140191 + return -EBUSY;
140192 + }
140193 + if (!list_empty(&channel->ccgs)) {
140194 + pr_err("CEETM channel#%d has ccg unreleased!\n",
140195 + channel->idx);
140196 + return -EBUSY;
140197 + }
140198 +
140199 + /* channel->dcp_idx corresponds to known fman validation */
140200 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
140201 + (channel->dcp_idx != qm_dc_portal_fman1)) {
140202 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140203 + channel->dcp_idx);
140204 + return -EINVAL;
140205 + }
140206 +
140207 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140208 + channel->idx);
140209 + config_opts.dcpid = channel->dcp_idx;
140210 + memset(&config_opts.shaper_config, 0,
140211 + sizeof(config_opts.shaper_config));
140212 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140213 + pr_err("Can't reset channel shapping parameters\n");
140214 + return -EINVAL;
140215 + }
140216 +
140217 + if (channel->dcp_idx == qm_dc_portal_fman0) {
140218 + qman_release_ceetm0_channelid(channel->idx);
140219 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
140220 + qman_release_ceetm1_channelid(channel->idx);
140221 + } else {
140222 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
140223 + channel->dcp_idx);
140224 + return -EINVAL;
140225 + }
140226 + list_del(&channel->node);
140227 + kfree(channel);
140228 +
140229 + return 0;
140230 +}
140231 +EXPORT_SYMBOL(qman_ceetm_channel_release);
140232 +
140233 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
140234 + int coupled)
140235 +{
140236 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140237 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140238 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140239 +
140240 + if (channel->shaper_enable == 1) {
140241 + pr_err("This channel shaper has been enabled!\n");
140242 + return -EINVAL;
140243 + }
140244 +
140245 + channel->shaper_enable = 1;
140246 + channel->shaper_couple = coupled;
140247 +
140248 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140249 + channel->idx);
140250 + query_opts.dcpid = channel->dcp_idx;
140251 +
140252 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140253 + pr_err("Can't query channel mapping\n");
140254 + return -EINVAL;
140255 + }
140256 +
140257 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140258 + channel->idx);
140259 + config_opts.dcpid = channel->dcp_idx;
140260 + config_opts.channel_mapping.map_lni_id =
140261 + query_result.channel_mapping_query.map_lni_id;
140262 + config_opts.channel_mapping.map_shaped = 1;
140263 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
140264 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
140265 + return -EINVAL;
140266 + }
140267 +
140268 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140269 + channel->idx);
140270 + config_opts.shaper_config.cpl = coupled;
140271 + config_opts.shaper_config.crtcr =
140272 + cpu_to_be24((channel->cr_token_rate.whole
140273 + << 13) |
140274 + channel->cr_token_rate.fraction);
140275 + config_opts.shaper_config.ertcr =
140276 + cpu_to_be24(channel->er_token_rate.whole
140277 + << 13 |
140278 + channel->er_token_rate.fraction);
140279 + config_opts.shaper_config.crtbl =
140280 + cpu_to_be16(channel->cr_token_bucket_limit);
140281 + config_opts.shaper_config.ertbl =
140282 + cpu_to_be16(channel->er_token_bucket_limit);
140283 +
140284 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140285 +}
140286 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
140287 +
140288 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
140289 +{
140290 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140291 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140292 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140293 +
140294 +
140295 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140296 + channel->idx);
140297 + query_opts.dcpid = channel->dcp_idx;
140298 +
140299 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140300 + pr_err("Can't query channel mapping\n");
140301 + return -EINVAL;
140302 + }
140303 +
140304 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140305 + channel->idx);
140306 + config_opts.dcpid = channel->dcp_idx;
140307 + config_opts.channel_mapping.map_shaped = 0;
140308 + config_opts.channel_mapping.map_lni_id =
140309 + query_result.channel_mapping_query.map_lni_id;
140310 +
140311 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140312 +}
140313 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
140314 +
140315 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
140316 +{
140317 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140318 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140319 +
140320 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
140321 + channel->idx);
140322 + query_opts.dcpid = channel->dcp_idx;
140323 +
140324 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
140325 + pr_err("Can't query channel mapping\n");
140326 + return -EINVAL;
140327 + }
140328 +
140329 + return query_result.channel_mapping_query.map_shaped;
140330 +}
140331 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
140332 +
140333 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
140334 + const struct qm_ceetm_rate *token_rate,
140335 + u16 token_limit)
140336 +{
140337 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140338 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140339 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140340 + int ret;
140341 +
140342 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140343 + channel->idx);
140344 + query_opts.dcpid = channel->dcp_idx;
140345 +
140346 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140347 + if (ret) {
140348 + pr_err("Fail to get the current channel shaper setting\n");
140349 + return -EINVAL;
140350 + }
140351 +
140352 + channel->cr_token_rate.whole = token_rate->whole;
140353 + channel->cr_token_rate.fraction = token_rate->fraction;
140354 + channel->cr_token_bucket_limit = token_limit;
140355 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140356 + channel->idx);
140357 + config_opts.dcpid = channel->dcp_idx;
140358 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
140359 + << 13) | (token_rate->fraction));
140360 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140361 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140362 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
140363 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
140364 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140365 +}
140366 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
140367 +
140368 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
140369 + u64 bps, u16 token_limit)
140370 +{
140371 + struct qm_ceetm_rate token_rate;
140372 + int ret;
140373 +
140374 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140375 + if (ret) {
140376 + pr_err("Can not convert bps to token rate\n");
140377 + return -EINVAL;
140378 + }
140379 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
140380 + token_limit);
140381 +}
140382 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
140383 +
140384 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
140385 + struct qm_ceetm_rate *token_rate,
140386 + u16 *token_limit)
140387 +{
140388 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140389 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140390 + int ret;
140391 +
140392 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140393 + channel->idx);
140394 + query_opts.dcpid = channel->dcp_idx;
140395 +
140396 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140397 + if (ret | !query_result.shaper_query.crtcr |
140398 + !query_result.shaper_query.crtbl) {
140399 + pr_err("The channel commit rate or limit is not set\n");
140400 + return -EINVAL;
140401 + }
140402 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
140403 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
140404 + 0x1FFF;
140405 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140406 + return 0;
140407 +}
140408 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
140409 +
140410 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
140411 + u64 *bps, u16 *token_limit)
140412 +{
140413 + struct qm_ceetm_rate token_rate;
140414 + int ret;
140415 +
140416 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
140417 + token_limit);
140418 + if (ret) {
140419 + pr_err("The channel CR rate or limit is not available\n");
140420 + return -EINVAL;
140421 + }
140422 +
140423 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140424 +}
140425 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
140426 +
140427 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
140428 + const struct qm_ceetm_rate *token_rate,
140429 + u16 token_limit)
140430 +{
140431 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140432 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140433 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140434 + int ret;
140435 +
140436 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140437 + channel->idx);
140438 + query_opts.dcpid = channel->dcp_idx;
140439 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140440 + if (ret) {
140441 + pr_err("Fail to get the current channel shaper setting\n");
140442 + return -EINVAL;
140443 + }
140444 +
140445 + channel->er_token_rate.whole = token_rate->whole;
140446 + channel->er_token_rate.fraction = token_rate->fraction;
140447 + channel->er_token_bucket_limit = token_limit;
140448 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140449 + channel->idx);
140450 + config_opts.dcpid = channel->dcp_idx;
140451 + config_opts.shaper_config.ertcr = cpu_to_be24(
140452 + (token_rate->whole << 13) | (token_rate->fraction));
140453 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
140454 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
140455 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
140456 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
140457 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140458 +}
140459 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
140460 +
140461 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
140462 + u64 bps, u16 token_limit)
140463 +{
140464 + struct qm_ceetm_rate token_rate;
140465 + int ret;
140466 +
140467 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
140468 + if (ret) {
140469 + pr_err("Can not convert bps to token rate\n");
140470 + return -EINVAL;
140471 + }
140472 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
140473 + token_limit);
140474 +}
140475 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
140476 +
140477 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
140478 + struct qm_ceetm_rate *token_rate,
140479 + u16 *token_limit)
140480 +{
140481 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140482 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140483 + int ret;
140484 +
140485 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140486 + channel->idx);
140487 + query_opts.dcpid = channel->dcp_idx;
140488 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140489 + if (ret | !query_result.shaper_query.ertcr |
140490 + !query_result.shaper_query.ertbl) {
140491 + pr_err("The channel excess rate or limit is not set\n");
140492 + return -EINVAL;
140493 + }
140494 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
140495 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
140496 + 0x1FFF;
140497 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
140498 + return 0;
140499 +}
140500 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
140501 +
140502 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
140503 + u64 *bps, u16 *token_limit)
140504 +{
140505 + struct qm_ceetm_rate token_rate;
140506 + int ret;
140507 +
140508 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
140509 + token_limit);
140510 + if (ret) {
140511 + pr_err("The channel ER rate or limit is not available\n");
140512 + return -EINVAL;
140513 + }
140514 +
140515 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
140516 +}
140517 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
140518 +
140519 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
140520 + u16 token_limit)
140521 +{
140522 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
140523 +
140524 + if (channel->shaper_enable) {
140525 + pr_err("This channel is a shaped one\n");
140526 + return -EINVAL;
140527 + }
140528 +
140529 + channel->cr_token_bucket_limit = token_limit;
140530 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140531 + channel->idx);
140532 + config_opts.dcpid = channel->dcp_idx;
140533 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
140534 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
140535 +}
140536 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
140537 +
140538 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
140539 + u16 *token_limit)
140540 +{
140541 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
140542 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
140543 + int ret;
140544 +
140545 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
140546 + channel->idx);
140547 + query_opts.dcpid = channel->dcp_idx;
140548 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
140549 + if (ret | !query_result.shaper_query.crtbl) {
140550 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
140551 + return -EINVAL;
140552 + }
140553 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
140554 + return 0;
140555 +}
140556 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
140557 +
140558 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
140559 + unsigned int prio_a, unsigned int prio_b)
140560 +{
140561 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140562 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140563 + int i;
140564 +
140565 + if (prio_a > 7) {
140566 + pr_err("The priority of group A is out of range\n");
140567 + return -EINVAL;
140568 + }
140569 + if (group_b && (prio_b > 7)) {
140570 + pr_err("The priority of group B is out of range\n");
140571 + return -EINVAL;
140572 + }
140573 +
140574 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140575 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140576 + return -EINVAL;
140577 + }
140578 +
140579 + config_opts.cqcid = cpu_to_be16(channel->idx);
140580 + config_opts.dcpid = channel->dcp_idx;
140581 + config_opts.gpc_combine_flag = !group_b;
140582 + config_opts.gpc_prio_a = prio_a;
140583 + config_opts.gpc_prio_b = prio_b;
140584 +
140585 + for (i = 0; i < 8; i++)
140586 + config_opts.w[i] = query_result.w[i];
140587 + config_opts.crem = query_result.crem;
140588 + config_opts.erem = query_result.erem;
140589 +
140590 + return qman_ceetm_configure_class_scheduler(&config_opts);
140591 +}
140592 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
140593 +
140594 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
140595 + unsigned int *prio_a, unsigned int *prio_b)
140596 +{
140597 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140598 +
140599 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
140600 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
140601 + return -EINVAL;
140602 + }
140603 + *group_b = !query_result.gpc_combine_flag;
140604 + *prio_a = query_result.gpc_prio_a;
140605 + *prio_b = query_result.gpc_prio_b;
140606 +
140607 + return 0;
140608 +}
140609 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
140610 +
140611 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
140612 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
140613 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
140614 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
140615 + *channel, int group_b, int cre)
140616 +{
140617 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140618 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140619 + int i;
140620 +
140621 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140622 + pr_err("Cannot get the channel %d scheduler setting.\n",
140623 + channel->idx);
140624 + return -EINVAL;
140625 + }
140626 + csch_config.cqcid = cpu_to_be16(channel->idx);
140627 + csch_config.dcpid = channel->dcp_idx;
140628 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140629 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140630 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140631 +
140632 + for (i = 0; i < 8; i++)
140633 + csch_config.w[i] = csch_query.w[i];
140634 + csch_config.erem = csch_query.erem;
140635 + if (group_b)
140636 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140637 + & ~GROUP_B_ELIGIBILITY_SET)
140638 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
140639 + else
140640 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140641 + & ~GROUP_A_ELIGIBILITY_SET)
140642 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
140643 +
140644 + csch_config.crem = cpu_to_be16(csch_config.crem);
140645 +
140646 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140647 + pr_err("Cannot config channel %d's scheduler with "
140648 + "group_%c's cr eligibility\n", channel->idx,
140649 + group_b ? 'b' : 'a');
140650 + return -EINVAL;
140651 + }
140652 +
140653 + return 0;
140654 +}
140655 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
140656 +
140657 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
140658 + *channel, int group_b, int ere)
140659 +{
140660 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140661 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140662 + int i;
140663 +
140664 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140665 + pr_err("Cannot get the channel %d scheduler setting.\n",
140666 + channel->idx);
140667 + return -EINVAL;
140668 + }
140669 + csch_config.cqcid = cpu_to_be16(channel->idx);
140670 + csch_config.dcpid = channel->dcp_idx;
140671 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140672 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140673 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140674 +
140675 + for (i = 0; i < 8; i++)
140676 + csch_config.w[i] = csch_query.w[i];
140677 + csch_config.crem = csch_query.crem;
140678 + if (group_b)
140679 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140680 + & ~GROUP_B_ELIGIBILITY_SET)
140681 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
140682 + else
140683 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140684 + & ~GROUP_A_ELIGIBILITY_SET)
140685 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
140686 +
140687 + csch_config.erem = cpu_to_be16(csch_config.erem);
140688 +
140689 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140690 + pr_err("Cannot config channel %d's scheduler with "
140691 + "group_%c's er eligibility\n", channel->idx,
140692 + group_b ? 'b' : 'a');
140693 + return -EINVAL;
140694 + }
140695 +
140696 + return 0;
140697 +}
140698 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
140699 +
140700 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
140701 + unsigned int idx, int cre)
140702 +{
140703 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140704 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140705 + int i;
140706 +
140707 + if (idx > 7) {
140708 + pr_err("CQ index is out of range\n");
140709 + return -EINVAL;
140710 + }
140711 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140712 + pr_err("Cannot get the channel %d scheduler setting.\n",
140713 + channel->idx);
140714 + return -EINVAL;
140715 + }
140716 + csch_config.cqcid = cpu_to_be16(channel->idx);
140717 + csch_config.dcpid = channel->dcp_idx;
140718 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140719 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140720 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140721 + for (i = 0; i < 8; i++)
140722 + csch_config.w[i] = csch_query.w[i];
140723 + csch_config.erem = csch_query.erem;
140724 + csch_config.crem = (be16_to_cpu(csch_query.crem)
140725 + & ~CQ_ELIGIBILITY_SET(idx)) |
140726 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
140727 + csch_config.crem = cpu_to_be16(csch_config.crem);
140728 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140729 + pr_err("Cannot config channel scheduler to set "
140730 + "cr eligibility mask for CQ#%d\n", idx);
140731 + return -EINVAL;
140732 + }
140733 +
140734 + return 0;
140735 +}
140736 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
140737 +
140738 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
140739 + unsigned int idx, int ere)
140740 +{
140741 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
140742 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
140743 + int i;
140744 +
140745 + if (idx > 7) {
140746 + pr_err("CQ index is out of range\n");
140747 + return -EINVAL;
140748 + }
140749 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
140750 + pr_err("Cannot get the channel %d scheduler setting.\n",
140751 + channel->idx);
140752 + return -EINVAL;
140753 + }
140754 + csch_config.cqcid = cpu_to_be16(channel->idx);
140755 + csch_config.dcpid = channel->dcp_idx;
140756 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
140757 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
140758 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
140759 + for (i = 0; i < 8; i++)
140760 + csch_config.w[i] = csch_query.w[i];
140761 + csch_config.crem = csch_query.crem;
140762 + csch_config.erem = (be16_to_cpu(csch_query.erem)
140763 + & ~CQ_ELIGIBILITY_SET(idx)) |
140764 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
140765 + csch_config.erem = cpu_to_be16(csch_config.erem);
140766 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
140767 + pr_err("Cannot config channel scheduler to set "
140768 + "er eligibility mask for CQ#%d\n", idx);
140769 + return -EINVAL;
140770 + }
140771 + return 0;
140772 +}
140773 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
140774 +
140775 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
140776 + struct qm_ceetm_channel *channel, unsigned int idx,
140777 + struct qm_ceetm_ccg *ccg)
140778 +{
140779 + struct qm_ceetm_cq *p;
140780 + struct qm_mcc_ceetm_cq_config cq_config;
140781 +
140782 + if (idx > 7) {
140783 + pr_err("The independent class queue id is out of range\n");
140784 + return -EINVAL;
140785 + }
140786 +
140787 + list_for_each_entry(p, &channel->class_queues, node) {
140788 + if (p->idx == idx) {
140789 + pr_err("The CQ#%d has been claimed!\n", idx);
140790 + return -EINVAL;
140791 + }
140792 + }
140793 +
140794 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140795 + if (!p) {
140796 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140797 + return -ENOMEM;
140798 + }
140799 +
140800 + list_add_tail(&p->node, &channel->class_queues);
140801 + p->idx = idx;
140802 + p->is_claimed = 1;
140803 + p->parent = channel;
140804 + INIT_LIST_HEAD(&p->bound_lfqids);
140805 +
140806 + if (ccg) {
140807 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140808 + cq_config.dcpid = channel->dcp_idx;
140809 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140810 + if (qman_ceetm_configure_cq(&cq_config)) {
140811 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140812 + idx, ccg->idx);
140813 + list_del(&p->node);
140814 + kfree(p);
140815 + return -EINVAL;
140816 + }
140817 + }
140818 +
140819 + *cq = p;
140820 + return 0;
140821 +}
140822 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
140823 +
140824 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
140825 + struct qm_ceetm_channel *channel, unsigned int idx,
140826 + struct qm_ceetm_ccg *ccg)
140827 +{
140828 + struct qm_ceetm_cq *p;
140829 + struct qm_mcc_ceetm_cq_config cq_config;
140830 +
140831 + if ((idx < 8) || (idx > 15)) {
140832 + pr_err("This grouped class queue id is out of range\n");
140833 + return -EINVAL;
140834 + }
140835 +
140836 + list_for_each_entry(p, &channel->class_queues, node) {
140837 + if (p->idx == idx) {
140838 + pr_err("The CQ#%d has been claimed!\n", idx);
140839 + return -EINVAL;
140840 + }
140841 + }
140842 +
140843 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140844 + if (!p) {
140845 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140846 + return -ENOMEM;
140847 + }
140848 +
140849 + list_add_tail(&p->node, &channel->class_queues);
140850 + p->idx = idx;
140851 + p->is_claimed = 1;
140852 + p->parent = channel;
140853 + INIT_LIST_HEAD(&p->bound_lfqids);
140854 +
140855 + if (ccg) {
140856 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140857 + cq_config.dcpid = channel->dcp_idx;
140858 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140859 + if (qman_ceetm_configure_cq(&cq_config)) {
140860 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140861 + idx, ccg->idx);
140862 + list_del(&p->node);
140863 + kfree(p);
140864 + return -EINVAL;
140865 + }
140866 + }
140867 + *cq = p;
140868 + return 0;
140869 +}
140870 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
140871 +
140872 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
140873 + struct qm_ceetm_channel *channel, unsigned int idx,
140874 + struct qm_ceetm_ccg *ccg)
140875 +{
140876 + struct qm_ceetm_cq *p;
140877 + struct qm_mcc_ceetm_cq_config cq_config;
140878 +
140879 + if ((idx < 12) || (idx > 15)) {
140880 + pr_err("This grouped class queue id is out of range\n");
140881 + return -EINVAL;
140882 + }
140883 +
140884 + list_for_each_entry(p, &channel->class_queues, node) {
140885 + if (p->idx == idx) {
140886 + pr_err("The CQ#%d has been claimed!\n", idx);
140887 + return -EINVAL;
140888 + }
140889 + }
140890 +
140891 + p = kmalloc(sizeof(*p), GFP_KERNEL);
140892 + if (!p) {
140893 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
140894 + return -ENOMEM;
140895 + }
140896 +
140897 + list_add_tail(&p->node, &channel->class_queues);
140898 + p->idx = idx;
140899 + p->is_claimed = 1;
140900 + p->parent = channel;
140901 + INIT_LIST_HEAD(&p->bound_lfqids);
140902 +
140903 + if (ccg) {
140904 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
140905 + cq_config.dcpid = channel->dcp_idx;
140906 + cq_config.ccgid = cpu_to_be16(ccg->idx);
140907 + if (qman_ceetm_configure_cq(&cq_config)) {
140908 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
140909 + idx, ccg->idx);
140910 + list_del(&p->node);
140911 + kfree(p);
140912 + return -EINVAL;
140913 + }
140914 + }
140915 + *cq = p;
140916 + return 0;
140917 +}
140918 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
140919 +
140920 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
140921 +{
140922 + if (!list_empty(&cq->bound_lfqids)) {
140923 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
140924 + return -EBUSY;
140925 + }
140926 + list_del(&cq->node);
140927 + qman_ceetm_drain_cq(cq);
140928 + kfree(cq);
140929 + return 0;
140930 +}
140931 +EXPORT_SYMBOL(qman_ceetm_cq_release);
140932 +
140933 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
140934 + struct qm_ceetm_weight_code *weight_code)
140935 +{
140936 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
140937 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140938 + int i;
140939 +
140940 + if (cq->idx < 8) {
140941 + pr_err("Can not set weight for ungrouped class queue\n");
140942 + return -EINVAL;
140943 + }
140944 +
140945 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
140946 + pr_err("Can't query channel#%d's scheduler!\n",
140947 + cq->parent->idx);
140948 + return -EINVAL;
140949 + }
140950 +
140951 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
140952 + config_opts.dcpid = cq->parent->dcp_idx;
140953 + config_opts.crem = query_result.crem;
140954 + config_opts.erem = query_result.erem;
140955 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
140956 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
140957 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
140958 +
140959 + for (i = 0; i < 8; i++)
140960 + config_opts.w[i] = query_result.w[i];
140961 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
140962 + (weight_code->x & 0x7));
140963 + return qman_ceetm_configure_class_scheduler(&config_opts);
140964 +}
140965 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
140966 +
140967 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
140968 + struct qm_ceetm_weight_code *weight_code)
140969 +{
140970 + struct qm_mcr_ceetm_class_scheduler_query query_result;
140971 +
140972 + if (cq->idx < 8) {
140973 + pr_err("Can not get weight for ungrouped class queue\n");
140974 + return -EINVAL;
140975 + }
140976 +
140977 + if (qman_ceetm_query_class_scheduler(cq->parent,
140978 + &query_result)) {
140979 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
140980 + return -EINVAL;
140981 + }
140982 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
140983 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
140984 +
140985 + return 0;
140986 +}
140987 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
140988 +
140989 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
140990 + * effective weight = 2^x / (1 - (y/64))
140991 + * = 2^(x+6) / (64 - y)
140992 + */
140993 +static void reduce_fraction(u32 *n, u32 *d)
140994 +{
140995 + u32 factor = 2;
140996 + u32 lesser = (*n < *d) ? *n : *d;
140997 + /* If factor exceeds the square-root of the lesser of *n and *d,
140998 + * then there's no point continuing. Proof: if there was a factor
140999 + * bigger than the square root, that would imply there exists
141000 + * another factor smaller than the square-root with which it
141001 + * multiplies to give 'lesser' - but that's a contradiction
141002 + * because the other factor would have already been found and
141003 + * divided out.
141004 + */
141005 + while ((factor * factor) <= lesser) {
141006 + /* If 'factor' is a factor of *n and *d, divide them both
141007 + * by 'factor' as many times as possible.
141008 + */
141009 + while (!(*n % factor) && !(*d % factor)) {
141010 + *n /= factor;
141011 + *d /= factor;
141012 + lesser /= factor;
141013 + }
141014 + if (factor == 2)
141015 + factor = 3;
141016 + else
141017 + factor += 2;
141018 + }
141019 +}
141020 +
141021 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
141022 + u32 *numerator,
141023 + u32 *denominator)
141024 +{
141025 + *numerator = (u32) 1 << (weight_code->x + 6);
141026 + *denominator = 64 - weight_code->y;
141027 + reduce_fraction(numerator, denominator);
141028 + return 0;
141029 +}
141030 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
141031 +
141032 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
141033 + * So find 'x' by range, and then estimate 'y' using:
141034 + * 64 - y = 2^(x + 6) / weight
141035 + * = 2^(x + 6) / (n/d)
141036 + * = d * 2^(x+6) / n
141037 + * y = 64 - (d * 2^(x+6) / n)
141038 + */
141039 +int qman_ceetm_ratio2wbfs(u32 numerator,
141040 + u32 denominator,
141041 + struct qm_ceetm_weight_code *weight_code,
141042 + int rounding)
141043 +{
141044 + unsigned int y, x = 0;
141045 + /* search incrementing 'x' until:
141046 + * weight < 2^(x+1)
141047 + * n/d < 2^(x+1)
141048 + * n < d * 2^(x+1)
141049 + */
141050 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
141051 + x++;
141052 + if (x >= 8)
141053 + return -ERANGE;
141054 + /* because of the subtraction, use '-rounding' */
141055 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
141056 + if (y >= 32)
141057 + return -ERANGE;
141058 + weight_code->x = x;
141059 + weight_code->y = y;
141060 + return 0;
141061 +}
141062 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
141063 +
141064 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
141065 +{
141066 + struct qm_ceetm_weight_code weight_code;
141067 +
141068 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
141069 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
141070 + return -EINVAL;
141071 + }
141072 + return qman_ceetm_set_queue_weight(cq, &weight_code);
141073 +}
141074 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
141075 +
141076 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
141077 +{
141078 + struct qm_ceetm_weight_code weight_code;
141079 + u32 n, d;
141080 +
141081 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
141082 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
141083 + return -EINVAL;
141084 + }
141085 +
141086 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
141087 + pr_err("Cannot get the ratio with wbfs code\n");
141088 + return -EINVAL;
141089 + }
141090 +
141091 + *ratio = (n * 100) / d;
141092 + return 0;
141093 +}
141094 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
141095 +
141096 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
141097 + u64 *frame_count, u64 *byte_count)
141098 +{
141099 + struct qm_mcr_ceetm_statistics_query result;
141100 + u16 cid, command_type;
141101 + enum qm_dc_portal dcp_idx;
141102 + int ret;
141103 +
141104 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
141105 + dcp_idx = cq->parent->dcp_idx;
141106 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141107 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
141108 + else
141109 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
141110 +
141111 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141112 + if (ret) {
141113 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
141114 + return -EINVAL;
141115 + }
141116 +
141117 + *frame_count = be40_to_cpu(result.frm_cnt);
141118 + *byte_count = be48_to_cpu(result.byte_cnt);
141119 + return 0;
141120 +}
141121 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
141122 +
141123 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
141124 +{
141125 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
141126 + int ret;
141127 +
141128 + do {
141129 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
141130 + if (ret) {
141131 + pr_err("Failed to pop frame from CQ\n");
141132 + return -EINVAL;
141133 + }
141134 + } while (!(ppxr.stat & 0x2));
141135 +
141136 + return 0;
141137 +}
141138 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
141139 +
141140 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
141141 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
141142 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
141143 + struct qm_ceetm_cq *cq)
141144 +{
141145 + struct qm_ceetm_lfq *p;
141146 + u32 lfqid;
141147 + int ret = 0;
141148 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
141149 +
141150 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
141151 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
141152 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
141153 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
141154 + } else {
141155 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141156 + cq->parent->dcp_idx);
141157 + return -EINVAL;
141158 + }
141159 +
141160 + if (ret) {
141161 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
141162 + return -ENODEV;
141163 + }
141164 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141165 + if (!p)
141166 + return -ENOMEM;
141167 + p->idx = lfqid;
141168 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
141169 + p->parent = cq->parent;
141170 + list_add_tail(&p->node, &cq->bound_lfqids);
141171 +
141172 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
141173 + (cq->parent->dcp_idx << 16) |
141174 + (lfqid & CEETM_LFQMT_LFQID_LSB));
141175 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
141176 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
141177 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
141178 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
141179 + lfqid, cq->idx);
141180 + list_del(&p->node);
141181 + kfree(p);
141182 + return -EINVAL;
141183 + }
141184 + *lfq = p;
141185 + return 0;
141186 +}
141187 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
141188 +
141189 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
141190 +{
141191 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
141192 + qman_release_ceetm0_lfqid(lfq->idx);
141193 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
141194 + qman_release_ceetm1_lfqid(lfq->idx);
141195 + } else {
141196 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141197 + lfq->parent->dcp_idx);
141198 + return -EINVAL;
141199 + }
141200 + list_del(&lfq->node);
141201 + kfree(lfq);
141202 + return 0;
141203 +}
141204 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
141205 +
141206 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
141207 + u32 context_b)
141208 +{
141209 + struct qm_mcc_ceetm_dct_config dct_config;
141210 + lfq->context_a = context_a;
141211 + lfq->context_b = context_b;
141212 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
141213 + dct_config.dcpid = lfq->parent->dcp_idx;
141214 + dct_config.context_b = cpu_to_be32(context_b);
141215 + dct_config.context_a = cpu_to_be64(context_a);
141216 +
141217 + return qman_ceetm_configure_dct(&dct_config);
141218 +}
141219 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
141220 +
141221 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
141222 + u32 *context_b)
141223 +{
141224 + struct qm_mcc_ceetm_dct_query dct_query;
141225 + struct qm_mcr_ceetm_dct_query query_result;
141226 +
141227 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
141228 + dct_query.dcpid = lfq->parent->dcp_idx;
141229 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
141230 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
141231 + return -EINVAL;
141232 + }
141233 + *context_a = be64_to_cpu(query_result.context_a);
141234 + *context_b = be32_to_cpu(query_result.context_b);
141235 + return 0;
141236 +}
141237 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
141238 +
141239 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
141240 +{
141241 + spin_lock_init(&fq->fqlock);
141242 + fq->fqid = lfq->idx;
141243 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
141244 + if (lfq->ern)
141245 + fq->cb.ern = lfq->ern;
141246 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
141247 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
141248 + return -ENOMEM;
141249 +#endif
141250 + return 0;
141251 +}
141252 +EXPORT_SYMBOL(qman_ceetm_create_fq);
141253 +
141254 +#define MAX_CCG_IDX 0x000F
141255 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
141256 + struct qm_ceetm_channel *channel,
141257 + unsigned int idx,
141258 + void (*cscn)(struct qm_ceetm_ccg *,
141259 + void *cb_ctx,
141260 + int congested),
141261 + void *cb_ctx)
141262 +{
141263 + struct qm_ceetm_ccg *p;
141264 +
141265 + if (idx > MAX_CCG_IDX) {
141266 + pr_err("The given ccg index is out of range\n");
141267 + return -EINVAL;
141268 + }
141269 +
141270 + list_for_each_entry(p, &channel->ccgs, node) {
141271 + if (p->idx == idx) {
141272 + pr_err("The CCG#%d has been claimed\n", idx);
141273 + return -EINVAL;
141274 + }
141275 + }
141276 +
141277 + p = kmalloc(sizeof(*p), GFP_KERNEL);
141278 + if (!p) {
141279 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
141280 + return -ENOMEM;
141281 + }
141282 +
141283 + list_add_tail(&p->node, &channel->ccgs);
141284 +
141285 + p->idx = idx;
141286 + p->parent = channel;
141287 + p->cb = cscn;
141288 + p->cb_ctx = cb_ctx;
141289 + INIT_LIST_HEAD(&p->cb_node);
141290 +
141291 + *ccg = p;
141292 + return 0;
141293 +}
141294 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
141295 +
141296 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
141297 +{
141298 + unsigned long irqflags __maybe_unused;
141299 + struct qm_mcc_ceetm_ccgr_config config_opts;
141300 + int ret = 0;
141301 + struct qman_portal *p = get_affine_portal();
141302 +
141303 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141304 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141305 + if (!list_empty(&ccg->cb_node))
141306 + list_del(&ccg->cb_node);
141307 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141308 + (ccg->parent->idx << 4) | ccg->idx);
141309 + config_opts.dcpid = ccg->parent->dcp_idx;
141310 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
141311 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
141312 + ret = qman_ceetm_configure_ccgr(&config_opts);
141313 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141314 + put_affine_portal();
141315 +
141316 + list_del(&ccg->node);
141317 + kfree(ccg);
141318 + return ret;
141319 +}
141320 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
141321 +
141322 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
141323 + const struct qm_ceetm_ccg_params *params)
141324 +{
141325 + struct qm_mcc_ceetm_ccgr_config config_opts;
141326 + unsigned long irqflags __maybe_unused;
141327 + int ret;
141328 + struct qman_portal *p;
141329 +
141330 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
141331 + return -EINVAL;
141332 +
141333 + p = get_affine_portal();
141334 +
141335 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
141336 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
141337 +
141338 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141339 + (ccg->parent->idx << 4) | ccg->idx);
141340 + config_opts.dcpid = ccg->parent->dcp_idx;
141341 + config_opts.we_mask = we_mask;
141342 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
141343 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
141344 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
141345 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
141346 + }
141347 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
141348 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141349 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141350 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141351 + config_opts.cm_config.ctl_td_en = params->td_en;
141352 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141353 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141354 + config_opts.cm_config.ctl_mode = params->mode;
141355 + config_opts.cm_config.oal = params->oal;
141356 + config_opts.cm_config.cs_thres.hword =
141357 + cpu_to_be16(params->cs_thres_in.hword);
141358 + config_opts.cm_config.cs_thres_x.hword =
141359 + cpu_to_be16(params->cs_thres_out.hword);
141360 + config_opts.cm_config.td_thres.hword =
141361 + cpu_to_be16(params->td_thres.hword);
141362 + config_opts.cm_config.wr_parm_g.word =
141363 + cpu_to_be32(params->wr_parm_g.word);
141364 + config_opts.cm_config.wr_parm_y.word =
141365 + cpu_to_be32(params->wr_parm_y.word);
141366 + config_opts.cm_config.wr_parm_r.word =
141367 + cpu_to_be32(params->wr_parm_r.word);
141368 + ret = qman_ceetm_configure_ccgr(&config_opts);
141369 + if (ret) {
141370 + pr_err("Configure CCGR CM failed!\n");
141371 + goto release_lock;
141372 + }
141373 +
141374 + if (we_mask & QM_CCGR_WE_CSCN_EN)
141375 + if (list_empty(&ccg->cb_node))
141376 + list_add(&ccg->cb_node,
141377 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
141378 +release_lock:
141379 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
141380 + put_affine_portal();
141381 + return ret;
141382 +}
141383 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
141384 +
141385 +#define CEETM_CCGR_CTL_MASK 0x01
141386 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
141387 + struct qm_ceetm_ccg_params *params)
141388 +{
141389 + struct qm_mcc_ceetm_ccgr_query query_opts;
141390 + struct qm_mcr_ceetm_ccgr_query query_result;
141391 +
141392 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141393 + (ccg->parent->idx << 4) | ccg->idx);
141394 + query_opts.dcpid = ccg->parent->dcp_idx;
141395 +
141396 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141397 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141398 + return -EINVAL;
141399 + }
141400 +
141401 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
141402 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
141403 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
141404 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
141405 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
141406 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
141407 + params->oal = query_result.cm_query.oal;
141408 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
141409 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
141410 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
141411 + params->td_en = query_result.cm_query.ctl_td_en;
141412 + params->td_mode = query_result.cm_query.ctl_td_mode;
141413 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
141414 + params->mode = query_result.cm_query.ctl_mode;
141415 +
141416 + return 0;
141417 +}
141418 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
141419 +
141420 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
141421 + u64 *frame_count, u64 *byte_count)
141422 +{
141423 + struct qm_mcr_ceetm_statistics_query result;
141424 + u16 cid, command_type;
141425 + enum qm_dc_portal dcp_idx;
141426 + int ret;
141427 +
141428 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
141429 + dcp_idx = ccg->parent->dcp_idx;
141430 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
141431 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
141432 + else
141433 + command_type = CEETM_QUERY_REJECT_STATISTICS;
141434 +
141435 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
141436 + if (ret) {
141437 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
141438 + return -EINVAL;
141439 + }
141440 +
141441 + *frame_count = be40_to_cpu(result.frm_cnt);
141442 + *byte_count = be48_to_cpu(result.byte_cnt);
141443 + return 0;
141444 +}
141445 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
141446 +
141447 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
141448 + u16 swp_idx,
141449 + unsigned int *cscn_enabled)
141450 +{
141451 + struct qm_mcc_ceetm_ccgr_query query_opts;
141452 + struct qm_mcr_ceetm_ccgr_query query_result;
141453 + int i;
141454 +
141455 + DPA_ASSERT(swp_idx < 127);
141456 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141457 + (ccg->parent->idx << 4) | ccg->idx);
141458 + query_opts.dcpid = ccg->parent->dcp_idx;
141459 +
141460 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141461 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141462 + return -EINVAL;
141463 + }
141464 +
141465 + i = swp_idx / 32;
141466 + i = 3 - i;
141467 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
141468 + (31 - swp_idx % 32);
141469 +
141470 + return 0;
141471 +}
141472 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
141473 +
141474 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
141475 + u16 dcp_idx,
141476 + u8 vcgid,
141477 + unsigned int cscn_enabled,
141478 + u16 we_mask,
141479 + const struct qm_ceetm_ccg_params *params)
141480 +{
141481 + struct qm_mcc_ceetm_ccgr_config config_opts;
141482 + int ret;
141483 +
141484 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
141485 + (ccg->parent->idx << 4) | ccg->idx);
141486 + config_opts.dcpid = ccg->parent->dcp_idx;
141487 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
141488 + QM_CCGR_WE_CDV);
141489 + config_opts.cm_config.cdv = vcgid;
141490 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
141491 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
141492 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
141493 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
141494 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
141495 + config_opts.cm_config.ctl_td_en = params->td_en;
141496 + config_opts.cm_config.ctl_td_mode = params->td_mode;
141497 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
141498 + config_opts.cm_config.ctl_mode = params->mode;
141499 + config_opts.cm_config.cs_thres.hword =
141500 + cpu_to_be16(params->cs_thres_in.hword);
141501 + config_opts.cm_config.cs_thres_x.hword =
141502 + cpu_to_be16(params->cs_thres_out.hword);
141503 + config_opts.cm_config.td_thres.hword =
141504 + cpu_to_be16(params->td_thres.hword);
141505 + config_opts.cm_config.wr_parm_g.word =
141506 + cpu_to_be32(params->wr_parm_g.word);
141507 + config_opts.cm_config.wr_parm_y.word =
141508 + cpu_to_be32(params->wr_parm_y.word);
141509 + config_opts.cm_config.wr_parm_r.word =
141510 + cpu_to_be32(params->wr_parm_r.word);
141511 +
141512 + ret = qman_ceetm_configure_ccgr(&config_opts);
141513 + if (ret) {
141514 + pr_err("Configure CSCN_TARG_DCP failed!\n");
141515 + return -EINVAL;
141516 + }
141517 + return 0;
141518 +}
141519 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
141520 +
141521 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
141522 + u16 dcp_idx,
141523 + u8 *vcgid,
141524 + unsigned int *cscn_enabled)
141525 +{
141526 + struct qm_mcc_ceetm_ccgr_query query_opts;
141527 + struct qm_mcr_ceetm_ccgr_query query_result;
141528 +
141529 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
141530 + (ccg->parent->idx << 4) | ccg->idx);
141531 + query_opts.dcpid = ccg->parent->dcp_idx;
141532 +
141533 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
141534 + pr_err("Can't query CCGR#%d\n", ccg->idx);
141535 + return -EINVAL;
141536 + }
141537 +
141538 + *vcgid = query_result.cm_query.cdv;
141539 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
141540 + return 0;
141541 +}
141542 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
141543 +
141544 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
141545 + unsigned int dcp_idx)
141546 +{
141547 + struct qm_mc_command *mcc;
141548 + struct qm_mc_result *mcr;
141549 + struct qman_portal *p;
141550 + unsigned long irqflags __maybe_unused;
141551 + u8 res;
141552 + int i, j;
141553 +
141554 + p = get_affine_portal();
141555 + PORTAL_IRQ_LOCK(p, irqflags);
141556 +
141557 + mcc = qm_mc_start(&p->p);
141558 + for (i = 0; i < 2; i++) {
141559 + mcc->ccgr_query.ccgrid =
141560 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
141561 + mcc->ccgr_query.dcpid = dcp_idx;
141562 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141563 +
141564 + while (!(mcr = qm_mc_result(&p->p)))
141565 + cpu_relax();
141566 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141567 + QM_CEETM_VERB_CCGR_QUERY);
141568 + res = mcr->result;
141569 + if (res == QM_MCR_RESULT_OK) {
141570 + for (j = 0; j < 8; j++)
141571 + mcr->ccgr_query.congestion_state.state.
141572 + __state[j] = be32_to_cpu(mcr->ccgr_query.
141573 + congestion_state.state.__state[j]);
141574 + *(ccg_state + i) =
141575 + mcr->ccgr_query.congestion_state.state;
141576 + } else {
141577 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
141578 + PORTAL_IRQ_UNLOCK(p, irqflags);
141579 + return -EIO;
141580 + }
141581 + }
141582 + PORTAL_IRQ_UNLOCK(p, irqflags);
141583 + put_affine_portal();
141584 + return 0;
141585 +}
141586 +
141587 +int qman_set_wpm(int wpm_enable)
141588 +{
141589 + return qm_set_wpm(wpm_enable);
141590 +}
141591 +EXPORT_SYMBOL(qman_set_wpm);
141592 +
141593 +int qman_get_wpm(int *wpm_enable)
141594 +{
141595 + return qm_get_wpm(wpm_enable);
141596 +}
141597 +EXPORT_SYMBOL(qman_get_wpm);
141598 +
141599 +int qman_shutdown_fq(u32 fqid)
141600 +{
141601 + struct qman_portal *p;
141602 + unsigned long irqflags __maybe_unused;
141603 + int ret;
141604 + struct qm_portal *low_p;
141605 + p = get_affine_portal();
141606 + PORTAL_IRQ_LOCK(p, irqflags);
141607 + low_p = &p->p;
141608 + ret = qm_shutdown_fq(&low_p, 1, fqid);
141609 + PORTAL_IRQ_UNLOCK(p, irqflags);
141610 + put_affine_portal();
141611 + return ret;
141612 +}
141613 +
141614 +const struct qm_portal_config *qman_get_qm_portal_config(
141615 + struct qman_portal *portal)
141616 +{
141617 + return portal->sharing_redirect ? NULL : portal->config;
141618 +}
141619 --- /dev/null
141620 +++ b/drivers/staging/fsl_qbman/qman_low.h
141621 @@ -0,0 +1,1442 @@
141622 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
141623 + *
141624 + * Redistribution and use in source and binary forms, with or without
141625 + * modification, are permitted provided that the following conditions are met:
141626 + * * Redistributions of source code must retain the above copyright
141627 + * notice, this list of conditions and the following disclaimer.
141628 + * * Redistributions in binary form must reproduce the above copyright
141629 + * notice, this list of conditions and the following disclaimer in the
141630 + * documentation and/or other materials provided with the distribution.
141631 + * * Neither the name of Freescale Semiconductor nor the
141632 + * names of its contributors may be used to endorse or promote products
141633 + * derived from this software without specific prior written permission.
141634 + *
141635 + *
141636 + * ALTERNATIVELY, this software may be distributed under the terms of the
141637 + * GNU General Public License ("GPL") as published by the Free Software
141638 + * Foundation, either version 2 of that License or (at your option) any
141639 + * later version.
141640 + *
141641 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
141642 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
141643 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
141644 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
141645 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
141646 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
141647 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
141648 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
141649 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
141650 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
141651 + */
141652 +
141653 +#include "qman_private.h"
141654 +
141655 +/***************************/
141656 +/* Portal register assists */
141657 +/***************************/
141658 +
141659 +/* Cache-inhibited register offsets */
141660 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
141661 +
141662 +#define QM_REG_EQCR_PI_CINH 0x0000
141663 +#define QM_REG_EQCR_CI_CINH 0x0004
141664 +#define QM_REG_EQCR_ITR 0x0008
141665 +#define QM_REG_DQRR_PI_CINH 0x0040
141666 +#define QM_REG_DQRR_CI_CINH 0x0044
141667 +#define QM_REG_DQRR_ITR 0x0048
141668 +#define QM_REG_DQRR_DCAP 0x0050
141669 +#define QM_REG_DQRR_SDQCR 0x0054
141670 +#define QM_REG_DQRR_VDQCR 0x0058
141671 +#define QM_REG_DQRR_PDQCR 0x005c
141672 +#define QM_REG_MR_PI_CINH 0x0080
141673 +#define QM_REG_MR_CI_CINH 0x0084
141674 +#define QM_REG_MR_ITR 0x0088
141675 +#define QM_REG_CFG 0x0100
141676 +#define QM_REG_ISR 0x0e00
141677 +#define QM_REG_IIR 0x0e0c
141678 +#define QM_REG_ITPR 0x0e14
141679 +
141680 +/* Cache-enabled register offsets */
141681 +#define QM_CL_EQCR 0x0000
141682 +#define QM_CL_DQRR 0x1000
141683 +#define QM_CL_MR 0x2000
141684 +#define QM_CL_EQCR_PI_CENA 0x3000
141685 +#define QM_CL_EQCR_CI_CENA 0x3100
141686 +#define QM_CL_DQRR_PI_CENA 0x3200
141687 +#define QM_CL_DQRR_CI_CENA 0x3300
141688 +#define QM_CL_MR_PI_CENA 0x3400
141689 +#define QM_CL_MR_CI_CENA 0x3500
141690 +#define QM_CL_CR 0x3800
141691 +#define QM_CL_RR0 0x3900
141692 +#define QM_CL_RR1 0x3940
141693 +
141694 +#endif
141695 +
141696 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
141697 +
141698 +#define QM_REG_EQCR_PI_CINH 0x3000
141699 +#define QM_REG_EQCR_CI_CINH 0x3040
141700 +#define QM_REG_EQCR_ITR 0x3080
141701 +#define QM_REG_DQRR_PI_CINH 0x3100
141702 +#define QM_REG_DQRR_CI_CINH 0x3140
141703 +#define QM_REG_DQRR_ITR 0x3180
141704 +#define QM_REG_DQRR_DCAP 0x31C0
141705 +#define QM_REG_DQRR_SDQCR 0x3200
141706 +#define QM_REG_DQRR_VDQCR 0x3240
141707 +#define QM_REG_DQRR_PDQCR 0x3280
141708 +#define QM_REG_MR_PI_CINH 0x3300
141709 +#define QM_REG_MR_CI_CINH 0x3340
141710 +#define QM_REG_MR_ITR 0x3380
141711 +#define QM_REG_CFG 0x3500
141712 +#define QM_REG_ISR 0x3600
141713 +#define QM_REG_IIR 0x36C0
141714 +#define QM_REG_ITPR 0x3740
141715 +
141716 +/* Cache-enabled register offsets */
141717 +#define QM_CL_EQCR 0x0000
141718 +#define QM_CL_DQRR 0x1000
141719 +#define QM_CL_MR 0x2000
141720 +#define QM_CL_EQCR_PI_CENA 0x3000
141721 +#define QM_CL_EQCR_CI_CENA 0x3040
141722 +#define QM_CL_DQRR_PI_CENA 0x3100
141723 +#define QM_CL_DQRR_CI_CENA 0x3140
141724 +#define QM_CL_MR_PI_CENA 0x3300
141725 +#define QM_CL_MR_CI_CENA 0x3340
141726 +#define QM_CL_CR 0x3800
141727 +#define QM_CL_RR0 0x3900
141728 +#define QM_CL_RR1 0x3940
141729 +
141730 +#endif
141731 +
141732 +
141733 +/* BTW, the drivers (and h/w programming model) already obtain the required
141734 + * synchronisation for portal accesses via lwsync(), hwsync(), and
141735 + * data-dependencies. Use of barrier()s or other order-preserving primitives
141736 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
141737 + * simply ensure that the compiler treats the portal registers as volatile (ie.
141738 + * non-coherent). */
141739 +
141740 +/* Cache-inhibited register access. */
141741 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
141742 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
141743 + (qm)->addr_ci + (o));
141744 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
141745 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
141746 +
141747 +/* Cache-enabled (index) register access */
141748 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
141749 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
141750 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
141751 +#define __qm_cl_out(qm, o, val) \
141752 + do { \
141753 + u32 *__tmpclout = (qm)->addr_ce + (o); \
141754 + __raw_writel(cpu_to_be32(val), __tmpclout); \
141755 + dcbf(__tmpclout); \
141756 + } while (0)
141757 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
141758 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
141759 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
141760 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
141761 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
141762 +#define qm_cl_invalidate(reg)\
141763 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
141764 +
141765 +/* Cache-enabled ring access */
141766 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
141767 +
141768 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
141769 + * analysis, look at using the "extra" bit in the ring index registers to avoid
141770 + * cyclic issues. */
141771 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
141772 +{
141773 + /* 'first' is included, 'last' is excluded */
141774 + if (first <= last)
141775 + return last - first;
141776 + return ringsize + last - first;
141777 +}
141778 +
141779 +/* Portal modes.
141780 + * Enum types;
141781 + * pmode == production mode
141782 + * cmode == consumption mode,
141783 + * dmode == h/w dequeue mode.
141784 + * Enum values use 3 letter codes. First letter matches the portal mode,
141785 + * remaining two letters indicate;
141786 + * ci == cache-inhibited portal register
141787 + * ce == cache-enabled portal register
141788 + * vb == in-band valid-bit (cache-enabled)
141789 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
141790 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
141791 + */
141792 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
141793 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
141794 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
141795 + qm_eqcr_pvb = 2 /* valid-bit */
141796 +};
141797 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
141798 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
141799 + qm_dqrr_dpull = 1 /* PDQCR */
141800 +};
141801 +enum qm_dqrr_pmode { /* s/w-only */
141802 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
141803 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
141804 + qm_dqrr_pvb /* reads valid-bit */
141805 +};
141806 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
141807 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
141808 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
141809 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
141810 +};
141811 +enum qm_mr_pmode { /* s/w-only */
141812 + qm_mr_pci, /* reads MR_PI_CINH */
141813 + qm_mr_pce, /* reads MR_PI_CENA */
141814 + qm_mr_pvb /* reads valid-bit */
141815 +};
141816 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
141817 + qm_mr_cci = 0, /* CI index, cache-inhibited */
141818 + qm_mr_cce = 1 /* CI index, cache-enabled */
141819 +};
141820 +
141821 +
141822 +/* ------------------------- */
141823 +/* --- Portal structures --- */
141824 +
141825 +#define QM_EQCR_SIZE 8
141826 +#define QM_DQRR_SIZE 16
141827 +#define QM_MR_SIZE 8
141828 +
141829 +struct qm_eqcr {
141830 + struct qm_eqcr_entry *ring, *cursor;
141831 + u8 ci, available, ithresh, vbit;
141832 +#ifdef CONFIG_FSL_DPA_CHECKING
141833 + u32 busy;
141834 + enum qm_eqcr_pmode pmode;
141835 +#endif
141836 +};
141837 +
141838 +struct qm_dqrr {
141839 + const struct qm_dqrr_entry *ring, *cursor;
141840 + u8 pi, ci, fill, ithresh, vbit;
141841 +#ifdef CONFIG_FSL_DPA_CHECKING
141842 + enum qm_dqrr_dmode dmode;
141843 + enum qm_dqrr_pmode pmode;
141844 + enum qm_dqrr_cmode cmode;
141845 +#endif
141846 +};
141847 +
141848 +struct qm_mr {
141849 + const struct qm_mr_entry *ring, *cursor;
141850 + u8 pi, ci, fill, ithresh, vbit;
141851 +#ifdef CONFIG_FSL_DPA_CHECKING
141852 + enum qm_mr_pmode pmode;
141853 + enum qm_mr_cmode cmode;
141854 +#endif
141855 +};
141856 +
141857 +struct qm_mc {
141858 + struct qm_mc_command *cr;
141859 + struct qm_mc_result *rr;
141860 + u8 rridx, vbit;
141861 +#ifdef CONFIG_FSL_DPA_CHECKING
141862 + enum {
141863 + /* Can be _mc_start()ed */
141864 + qman_mc_idle,
141865 + /* Can be _mc_commit()ed or _mc_abort()ed */
141866 + qman_mc_user,
141867 + /* Can only be _mc_retry()ed */
141868 + qman_mc_hw
141869 + } state;
141870 +#endif
141871 +};
141872 +
141873 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
141874 +
141875 +struct qm_addr {
141876 + void __iomem *addr_ce; /* cache-enabled */
141877 + void __iomem *addr_ci; /* cache-inhibited */
141878 +};
141879 +
141880 +struct qm_portal {
141881 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
141882 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
141883 + * is setup-only, so isn't a cause for a concern. In other words, don't
141884 + * rearrange this structure on a whim, there be dragons ... */
141885 + struct qm_addr addr;
141886 + struct qm_eqcr eqcr;
141887 + struct qm_dqrr dqrr;
141888 + struct qm_mr mr;
141889 + struct qm_mc mc;
141890 +} QM_PORTAL_ALIGNMENT;
141891 +
141892 +
141893 +/* ---------------- */
141894 +/* --- EQCR API --- */
141895 +
141896 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
141897 +#define EQCR_CARRYCLEAR(p) \
141898 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
141899 +
141900 +/* Bit-wise logic to convert a ring pointer to a ring index */
141901 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
141902 +{
141903 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
141904 +}
141905 +
141906 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
141907 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
141908 +{
141909 + /* NB: this is odd-looking, but experiments show that it generates fast
141910 + * code with essentially no branching overheads. We increment to the
141911 + * next EQCR pointer and handle overflow and 'vbit'. */
141912 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
141913 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
141914 + if (partial != eqcr->cursor)
141915 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
141916 +}
141917 +
141918 +static inline int qm_eqcr_init(struct qm_portal *portal,
141919 + enum qm_eqcr_pmode pmode,
141920 + unsigned int eq_stash_thresh,
141921 + int eq_stash_prio)
141922 +{
141923 + /* This use of 'register', as well as all other occurrences, is because
141924 + * it has been observed to generate much faster code with gcc than is
141925 + * otherwise the case. */
141926 + register struct qm_eqcr *eqcr = &portal->eqcr;
141927 + u32 cfg;
141928 + u8 pi;
141929 +
141930 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
141931 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141932 + qm_cl_invalidate(EQCR_CI);
141933 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141934 + eqcr->cursor = eqcr->ring + pi;
141935 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
141936 + QM_EQCR_VERB_VBIT : 0;
141937 + eqcr->available = QM_EQCR_SIZE - 1 -
141938 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
141939 + eqcr->ithresh = qm_in(EQCR_ITR);
141940 +#ifdef CONFIG_FSL_DPA_CHECKING
141941 + eqcr->busy = 0;
141942 + eqcr->pmode = pmode;
141943 +#endif
141944 + cfg = (qm_in(CFG) & 0x00ffffff) |
141945 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
141946 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
141947 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
141948 + qm_out(CFG, cfg);
141949 + return 0;
141950 +}
141951 +
141952 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
141953 +{
141954 + return (qm_in(CFG) >> 28) & 0x7;
141955 +}
141956 +
141957 +static inline void qm_eqcr_finish(struct qm_portal *portal)
141958 +{
141959 + register struct qm_eqcr *eqcr = &portal->eqcr;
141960 + u8 pi, ci;
141961 + u32 cfg;
141962 +
141963 + /*
141964 + * Disable EQCI stashing because the QMan only
141965 + * presents the value it previously stashed to
141966 + * maintain coherency. Setting the stash threshold
141967 + * to 1 then 0 ensures that QMan has resyncronized
141968 + * its internal copy so that the portal is clean
141969 + * when it is reinitialized in the future
141970 + */
141971 + cfg = (qm_in(CFG) & 0x0fffffff) |
141972 + (1 << 28); /* QCSP_CFG: EST */
141973 + qm_out(CFG, cfg);
141974 + cfg &= 0x0fffffff; /* stash threshold = 0 */
141975 + qm_out(CFG, cfg);
141976 +
141977 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
141978 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
141979 +
141980 + /* Refresh EQCR CI cache value */
141981 + qm_cl_invalidate(EQCR_CI);
141982 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
141983 +
141984 + DPA_ASSERT(!eqcr->busy);
141985 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
141986 + pr_crit("losing uncommited EQCR entries\n");
141987 + if (ci != eqcr->ci)
141988 + pr_crit("missing existing EQCR completions\n");
141989 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
141990 + pr_crit("EQCR destroyed unquiesced\n");
141991 +}
141992 +
141993 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
141994 + *portal)
141995 +{
141996 + register struct qm_eqcr *eqcr = &portal->eqcr;
141997 + DPA_ASSERT(!eqcr->busy);
141998 + if (!eqcr->available)
141999 + return NULL;
142000 +
142001 +
142002 +#ifdef CONFIG_FSL_DPA_CHECKING
142003 + eqcr->busy = 1;
142004 +#endif
142005 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142006 + dcbz_64(eqcr->cursor);
142007 +#endif
142008 + return eqcr->cursor;
142009 +}
142010 +
142011 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
142012 + *portal)
142013 +{
142014 + register struct qm_eqcr *eqcr = &portal->eqcr;
142015 + u8 diff, old_ci;
142016 +
142017 + DPA_ASSERT(!eqcr->busy);
142018 + if (!eqcr->available) {
142019 + old_ci = eqcr->ci;
142020 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142021 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142022 + eqcr->available += diff;
142023 + if (!diff)
142024 + return NULL;
142025 + }
142026 +#ifdef CONFIG_FSL_DPA_CHECKING
142027 + eqcr->busy = 1;
142028 +#endif
142029 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142030 + dcbz_64(eqcr->cursor);
142031 +#endif
142032 + return eqcr->cursor;
142033 +}
142034 +
142035 +static inline void qm_eqcr_abort(struct qm_portal *portal)
142036 +{
142037 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142038 + DPA_ASSERT(eqcr->busy);
142039 +#ifdef CONFIG_FSL_DPA_CHECKING
142040 + eqcr->busy = 0;
142041 +#endif
142042 +}
142043 +
142044 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
142045 + struct qm_portal *portal, u8 myverb)
142046 +{
142047 + register struct qm_eqcr *eqcr = &portal->eqcr;
142048 + DPA_ASSERT(eqcr->busy);
142049 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
142050 + if (eqcr->available == 1)
142051 + return NULL;
142052 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142053 + dcbf(eqcr->cursor);
142054 + EQCR_INC(eqcr);
142055 + eqcr->available--;
142056 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142057 + dcbz_64(eqcr->cursor);
142058 +#endif
142059 + return eqcr->cursor;
142060 +}
142061 +
142062 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
142063 +#define EQCR_COMMIT_CHECKS(eqcr) \
142064 +do { \
142065 + DPA_ASSERT(eqcr->busy); \
142066 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
142067 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
142068 +} while (0)
142069 +#else
142070 +#define EQCR_COMMIT_CHECKS(eqcr) \
142071 +do { \
142072 + DPA_ASSERT(eqcr->busy); \
142073 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
142074 + cpu_to_be32(0x00ffffff))); \
142075 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
142076 + cpu_to_be32(0x00ffffff))); \
142077 +} while (0)
142078 +#endif
142079 +
142080 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
142081 +{
142082 + register struct qm_eqcr *eqcr = &portal->eqcr;
142083 + EQCR_COMMIT_CHECKS(eqcr);
142084 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
142085 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142086 + EQCR_INC(eqcr);
142087 + eqcr->available--;
142088 + dcbf(eqcr->cursor);
142089 + hwsync();
142090 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
142091 +#ifdef CONFIG_FSL_DPA_CHECKING
142092 + eqcr->busy = 0;
142093 +#endif
142094 +}
142095 +
142096 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
142097 +{
142098 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142099 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142100 + qm_cl_invalidate(EQCR_PI);
142101 + qm_cl_touch_rw(EQCR_PI);
142102 +}
142103 +
142104 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
142105 +{
142106 + register struct qm_eqcr *eqcr = &portal->eqcr;
142107 + EQCR_COMMIT_CHECKS(eqcr);
142108 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
142109 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142110 + EQCR_INC(eqcr);
142111 + eqcr->available--;
142112 + dcbf(eqcr->cursor);
142113 + lwsync();
142114 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
142115 +#ifdef CONFIG_FSL_DPA_CHECKING
142116 + eqcr->busy = 0;
142117 +#endif
142118 +}
142119 +
142120 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
142121 +{
142122 + register struct qm_eqcr *eqcr = &portal->eqcr;
142123 + struct qm_eqcr_entry *eqcursor;
142124 + EQCR_COMMIT_CHECKS(eqcr);
142125 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
142126 + lwsync();
142127 + eqcursor = eqcr->cursor;
142128 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
142129 + dcbf(eqcursor);
142130 + EQCR_INC(eqcr);
142131 + eqcr->available--;
142132 +#ifdef CONFIG_FSL_DPA_CHECKING
142133 + eqcr->busy = 0;
142134 +#endif
142135 +}
142136 +
142137 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
142138 +{
142139 + register struct qm_eqcr *eqcr = &portal->eqcr;
142140 + u8 diff, old_ci = eqcr->ci;
142141 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
142142 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142143 + eqcr->available += diff;
142144 + return diff;
142145 +}
142146 +
142147 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
142148 +{
142149 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
142150 + qm_cl_touch_ro(EQCR_CI);
142151 +}
142152 +
142153 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
142154 +{
142155 + register struct qm_eqcr *eqcr = &portal->eqcr;
142156 + u8 diff, old_ci = eqcr->ci;
142157 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
142158 + qm_cl_invalidate(EQCR_CI);
142159 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
142160 + eqcr->available += diff;
142161 + return diff;
142162 +}
142163 +
142164 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
142165 +{
142166 + register struct qm_eqcr *eqcr = &portal->eqcr;
142167 + return eqcr->ithresh;
142168 +}
142169 +
142170 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142171 +{
142172 + register struct qm_eqcr *eqcr = &portal->eqcr;
142173 + eqcr->ithresh = ithresh;
142174 + qm_out(EQCR_ITR, ithresh);
142175 +}
142176 +
142177 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
142178 +{
142179 + register struct qm_eqcr *eqcr = &portal->eqcr;
142180 + return eqcr->available;
142181 +}
142182 +
142183 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
142184 +{
142185 + register struct qm_eqcr *eqcr = &portal->eqcr;
142186 + return QM_EQCR_SIZE - 1 - eqcr->available;
142187 +}
142188 +
142189 +
142190 +/* ---------------- */
142191 +/* --- DQRR API --- */
142192 +
142193 +/* FIXME: many possible improvements;
142194 + * - look at changing the API to use pointer rather than index parameters now
142195 + * that 'cursor' is a pointer,
142196 + * - consider moving other parameters to pointer if it could help (ci)
142197 + */
142198 +
142199 +#define DQRR_CARRYCLEAR(p) \
142200 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
142201 +
142202 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
142203 +{
142204 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
142205 +}
142206 +
142207 +static inline const struct qm_dqrr_entry *DQRR_INC(
142208 + const struct qm_dqrr_entry *e)
142209 +{
142210 + return DQRR_CARRYCLEAR(e + 1);
142211 +}
142212 +
142213 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
142214 +{
142215 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
142216 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
142217 +}
142218 +
142219 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
142220 +{
142221 + register struct qm_dqrr *dqrr = &portal->dqrr;
142222 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142223 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142224 + qm_out(DQRR_CI_CINH, dqrr->ci);
142225 +}
142226 +
142227 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
142228 +{
142229 + register struct qm_dqrr *dqrr = &portal->dqrr;
142230 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142231 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
142232 + qm_cl_out(DQRR_CI, dqrr->ci);
142233 +}
142234 +
142235 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
142236 +{
142237 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142238 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142239 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
142240 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
142241 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142242 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142243 +}
142244 +
142245 +static inline int qm_dqrr_init(struct qm_portal *portal,
142246 + const struct qm_portal_config *config,
142247 + enum qm_dqrr_dmode dmode,
142248 + __maybe_unused enum qm_dqrr_pmode pmode,
142249 + enum qm_dqrr_cmode cmode, u8 max_fill)
142250 +{
142251 + register struct qm_dqrr *dqrr = &portal->dqrr;
142252 + u32 cfg;
142253 +
142254 + /* Make sure the DQRR will be idle when we enable */
142255 + qm_out(DQRR_SDQCR, 0);
142256 + qm_out(DQRR_VDQCR, 0);
142257 + qm_out(DQRR_PDQCR, 0);
142258 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
142259 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142260 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142261 + dqrr->cursor = dqrr->ring + dqrr->ci;
142262 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
142263 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
142264 + QM_DQRR_VERB_VBIT : 0;
142265 + dqrr->ithresh = qm_in(DQRR_ITR);
142266 +
142267 + /* Free up pending DQRR entries if any as per current DCM */
142268 + if (dqrr->fill) {
142269 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
142270 +
142271 +#ifdef CONFIG_FSL_DPA_CHECKING
142272 + dqrr->cmode = dcm;
142273 +#endif
142274 + switch (dcm) {
142275 + case qm_dqrr_cci:
142276 + qm_dqrr_cci_consume(portal, dqrr->fill);
142277 + break;
142278 + case qm_dqrr_cce:
142279 + qm_dqrr_cce_consume(portal, dqrr->fill);
142280 + break;
142281 + case qm_dqrr_cdc:
142282 + qm_dqrr_cdc_consume_n(portal, (QM_DQRR_SIZE - 1));
142283 + break;
142284 + default:
142285 + DPA_ASSERT(0);
142286 + }
142287 + }
142288 +
142289 +#ifdef CONFIG_FSL_DPA_CHECKING
142290 + dqrr->dmode = dmode;
142291 + dqrr->pmode = pmode;
142292 + dqrr->cmode = cmode;
142293 +#endif
142294 + /* Invalidate every ring entry before beginning */
142295 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
142296 + dcbi(qm_cl(dqrr->ring, cfg));
142297 + cfg = (qm_in(CFG) & 0xff000f00) |
142298 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
142299 + ((dmode & 1) << 18) | /* DP */
142300 + ((cmode & 3) << 16) | /* DCM */
142301 + 0xa0 | /* RE+SE */
142302 + (0 ? 0x40 : 0) | /* Ignore RP */
142303 + (0 ? 0x10 : 0); /* Ignore SP */
142304 + qm_out(CFG, cfg);
142305 + qm_dqrr_set_maxfill(portal, max_fill);
142306 + return 0;
142307 +}
142308 +
142309 +static inline void qm_dqrr_finish(struct qm_portal *portal)
142310 +{
142311 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142312 +#ifdef CONFIG_FSL_DPA_CHECKING
142313 + if ((dqrr->cmode != qm_dqrr_cdc) &&
142314 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
142315 + pr_crit("Ignoring completed DQRR entries\n");
142316 +#endif
142317 +}
142318 +
142319 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
142320 + struct qm_portal *portal)
142321 +{
142322 + register struct qm_dqrr *dqrr = &portal->dqrr;
142323 + if (!dqrr->fill)
142324 + return NULL;
142325 + return dqrr->cursor;
142326 +}
142327 +
142328 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
142329 +{
142330 + register struct qm_dqrr *dqrr = &portal->dqrr;
142331 + return DQRR_PTR2IDX(dqrr->cursor);
142332 +}
142333 +
142334 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
142335 +{
142336 + register struct qm_dqrr *dqrr = &portal->dqrr;
142337 + DPA_ASSERT(dqrr->fill);
142338 + dqrr->cursor = DQRR_INC(dqrr->cursor);
142339 + return --dqrr->fill;
142340 +}
142341 +
142342 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
142343 +{
142344 + register struct qm_dqrr *dqrr = &portal->dqrr;
142345 + u8 diff, old_pi = dqrr->pi;
142346 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
142347 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
142348 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142349 + dqrr->fill += diff;
142350 + return diff;
142351 +}
142352 +
142353 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
142354 +{
142355 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142356 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142357 + qm_cl_invalidate(DQRR_PI);
142358 + qm_cl_touch_ro(DQRR_PI);
142359 +}
142360 +
142361 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
142362 +{
142363 + register struct qm_dqrr *dqrr = &portal->dqrr;
142364 + u8 diff, old_pi = dqrr->pi;
142365 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
142366 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
142367 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
142368 + dqrr->fill += diff;
142369 + return diff;
142370 +}
142371 +
142372 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
142373 +{
142374 + register struct qm_dqrr *dqrr = &portal->dqrr;
142375 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
142376 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
142377 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
142378 + /*
142379 + * On PowerPC platforms if PAMU is not available we need to
142380 + * manually invalidate the cache. When PAMU is available the
142381 + * cache is updated by stashing operations generated by QMan
142382 + */
142383 + dcbi(res);
142384 + dcbt_ro(res);
142385 +#endif
142386 +
142387 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142388 + * inlining doesn't try to optimise out "excess reads". */
142389 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
142390 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
142391 + if (!dqrr->pi)
142392 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
142393 + dqrr->fill++;
142394 + }
142395 +}
142396 +
142397 +
142398 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
142399 +{
142400 + register struct qm_dqrr *dqrr = &portal->dqrr;
142401 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
142402 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142403 + qm_out(DQRR_CI_CINH, dqrr->ci);
142404 +}
142405 +
142406 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
142407 +{
142408 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142409 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142410 + qm_cl_invalidate(DQRR_CI);
142411 + qm_cl_touch_rw(DQRR_CI);
142412 +}
142413 +
142414 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
142415 +{
142416 + register struct qm_dqrr *dqrr = &portal->dqrr;
142417 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
142418 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
142419 + qm_cl_out(DQRR_CI, dqrr->ci);
142420 +}
142421 +
142422 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
142423 + int park)
142424 +{
142425 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142426 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142427 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142428 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142429 + ((park ? 1 : 0) << 6) | /* PK */
142430 + idx); /* DCAP_CI */
142431 +}
142432 +
142433 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
142434 + const struct qm_dqrr_entry *dq,
142435 + int park)
142436 +{
142437 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142438 + u8 idx = DQRR_PTR2IDX(dq);
142439 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142440 + DPA_ASSERT((dqrr->ring + idx) == dq);
142441 + DPA_ASSERT(idx < QM_DQRR_SIZE);
142442 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
142443 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
142444 + idx); /* DQRR_DCAP::DCAP_CI */
142445 +}
142446 +
142447 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
142448 +{
142449 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142450 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142451 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
142452 +}
142453 +
142454 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
142455 +{
142456 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142457 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142458 + qm_cl_invalidate(DQRR_CI);
142459 + qm_cl_touch_ro(DQRR_CI);
142460 +}
142461 +
142462 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
142463 +{
142464 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142465 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
142466 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
142467 +}
142468 +
142469 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
142470 +{
142471 + register struct qm_dqrr *dqrr = &portal->dqrr;
142472 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142473 + return dqrr->ci;
142474 +}
142475 +
142476 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
142477 +{
142478 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
142479 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142480 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142481 + (1 << 6) | /* PK */
142482 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
142483 +}
142484 +
142485 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
142486 +{
142487 + register struct qm_dqrr *dqrr = &portal->dqrr;
142488 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
142489 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
142490 + (1 << 6) | /* PK */
142491 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
142492 +}
142493 +
142494 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
142495 +{
142496 + qm_out(DQRR_SDQCR, sdqcr);
142497 +}
142498 +
142499 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
142500 +{
142501 + return qm_in(DQRR_SDQCR);
142502 +}
142503 +
142504 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
142505 +{
142506 + qm_out(DQRR_VDQCR, vdqcr);
142507 +}
142508 +
142509 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
142510 +{
142511 + return qm_in(DQRR_VDQCR);
142512 +}
142513 +
142514 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
142515 +{
142516 + qm_out(DQRR_PDQCR, pdqcr);
142517 +}
142518 +
142519 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
142520 +{
142521 + return qm_in(DQRR_PDQCR);
142522 +}
142523 +
142524 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
142525 +{
142526 + register struct qm_dqrr *dqrr = &portal->dqrr;
142527 + return dqrr->ithresh;
142528 +}
142529 +
142530 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142531 +{
142532 + qm_out(DQRR_ITR, ithresh);
142533 +}
142534 +
142535 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
142536 +{
142537 + return (qm_in(CFG) & 0x00f00000) >> 20;
142538 +}
142539 +
142540 +
142541 +/* -------------- */
142542 +/* --- MR API --- */
142543 +
142544 +#define MR_CARRYCLEAR(p) \
142545 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
142546 +
142547 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
142548 +{
142549 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
142550 +}
142551 +
142552 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
142553 +{
142554 + return MR_CARRYCLEAR(e + 1);
142555 +}
142556 +
142557 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
142558 + enum qm_mr_cmode cmode)
142559 +{
142560 + register struct qm_mr *mr = &portal->mr;
142561 + u32 cfg;
142562 +
142563 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
142564 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
142565 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
142566 + mr->cursor = mr->ring + mr->ci;
142567 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
142568 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
142569 + mr->ithresh = qm_in(MR_ITR);
142570 +#ifdef CONFIG_FSL_DPA_CHECKING
142571 + mr->pmode = pmode;
142572 + mr->cmode = cmode;
142573 +#endif
142574 + cfg = (qm_in(CFG) & 0xfffff0ff) |
142575 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
142576 + qm_out(CFG, cfg);
142577 + return 0;
142578 +}
142579 +
142580 +static inline void qm_mr_finish(struct qm_portal *portal)
142581 +{
142582 + register struct qm_mr *mr = &portal->mr;
142583 + if (mr->ci != MR_PTR2IDX(mr->cursor))
142584 + pr_crit("Ignoring completed MR entries\n");
142585 +}
142586 +
142587 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
142588 +{
142589 + register struct qm_mr *mr = &portal->mr;
142590 + if (!mr->fill)
142591 + return NULL;
142592 + return mr->cursor;
142593 +}
142594 +
142595 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
142596 +{
142597 + register struct qm_mr *mr = &portal->mr;
142598 + return MR_PTR2IDX(mr->cursor);
142599 +}
142600 +
142601 +static inline u8 qm_mr_next(struct qm_portal *portal)
142602 +{
142603 + register struct qm_mr *mr = &portal->mr;
142604 + DPA_ASSERT(mr->fill);
142605 + mr->cursor = MR_INC(mr->cursor);
142606 + return --mr->fill;
142607 +}
142608 +
142609 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
142610 +{
142611 + register struct qm_mr *mr = &portal->mr;
142612 + u8 diff, old_pi = mr->pi;
142613 + DPA_ASSERT(mr->pmode == qm_mr_pci);
142614 + mr->pi = qm_in(MR_PI_CINH);
142615 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142616 + mr->fill += diff;
142617 + return diff;
142618 +}
142619 +
142620 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
142621 +{
142622 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142623 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142624 + qm_cl_invalidate(MR_PI);
142625 + qm_cl_touch_ro(MR_PI);
142626 +}
142627 +
142628 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
142629 +{
142630 + register struct qm_mr *mr = &portal->mr;
142631 + u8 diff, old_pi = mr->pi;
142632 + DPA_ASSERT(mr->pmode == qm_mr_pce);
142633 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
142634 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
142635 + mr->fill += diff;
142636 + return diff;
142637 +}
142638 +
142639 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
142640 +{
142641 + register struct qm_mr *mr = &portal->mr;
142642 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
142643 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
142644 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
142645 + * inlining doesn't try to optimise out "excess reads". */
142646 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
142647 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
142648 + if (!mr->pi)
142649 + mr->vbit ^= QM_MR_VERB_VBIT;
142650 + mr->fill++;
142651 + res = MR_INC(res);
142652 + }
142653 + dcbit_ro(res);
142654 +}
142655 +
142656 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
142657 +{
142658 + register struct qm_mr *mr = &portal->mr;
142659 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142660 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142661 + qm_out(MR_CI_CINH, mr->ci);
142662 +}
142663 +
142664 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
142665 +{
142666 + register struct qm_mr *mr = &portal->mr;
142667 + DPA_ASSERT(mr->cmode == qm_mr_cci);
142668 + mr->ci = MR_PTR2IDX(mr->cursor);
142669 + qm_out(MR_CI_CINH, mr->ci);
142670 +}
142671 +
142672 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
142673 +{
142674 + __maybe_unused register struct qm_mr *mr = &portal->mr;
142675 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142676 + qm_cl_invalidate(MR_CI);
142677 + qm_cl_touch_rw(MR_CI);
142678 +}
142679 +
142680 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
142681 +{
142682 + register struct qm_mr *mr = &portal->mr;
142683 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142684 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
142685 + qm_cl_out(MR_CI, mr->ci);
142686 +}
142687 +
142688 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
142689 +{
142690 + register struct qm_mr *mr = &portal->mr;
142691 + DPA_ASSERT(mr->cmode == qm_mr_cce);
142692 + mr->ci = MR_PTR2IDX(mr->cursor);
142693 + qm_cl_out(MR_CI, mr->ci);
142694 +}
142695 +
142696 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
142697 +{
142698 + register struct qm_mr *mr = &portal->mr;
142699 + return mr->ci;
142700 +}
142701 +
142702 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
142703 +{
142704 + register struct qm_mr *mr = &portal->mr;
142705 + return mr->ithresh;
142706 +}
142707 +
142708 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
142709 +{
142710 + qm_out(MR_ITR, ithresh);
142711 +}
142712 +
142713 +
142714 +/* ------------------------------ */
142715 +/* --- Management command API --- */
142716 +
142717 +static inline int qm_mc_init(struct qm_portal *portal)
142718 +{
142719 + u8 rr0, rr1;
142720 + register struct qm_mc *mc = &portal->mc;
142721 +
142722 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
142723 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
142724 +
142725 + /*
142726 + * The expected valid bit polarity for the next CR command is 0
142727 + * if RR1 contains a valid response, and is 1 if RR0 contains a
142728 + * valid response. If both RR contain all 0, this indicates either
142729 + * that no command has been executed since reset (in which case the
142730 + * expected valid bit polarity is 1)
142731 + */
142732 + rr0 = __raw_readb(&mc->rr->verb);
142733 + rr1 = __raw_readb(&(mc->rr+1)->verb);
142734 + if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
142735 + mc->rridx = 1;
142736 + else
142737 + mc->rridx = 0;
142738 +
142739 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
142740 +#ifdef CONFIG_FSL_DPA_CHECKING
142741 + mc->state = qman_mc_idle;
142742 +#endif
142743 + return 0;
142744 +}
142745 +
142746 +static inline void qm_mc_finish(struct qm_portal *portal)
142747 +{
142748 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142749 + DPA_ASSERT(mc->state == qman_mc_idle);
142750 +#ifdef CONFIG_FSL_DPA_CHECKING
142751 + if (mc->state != qman_mc_idle)
142752 + pr_crit("Losing incomplete MC command\n");
142753 +#endif
142754 +}
142755 +
142756 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
142757 +{
142758 + register struct qm_mc *mc = &portal->mc;
142759 + DPA_ASSERT(mc->state == qman_mc_idle);
142760 +#ifdef CONFIG_FSL_DPA_CHECKING
142761 + mc->state = qman_mc_user;
142762 +#endif
142763 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
142764 + dcbz_64(mc->cr);
142765 +#endif
142766 + return mc->cr;
142767 +}
142768 +
142769 +static inline void qm_mc_abort(struct qm_portal *portal)
142770 +{
142771 + __maybe_unused register struct qm_mc *mc = &portal->mc;
142772 + DPA_ASSERT(mc->state == qman_mc_user);
142773 +#ifdef CONFIG_FSL_DPA_CHECKING
142774 + mc->state = qman_mc_idle;
142775 +#endif
142776 +}
142777 +
142778 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
142779 +{
142780 + register struct qm_mc *mc = &portal->mc;
142781 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142782 + DPA_ASSERT(mc->state == qman_mc_user);
142783 + lwsync();
142784 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
142785 + dcbf(mc->cr);
142786 + dcbit_ro(rr);
142787 +#ifdef CONFIG_FSL_DPA_CHECKING
142788 + mc->state = qman_mc_hw;
142789 +#endif
142790 +}
142791 +
142792 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
142793 +{
142794 + register struct qm_mc *mc = &portal->mc;
142795 + struct qm_mc_result *rr = mc->rr + mc->rridx;
142796 + DPA_ASSERT(mc->state == qman_mc_hw);
142797 + /* The inactive response register's verb byte always returns zero until
142798 + * its command is submitted and completed. This includes the valid-bit,
142799 + * in case you were wondering... */
142800 + if (!__raw_readb(&rr->verb)) {
142801 + dcbit_ro(rr);
142802 + return NULL;
142803 + }
142804 + mc->rridx ^= 1;
142805 + mc->vbit ^= QM_MCC_VERB_VBIT;
142806 +#ifdef CONFIG_FSL_DPA_CHECKING
142807 + mc->state = qman_mc_idle;
142808 +#endif
142809 + return rr;
142810 +}
142811 +
142812 +
142813 +/* ------------------------------------- */
142814 +/* --- Portal interrupt register API --- */
142815 +
142816 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
142817 +{
142818 + return 0;
142819 +}
142820 +
142821 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
142822 +{
142823 +}
142824 +
142825 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
142826 +{
142827 + qm_out(ITPR, iperiod);
142828 +}
142829 +
142830 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
142831 +{
142832 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142833 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
142834 +#else
142835 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
142836 +#endif
142837 +}
142838 +
142839 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
142840 + u32 val)
142841 +{
142842 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
142843 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
142844 +#else
142845 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
142846 +#endif
142847 +}
142848 +
142849 +/* Cleanup FQs */
142850 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
142851 + u32 fqid)
142852 +{
142853 +
142854 + struct qm_mc_command *mcc;
142855 + struct qm_mc_result *mcr;
142856 + u8 state;
142857 + int orl_empty, fq_empty, i, drain = 0;
142858 + u32 result;
142859 + u32 channel, wq;
142860 + u16 dest_wq;
142861 +
142862 + /* Determine the state of the FQID */
142863 + mcc = qm_mc_start(portal[0]);
142864 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
142865 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
142866 + while (!(mcr = qm_mc_result(portal[0])))
142867 + cpu_relax();
142868 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
142869 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
142870 + if (state == QM_MCR_NP_STATE_OOS)
142871 + return 0; /* Already OOS, no need to do anymore checks */
142872 +
142873 + /* Query which channel the FQ is using */
142874 + mcc = qm_mc_start(portal[0]);
142875 + mcc->queryfq.fqid = cpu_to_be32(fqid);
142876 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
142877 + while (!(mcr = qm_mc_result(portal[0])))
142878 + cpu_relax();
142879 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
142880 +
142881 + /* Need to store these since the MCR gets reused */
142882 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
142883 + wq = dest_wq & 0x7;
142884 + channel = dest_wq>>3;
142885 +
142886 + switch (state) {
142887 + case QM_MCR_NP_STATE_TEN_SCHED:
142888 + case QM_MCR_NP_STATE_TRU_SCHED:
142889 + case QM_MCR_NP_STATE_ACTIVE:
142890 + case QM_MCR_NP_STATE_PARKED:
142891 + orl_empty = 0;
142892 + mcc = qm_mc_start(portal[0]);
142893 + mcc->alterfq.fqid = cpu_to_be32(fqid);
142894 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
142895 + while (!(mcr = qm_mc_result(portal[0])))
142896 + cpu_relax();
142897 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
142898 + QM_MCR_VERB_ALTER_RETIRE);
142899 + result = mcr->result; /* Make a copy as we reuse MCR below */
142900 +
142901 + if (result == QM_MCR_RESULT_PENDING) {
142902 + /* Need to wait for the FQRN in the message ring, which
142903 + will only occur once the FQ has been drained. In
142904 + order for the FQ to drain the portal needs to be set
142905 + to dequeue from the channel the FQ is scheduled on */
142906 + const struct qm_mr_entry *msg;
142907 + const struct qm_dqrr_entry *dqrr = NULL;
142908 + int found_fqrn = 0;
142909 + u16 dequeue_wq = 0;
142910 +
142911 + /* Flag that we need to drain FQ */
142912 + drain = 1;
142913 +
142914 + if (channel >= qm_channel_pool1 &&
142915 + channel < (qm_channel_pool1 + 15)) {
142916 + /* Pool channel, enable the bit in the portal */
142917 + dequeue_wq = (channel -
142918 + qm_channel_pool1 + 1)<<4 | wq;
142919 + } else if (channel < qm_channel_pool1) {
142920 + /* Dedicated channel */
142921 + dequeue_wq = wq;
142922 + } else {
142923 + pr_info("Cannot recover FQ 0x%x, it is "
142924 + "scheduled on channel 0x%x",
142925 + fqid, channel);
142926 + return -EBUSY;
142927 + }
142928 + /* Set the sdqcr to drain this channel */
142929 + if (channel < qm_channel_pool1)
142930 + for (i = 0; i < portal_count; i++)
142931 + qm_dqrr_sdqcr_set(portal[i],
142932 + QM_SDQCR_TYPE_ACTIVE |
142933 + QM_SDQCR_CHANNELS_DEDICATED);
142934 + else
142935 + for (i = 0; i < portal_count; i++)
142936 + qm_dqrr_sdqcr_set(
142937 + portal[i],
142938 + QM_SDQCR_TYPE_ACTIVE |
142939 + QM_SDQCR_CHANNELS_POOL_CONV
142940 + (channel));
142941 + while (!found_fqrn) {
142942 + /* Keep draining DQRR while checking the MR*/
142943 + for (i = 0; i < portal_count; i++) {
142944 + qm_dqrr_pvb_update(portal[i]);
142945 + dqrr = qm_dqrr_current(portal[i]);
142946 + while (dqrr) {
142947 + qm_dqrr_cdc_consume_1ptr(
142948 + portal[i], dqrr, 0);
142949 + qm_dqrr_pvb_update(portal[i]);
142950 + qm_dqrr_next(portal[i]);
142951 + dqrr = qm_dqrr_current(
142952 + portal[i]);
142953 + }
142954 + /* Process message ring too */
142955 + qm_mr_pvb_update(portal[i]);
142956 + msg = qm_mr_current(portal[i]);
142957 + while (msg) {
142958 + if ((msg->verb &
142959 + QM_MR_VERB_TYPE_MASK)
142960 + == QM_MR_VERB_FQRN)
142961 + found_fqrn = 1;
142962 + qm_mr_next(portal[i]);
142963 + qm_mr_cci_consume_to_current(
142964 + portal[i]);
142965 + qm_mr_pvb_update(portal[i]);
142966 + msg = qm_mr_current(portal[i]);
142967 + }
142968 + cpu_relax();
142969 + }
142970 + }
142971 + }
142972 + if (result != QM_MCR_RESULT_OK &&
142973 + result != QM_MCR_RESULT_PENDING) {
142974 + /* error */
142975 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
142976 + fqid, result);
142977 + return -1;
142978 + }
142979 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
142980 + /* ORL had no entries, no need to wait until the
142981 + ERNs come in */
142982 + orl_empty = 1;
142983 + }
142984 + /* Retirement succeeded, check to see if FQ needs
142985 + to be drained */
142986 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
142987 + /* FQ is Not Empty, drain using volatile DQ commands */
142988 + fq_empty = 0;
142989 + do {
142990 + const struct qm_dqrr_entry *dqrr = NULL;
142991 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
142992 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
142993 +
142994 + /* Wait for a dequeue to occur */
142995 + while (dqrr == NULL) {
142996 + qm_dqrr_pvb_update(portal[0]);
142997 + dqrr = qm_dqrr_current(portal[0]);
142998 + if (!dqrr)
142999 + cpu_relax();
143000 + }
143001 + /* Process the dequeues, making sure to
143002 + empty the ring completely */
143003 + while (dqrr) {
143004 + if (be32_to_cpu(dqrr->fqid) == fqid &&
143005 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
143006 + fq_empty = 1;
143007 + qm_dqrr_cdc_consume_1ptr(portal[0],
143008 + dqrr, 0);
143009 + qm_dqrr_pvb_update(portal[0]);
143010 + qm_dqrr_next(portal[0]);
143011 + dqrr = qm_dqrr_current(portal[0]);
143012 + }
143013 + } while (fq_empty == 0);
143014 + }
143015 + for (i = 0; i < portal_count; i++)
143016 + qm_dqrr_sdqcr_set(portal[i], 0);
143017 +
143018 + /* Wait for the ORL to have been completely drained */
143019 + while (orl_empty == 0) {
143020 + const struct qm_mr_entry *msg;
143021 + qm_mr_pvb_update(portal[0]);
143022 + msg = qm_mr_current(portal[0]);
143023 + while (msg) {
143024 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
143025 + QM_MR_VERB_FQRL)
143026 + orl_empty = 1;
143027 + qm_mr_next(portal[0]);
143028 + qm_mr_cci_consume_to_current(portal[0]);
143029 + qm_mr_pvb_update(portal[0]);
143030 + msg = qm_mr_current(portal[0]);
143031 + }
143032 + cpu_relax();
143033 + }
143034 + mcc = qm_mc_start(portal[0]);
143035 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143036 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143037 + while (!(mcr = qm_mc_result(portal[0])))
143038 + cpu_relax();
143039 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143040 + QM_MCR_VERB_ALTER_OOS);
143041 + if (mcr->result != QM_MCR_RESULT_OK) {
143042 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
143043 + fqid, mcr->result);
143044 + return -1;
143045 + }
143046 + return 0;
143047 + case QM_MCR_NP_STATE_RETIRED:
143048 + /* Send OOS Command */
143049 + mcc = qm_mc_start(portal[0]);
143050 + mcc->alterfq.fqid = cpu_to_be32(fqid);
143051 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
143052 + while (!(mcr = qm_mc_result(portal[0])))
143053 + cpu_relax();
143054 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143055 + QM_MCR_VERB_ALTER_OOS);
143056 + if (mcr->result) {
143057 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
143058 + return -1;
143059 + }
143060 + return 0;
143061 + }
143062 + return -1;
143063 +}
143064 --- /dev/null
143065 +++ b/drivers/staging/fsl_qbman/qman_private.h
143066 @@ -0,0 +1,398 @@
143067 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
143068 + *
143069 + * Redistribution and use in source and binary forms, with or without
143070 + * modification, are permitted provided that the following conditions are met:
143071 + * * Redistributions of source code must retain the above copyright
143072 + * notice, this list of conditions and the following disclaimer.
143073 + * * Redistributions in binary form must reproduce the above copyright
143074 + * notice, this list of conditions and the following disclaimer in the
143075 + * documentation and/or other materials provided with the distribution.
143076 + * * Neither the name of Freescale Semiconductor nor the
143077 + * names of its contributors may be used to endorse or promote products
143078 + * derived from this software without specific prior written permission.
143079 + *
143080 + *
143081 + * ALTERNATIVELY, this software may be distributed under the terms of the
143082 + * GNU General Public License ("GPL") as published by the Free Software
143083 + * Foundation, either version 2 of that License or (at your option) any
143084 + * later version.
143085 + *
143086 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143087 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143088 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143089 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143090 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143091 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143092 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143093 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143094 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143095 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143096 + */
143097 +
143098 +#include "dpa_sys.h"
143099 +#include <linux/fsl_qman.h>
143100 +#include <linux/iommu.h>
143101 +
143102 +#if defined(CONFIG_FSL_PAMU)
143103 +#include <asm/fsl_pamu_stash.h>
143104 +#endif
143105 +
143106 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
143107 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
143108 +#endif
143109 +
143110 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
143111 + /* ----------------- */
143112 + /* Congestion Groups */
143113 + /* ----------------- */
143114 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
143115 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
143116 + * those that don't concern us. We harness the structure and accessor details
143117 + * already used in the management command to query congestion groups. */
143118 +struct qman_cgrs {
143119 + struct __qm_mcr_querycongestion q;
143120 +};
143121 +static inline void qman_cgrs_init(struct qman_cgrs *c)
143122 +{
143123 + memset(c, 0, sizeof(*c));
143124 +}
143125 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
143126 +{
143127 + memset(c, 0xff, sizeof(*c));
143128 +}
143129 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
143130 +{
143131 + return QM_MCR_QUERYCONGESTION(&c->q, num);
143132 +}
143133 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
143134 +{
143135 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
143136 +}
143137 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
143138 +{
143139 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
143140 +}
143141 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
143142 +{
143143 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
143144 + ;
143145 + return num;
143146 +}
143147 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
143148 + const struct qman_cgrs *src)
143149 +{
143150 + *dest = *src;
143151 +}
143152 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
143153 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143154 +{
143155 + int ret;
143156 + u32 *_d = dest->q.__state;
143157 + const u32 *_a = a->q.__state;
143158 + const u32 *_b = b->q.__state;
143159 + for (ret = 0; ret < 8; ret++)
143160 + *(_d++) = *(_a++) & *(_b++);
143161 +}
143162 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
143163 + const struct qman_cgrs *a, const struct qman_cgrs *b)
143164 +{
143165 + int ret;
143166 + u32 *_d = dest->q.__state;
143167 + const u32 *_a = a->q.__state;
143168 + const u32 *_b = b->q.__state;
143169 + for (ret = 0; ret < 8; ret++)
143170 + *(_d++) = *(_a++) ^ *(_b++);
143171 +}
143172 +
143173 + /* ----------------------- */
143174 + /* CEETM Congestion Groups */
143175 + /* ----------------------- */
143176 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
143177 + * congestion groups.
143178 + */
143179 +struct qman_ccgrs {
143180 + struct __qm_mcr_querycongestion q[2];
143181 +};
143182 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
143183 +{
143184 + memset(c, 0, sizeof(*c));
143185 +}
143186 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
143187 +{
143188 + memset(c, 0xff, sizeof(*c));
143189 +}
143190 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
143191 +{
143192 + if (num < __CGR_NUM)
143193 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
143194 + else
143195 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
143196 +}
143197 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
143198 +{
143199 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
143200 + ;
143201 + return num;
143202 +}
143203 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
143204 + const struct qman_ccgrs *src)
143205 +{
143206 + *dest = *src;
143207 +}
143208 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
143209 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143210 +{
143211 + int ret, i;
143212 + u32 *_d;
143213 + const u32 *_a, *_b;
143214 + for (i = 0; i < 2; i++) {
143215 + _d = dest->q[i].__state;
143216 + _a = a->q[i].__state;
143217 + _b = b->q[i].__state;
143218 + for (ret = 0; ret < 8; ret++)
143219 + *(_d++) = *(_a++) & *(_b++);
143220 + }
143221 +}
143222 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
143223 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
143224 +{
143225 + int ret, i;
143226 + u32 *_d;
143227 + const u32 *_a, *_b;
143228 + for (i = 0; i < 2; i++) {
143229 + _d = dest->q[i].__state;
143230 + _a = a->q[i].__state;
143231 + _b = b->q[i].__state;
143232 + for (ret = 0; ret < 8; ret++)
143233 + *(_d++) = *(_a++) ^ *(_b++);
143234 + }
143235 +}
143236 +
143237 +/* used by CCSR and portal interrupt code */
143238 +enum qm_isr_reg {
143239 + qm_isr_status = 0,
143240 + qm_isr_enable = 1,
143241 + qm_isr_disable = 2,
143242 + qm_isr_inhibit = 3
143243 +};
143244 +
143245 +struct qm_portal_config {
143246 + /* Corenet portal addresses;
143247 + * [0]==cache-enabled, [1]==cache-inhibited. */
143248 + __iomem void *addr_virt[2];
143249 + struct resource addr_phys[2];
143250 + struct device dev;
143251 + struct iommu_domain *iommu_domain;
143252 + /* Allow these to be joined in lists */
143253 + struct list_head list;
143254 + /* User-visible portal configuration settings */
143255 + struct qman_portal_config public_cfg;
143256 + /* power management saved data */
143257 + u32 saved_isdr;
143258 +};
143259 +
143260 +/* Revision info (for errata and feature handling) */
143261 +#define QMAN_REV11 0x0101
143262 +#define QMAN_REV12 0x0102
143263 +#define QMAN_REV20 0x0200
143264 +#define QMAN_REV30 0x0300
143265 +#define QMAN_REV31 0x0301
143266 +#define QMAN_REV32 0x0302
143267 +
143268 +/* QMan REV_2 register contains the Cfg option */
143269 +#define QMAN_REV_CFG_0 0x0
143270 +#define QMAN_REV_CFG_1 0x1
143271 +#define QMAN_REV_CFG_2 0x2
143272 +#define QMAN_REV_CFG_3 0x3
143273 +
143274 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
143275 +extern u8 qman_ip_cfg;
143276 +extern u32 qman_clk;
143277 +extern u16 qman_portal_max;
143278 +
143279 +#ifdef CONFIG_FSL_QMAN_CONFIG
143280 +/* Hooks from qman_driver.c to qman_config.c */
143281 +int qman_init_ccsr(struct device_node *node);
143282 +void qman_liodn_fixup(u16 channel);
143283 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
143284 +size_t get_qman_fqd_size(void);
143285 +#else
143286 +static inline size_t get_qman_fqd_size(void)
143287 +{
143288 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
143289 +}
143290 +#endif
143291 +
143292 +int qm_set_wpm(int wpm);
143293 +int qm_get_wpm(int *wpm);
143294 +
143295 +/* Hooks from qman_driver.c in to qman_high.c */
143296 +struct qman_portal *qman_create_portal(
143297 + struct qman_portal *portal,
143298 + const struct qm_portal_config *config,
143299 + const struct qman_cgrs *cgrs);
143300 +
143301 +struct qman_portal *qman_create_affine_portal(
143302 + const struct qm_portal_config *config,
143303 + const struct qman_cgrs *cgrs);
143304 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
143305 + int cpu);
143306 +const struct qm_portal_config *qman_destroy_affine_portal(void);
143307 +void qman_destroy_portal(struct qman_portal *qm);
143308 +
143309 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
143310 +struct qm_portal_config *qm_get_unused_portal(void);
143311 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
143312 +
143313 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
143314 +void qm_set_liodns(struct qm_portal_config *pcfg);
143315 +
143316 +/* This CGR feature is supported by h/w and required by unit-tests and the
143317 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
143318 + * corruption of h/w fields by s/w that are usually incorruptible (because the
143319 + * counters are usually maintained entirely within h/w). As such, we declare
143320 + * this API internally. */
143321 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
143322 + struct qm_mcr_cgrtestwrite *result);
143323 +
143324 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
143325 +/* If the fq object pointer is greater than the size of context_b field,
143326 + * than a lookup table is required. */
143327 +int qman_setup_fq_lookup_table(size_t num_entries);
143328 +#endif
143329 +
143330 +
143331 +/*************************************************/
143332 +/* QMan s/w corenet portal, low-level i/face */
143333 +/*************************************************/
143334 +
143335 +/* Note: most functions are only used by the high-level interface, so are
143336 + * inlined from qman_low.h. The stuff below is for use by other parts of the
143337 + * driver. */
143338 +
143339 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
143340 + * dequeue TYPE. Choose TOKEN (8-bit).
143341 + * If SOURCE == CHANNELS,
143342 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
143343 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143344 + * priority.
143345 + * If SOURCE == SPECIFICWQ,
143346 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143347 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143348 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143349 + * same value.
143350 + */
143351 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
143352 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
143353 +#define QM_SDQCR_COUNT_EXACT1 0x0
143354 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
143355 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
143356 +#define QM_SDQCR_TYPE_MASK 0x03000000
143357 +#define QM_SDQCR_TYPE_NULL 0x0
143358 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
143359 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
143360 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
143361 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
143362 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
143363 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
143364 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
143365 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
143366 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
143367 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143368 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
143369 +
143370 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
143371 +#define QM_VDQCR_FQID_MASK 0x00ffffff
143372 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
143373 +
143374 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
143375 + * If MODE==SCHEDULED
143376 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
143377 + * If CHANNELS,
143378 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
143379 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
143380 + * priority.
143381 + * If SPECIFICWQ,
143382 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
143383 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
143384 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
143385 + * same value.
143386 + * If MODE==UNSCHEDULED
143387 + * Choose FQID().
143388 + */
143389 +#define QM_PDQCR_MODE_SCHEDULED 0x0
143390 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
143391 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
143392 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
143393 +#define QM_PDQCR_COUNT_EXACT1 0x0
143394 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
143395 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
143396 +#define QM_PDQCR_TYPE_MASK 0x03000000
143397 +#define QM_PDQCR_TYPE_NULL 0x0
143398 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
143399 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
143400 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
143401 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
143402 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
143403 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
143404 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
143405 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
143406 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
143407 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
143408 +
143409 +/* Used by all portal interrupt registers except 'inhibit'
143410 + * Channels with frame availability
143411 + */
143412 +#define QM_PIRQ_DQAVAIL 0x0000ffff
143413 +
143414 +/* The DQAVAIL interrupt fields break down into these bits; */
143415 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
143416 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
143417 +#define QM_DQAVAIL_MASK 0xffff
143418 +/* This mask contains all the "irqsource" bits visible to API users */
143419 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
143420 +
143421 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
143422 + * the disable register" rather than "disable the ability to write". */
143423 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
143424 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
143425 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
143426 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
143427 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
143428 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
143429 +/* TODO: unfortunate name-clash here, reword? */
143430 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
143431 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
143432 +
143433 +#ifdef CONFIG_FSL_QMAN_CONFIG
143434 +int qman_have_ccsr(void);
143435 +#else
143436 +#define qman_have_ccsr 0
143437 +#endif
143438 +
143439 +__init int qman_init(void);
143440 +__init int qman_resource_init(void);
143441 +
143442 +/* CEETM related */
143443 +#define QMAN_CEETM_MAX 2
143444 +extern u8 num_ceetms;
143445 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
143446 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143447 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
143448 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
143449 +int qman_ceetm_get_prescaler(u16 *pres);
143450 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
143451 + struct qm_mcr_ceetm_cq_query *cq_query);
143452 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
143453 + struct qm_mcr_ceetm_ccgr_query *response);
143454 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
143455 +
143456 +extern void *affine_portals[NR_CPUS];
143457 +const struct qm_portal_config *qman_get_qm_portal_config(
143458 + struct qman_portal *portal);
143459 +
143460 +/* power management */
143461 +#ifdef CONFIG_SUSPEND
143462 +void suspend_unused_qportal(void);
143463 +void resume_unused_qportal(void);
143464 +#endif
143465 --- /dev/null
143466 +++ b/drivers/staging/fsl_qbman/qman_test.c
143467 @@ -0,0 +1,57 @@
143468 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143469 + *
143470 + * Redistribution and use in source and binary forms, with or without
143471 + * modification, are permitted provided that the following conditions are met:
143472 + * * Redistributions of source code must retain the above copyright
143473 + * notice, this list of conditions and the following disclaimer.
143474 + * * Redistributions in binary form must reproduce the above copyright
143475 + * notice, this list of conditions and the following disclaimer in the
143476 + * documentation and/or other materials provided with the distribution.
143477 + * * Neither the name of Freescale Semiconductor nor the
143478 + * names of its contributors may be used to endorse or promote products
143479 + * derived from this software without specific prior written permission.
143480 + *
143481 + *
143482 + * ALTERNATIVELY, this software may be distributed under the terms of the
143483 + * GNU General Public License ("GPL") as published by the Free Software
143484 + * Foundation, either version 2 of that License or (at your option) any
143485 + * later version.
143486 + *
143487 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143488 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143489 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143490 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143491 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143492 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143493 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143494 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143495 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143496 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143497 + */
143498 +
143499 +#include "qman_test.h"
143500 +
143501 +MODULE_AUTHOR("Geoff Thorpe");
143502 +MODULE_LICENSE("Dual BSD/GPL");
143503 +MODULE_DESCRIPTION("Qman testing");
143504 +
143505 +static int test_init(void)
143506 +{
143507 + int loop = 1;
143508 + while (loop--) {
143509 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
143510 + qman_test_hotpotato();
143511 +#endif
143512 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
143513 + qman_test_high();
143514 +#endif
143515 + }
143516 + return 0;
143517 +}
143518 +
143519 +static void test_exit(void)
143520 +{
143521 +}
143522 +
143523 +module_init(test_init);
143524 +module_exit(test_exit);
143525 --- /dev/null
143526 +++ b/drivers/staging/fsl_qbman/qman_test.h
143527 @@ -0,0 +1,45 @@
143528 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143529 + *
143530 + * Redistribution and use in source and binary forms, with or without
143531 + * modification, are permitted provided that the following conditions are met:
143532 + * * Redistributions of source code must retain the above copyright
143533 + * notice, this list of conditions and the following disclaimer.
143534 + * * Redistributions in binary form must reproduce the above copyright
143535 + * notice, this list of conditions and the following disclaimer in the
143536 + * documentation and/or other materials provided with the distribution.
143537 + * * Neither the name of Freescale Semiconductor nor the
143538 + * names of its contributors may be used to endorse or promote products
143539 + * derived from this software without specific prior written permission.
143540 + *
143541 + *
143542 + * ALTERNATIVELY, this software may be distributed under the terms of the
143543 + * GNU General Public License ("GPL") as published by the Free Software
143544 + * Foundation, either version 2 of that License or (at your option) any
143545 + * later version.
143546 + *
143547 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143548 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143549 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143550 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143551 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143552 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143553 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143554 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143555 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143556 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143557 + */
143558 +
143559 +#include <linux/kernel.h>
143560 +#include <linux/errno.h>
143561 +#include <linux/io.h>
143562 +#include <linux/slab.h>
143563 +#include <linux/module.h>
143564 +#include <linux/interrupt.h>
143565 +#include <linux/delay.h>
143566 +#include <linux/sched.h>
143567 +
143568 +#include <linux/fsl_qman.h>
143569 +
143570 +void qman_test_hotpotato(void);
143571 +void qman_test_high(void);
143572 +
143573 --- /dev/null
143574 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
143575 @@ -0,0 +1,216 @@
143576 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143577 + *
143578 + * Redistribution and use in source and binary forms, with or without
143579 + * modification, are permitted provided that the following conditions are met:
143580 + * * Redistributions of source code must retain the above copyright
143581 + * notice, this list of conditions and the following disclaimer.
143582 + * * Redistributions in binary form must reproduce the above copyright
143583 + * notice, this list of conditions and the following disclaimer in the
143584 + * documentation and/or other materials provided with the distribution.
143585 + * * Neither the name of Freescale Semiconductor nor the
143586 + * names of its contributors may be used to endorse or promote products
143587 + * derived from this software without specific prior written permission.
143588 + *
143589 + *
143590 + * ALTERNATIVELY, this software may be distributed under the terms of the
143591 + * GNU General Public License ("GPL") as published by the Free Software
143592 + * Foundation, either version 2 of that License or (at your option) any
143593 + * later version.
143594 + *
143595 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143596 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143597 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143598 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143599 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143600 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143601 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143602 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143603 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143604 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143605 + */
143606 +
143607 +#include "qman_test.h"
143608 +
143609 +/*************/
143610 +/* constants */
143611 +/*************/
143612 +
143613 +#define CGR_ID 27
143614 +#define POOL_ID 2
143615 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
143616 +#define NUM_ENQUEUES 10
143617 +#define NUM_PARTIAL 4
143618 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
143619 + QM_SDQCR_TYPE_PRIO_QOS | \
143620 + QM_SDQCR_TOKEN_SET(0x98) | \
143621 + QM_SDQCR_CHANNELS_DEDICATED | \
143622 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
143623 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
143624 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
143625 +
143626 +/*************************************/
143627 +/* Predeclarations (eg. for fq_base) */
143628 +/*************************************/
143629 +
143630 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
143631 + struct qman_fq *,
143632 + const struct qm_dqrr_entry *);
143633 +static void cb_ern(struct qman_portal *, struct qman_fq *,
143634 + const struct qm_mr_entry *);
143635 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
143636 + const struct qm_mr_entry *);
143637 +
143638 +/***************/
143639 +/* global vars */
143640 +/***************/
143641 +
143642 +static struct qm_fd fd, fd_dq;
143643 +static struct qman_fq fq_base = {
143644 + .cb.dqrr = cb_dqrr,
143645 + .cb.ern = cb_ern,
143646 + .cb.fqs = cb_fqs
143647 +};
143648 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
143649 +static int retire_complete, sdqcr_complete;
143650 +
143651 +/**********************/
143652 +/* internal functions */
143653 +/**********************/
143654 +
143655 +/* Helpers for initialising and "incrementing" a frame descriptor */
143656 +static void fd_init(struct qm_fd *__fd)
143657 +{
143658 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
143659 + __fd->format = qm_fd_contig_big;
143660 + __fd->length29 = 0x0000ffff;
143661 + __fd->cmd = 0xfeedf00d;
143662 +}
143663 +
143664 +static void fd_inc(struct qm_fd *__fd)
143665 +{
143666 + u64 t = qm_fd_addr_get64(__fd);
143667 + int z = t >> 40;
143668 + t <<= 1;
143669 + if (z)
143670 + t |= 1;
143671 + qm_fd_addr_set64(__fd, t);
143672 + __fd->length29--;
143673 + __fd->cmd++;
143674 +}
143675 +
143676 +/* The only part of the 'fd' we can't memcmp() is the ppid */
143677 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
143678 +{
143679 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
143680 + if (!r)
143681 + r = a->format - b->format;
143682 + if (!r)
143683 + r = a->opaque - b->opaque;
143684 + if (!r)
143685 + r = a->cmd - b->cmd;
143686 + return r;
143687 +}
143688 +
143689 +/********/
143690 +/* test */
143691 +/********/
143692 +
143693 +static void do_enqueues(struct qman_fq *fq)
143694 +{
143695 + unsigned int loop;
143696 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
143697 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
143698 + (((loop + 1) == NUM_ENQUEUES) ?
143699 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
143700 + panic("qman_enqueue() failed\n");
143701 + fd_inc(&fd);
143702 + }
143703 +}
143704 +
143705 +void qman_test_high(void)
143706 +{
143707 + unsigned int flags;
143708 + int res;
143709 + struct qman_fq *fq = &fq_base;
143710 +
143711 + pr_info("qman_test_high starting\n");
143712 + fd_init(&fd);
143713 + fd_init(&fd_dq);
143714 +
143715 + /* Initialise (parked) FQ */
143716 + if (qman_create_fq(0, FQ_FLAGS, fq))
143717 + panic("qman_create_fq() failed\n");
143718 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
143719 + panic("qman_init_fq() failed\n");
143720 +
143721 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
143722 + do_enqueues(fq);
143723 + pr_info("VDQCR (till-empty);\n");
143724 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143725 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
143726 + panic("qman_volatile_dequeue() failed\n");
143727 + do_enqueues(fq);
143728 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
143729 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143730 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
143731 + panic("qman_volatile_dequeue() failed\n");
143732 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
143733 + NUM_ENQUEUES);
143734 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
143735 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
143736 + panic("qman_volatile_dequeue() failed\n");
143737 +
143738 + do_enqueues(fq);
143739 + pr_info("scheduled dequeue (till-empty)\n");
143740 + if (qman_schedule_fq(fq))
143741 + panic("qman_schedule_fq() failed\n");
143742 + wait_event(waitqueue, sdqcr_complete);
143743 +
143744 + /* Retire and OOS the FQ */
143745 + res = qman_retire_fq(fq, &flags);
143746 + if (res < 0)
143747 + panic("qman_retire_fq() failed\n");
143748 + wait_event(waitqueue, retire_complete);
143749 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
143750 + panic("leaking frames\n");
143751 + if (qman_oos_fq(fq))
143752 + panic("qman_oos_fq() failed\n");
143753 + qman_destroy_fq(fq, 0);
143754 + pr_info("qman_test_high finished\n");
143755 +}
143756 +
143757 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
143758 + struct qman_fq *fq,
143759 + const struct qm_dqrr_entry *dq)
143760 +{
143761 + if (fd_cmp(&fd_dq, &dq->fd)) {
143762 + pr_err("BADNESS: dequeued frame doesn't match;\n");
143763 + pr_err("Expected 0x%llx, got 0x%llx\n",
143764 + (unsigned long long)fd_dq.length29,
143765 + (unsigned long long)dq->fd.length29);
143766 + BUG();
143767 + }
143768 + fd_inc(&fd_dq);
143769 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
143770 + sdqcr_complete = 1;
143771 + wake_up(&waitqueue);
143772 + }
143773 + return qman_cb_dqrr_consume;
143774 +}
143775 +
143776 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
143777 + const struct qm_mr_entry *msg)
143778 +{
143779 + panic("cb_ern() unimplemented");
143780 +}
143781 +
143782 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
143783 + const struct qm_mr_entry *msg)
143784 +{
143785 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
143786 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
143787 + panic("unexpected FQS message");
143788 + pr_info("Retirement message received\n");
143789 + retire_complete = 1;
143790 + wake_up(&waitqueue);
143791 +}
143792 --- /dev/null
143793 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
143794 @@ -0,0 +1,502 @@
143795 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
143796 + *
143797 + * Redistribution and use in source and binary forms, with or without
143798 + * modification, are permitted provided that the following conditions are met:
143799 + * * Redistributions of source code must retain the above copyright
143800 + * notice, this list of conditions and the following disclaimer.
143801 + * * Redistributions in binary form must reproduce the above copyright
143802 + * notice, this list of conditions and the following disclaimer in the
143803 + * documentation and/or other materials provided with the distribution.
143804 + * * Neither the name of Freescale Semiconductor nor the
143805 + * names of its contributors may be used to endorse or promote products
143806 + * derived from this software without specific prior written permission.
143807 + *
143808 + *
143809 + * ALTERNATIVELY, this software may be distributed under the terms of the
143810 + * GNU General Public License ("GPL") as published by the Free Software
143811 + * Foundation, either version 2 of that License or (at your option) any
143812 + * later version.
143813 + *
143814 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143815 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143816 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143817 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143818 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143819 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143820 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143821 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143822 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143823 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143824 + */
143825 +
143826 +#include <linux/kthread.h>
143827 +#include <linux/platform_device.h>
143828 +#include <linux/dma-mapping.h>
143829 +#include "qman_test.h"
143830 +
143831 +/* Algorithm:
143832 + *
143833 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
143834 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
143835 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
143836 + * shuttle a "hot potato" frame around them such that every forwarding action
143837 + * moves it from one cpu to another. (The use of more than one handler per cpu
143838 + * is to allow enough handlers/FQs to truly test the significance of caching -
143839 + * ie. when cache-expiries are occurring.)
143840 + *
143841 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
143842 + * first and last words of the frame data will undergo a transformation step on
143843 + * each forwarding action. To achieve this, each handler will be assigned a
143844 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
143845 + * received by a handler, the mixer of the expected sender is XOR'd into all
143846 + * words of the entire frame, which is then validated against the original
143847 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
143848 + * the current handler. Apart from validating that the frame is taking the
143849 + * expected path, this also provides some quasi-realistic overheads to each
143850 + * forwarding action - dereferencing *all* the frame data, computation, and
143851 + * conditional branching. There is a "special" handler designated to act as the
143852 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
143853 + * to determine when the test has completed by counting HP_LOOPS iterations.
143854 + *
143855 + * Init phases:
143856 + *
143857 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
143858 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
143859 + * handlers and link-list them (but do no other handler setup).
143860 + *
143861 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143862 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143863 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
143864 + * and advance the iterator for the next loop. This includes a final fixup,
143865 + * which connects the last handler to the first (and which is why phase 2
143866 + * and 3 are separate).
143867 + *
143868 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
143869 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
143870 + * initialise FQ objects and advance the iterator for the next loop.
143871 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
143872 + * initialisation targets the correct cpu.
143873 + */
143874 +
143875 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
143876 + * the fn from irq context, which is too restrictive). */
143877 +struct bstrap {
143878 + void (*fn)(void);
143879 + atomic_t started;
143880 +};
143881 +static int bstrap_fn(void *__bstrap)
143882 +{
143883 + struct bstrap *bstrap = __bstrap;
143884 + atomic_inc(&bstrap->started);
143885 + bstrap->fn();
143886 + while (!kthread_should_stop())
143887 + msleep(1);
143888 + return 0;
143889 +}
143890 +static int on_all_cpus(void (*fn)(void))
143891 +{
143892 + int cpu;
143893 + for_each_cpu(cpu, cpu_online_mask) {
143894 + struct bstrap bstrap = {
143895 + .fn = fn,
143896 + .started = ATOMIC_INIT(0)
143897 + };
143898 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
143899 + "hotpotato%d", cpu);
143900 + int ret;
143901 + if (IS_ERR(k))
143902 + return -ENOMEM;
143903 + kthread_bind(k, cpu);
143904 + wake_up_process(k);
143905 + /* If we call kthread_stop() before the "wake up" has had an
143906 + * effect, then the thread may exit with -EINTR without ever
143907 + * running the function. So poll until it's started before
143908 + * requesting it to stop. */
143909 + while (!atomic_read(&bstrap.started))
143910 + msleep(10);
143911 + ret = kthread_stop(k);
143912 + if (ret)
143913 + return ret;
143914 + }
143915 + return 0;
143916 +}
143917 +
143918 +struct hp_handler {
143919 +
143920 + /* The following data is stashed when 'rx' is dequeued; */
143921 + /* -------------- */
143922 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
143923 + struct qman_fq rx;
143924 + /* The Tx FQ we should forward to */
143925 + struct qman_fq tx;
143926 + /* The value we XOR post-dequeue, prior to validating */
143927 + u32 rx_mixer;
143928 + /* The value we XOR pre-enqueue, after validating */
143929 + u32 tx_mixer;
143930 + /* what the hotpotato address should be on dequeue */
143931 + dma_addr_t addr;
143932 + u32 *frame_ptr;
143933 +
143934 + /* The following data isn't (necessarily) stashed on dequeue; */
143935 + /* -------------- */
143936 + u32 fqid_rx, fqid_tx;
143937 + /* list node for linking us into 'hp_cpu' */
143938 + struct list_head node;
143939 + /* Just to check ... */
143940 + unsigned int processor_id;
143941 +} ____cacheline_aligned;
143942 +
143943 +struct hp_cpu {
143944 + /* identify the cpu we run on; */
143945 + unsigned int processor_id;
143946 + /* root node for the per-cpu list of handlers */
143947 + struct list_head handlers;
143948 + /* list node for linking us into 'hp_cpu_list' */
143949 + struct list_head node;
143950 + /* when repeatedly scanning 'hp_list', each time linking the n'th
143951 + * handlers together, this is used as per-cpu iterator state */
143952 + struct hp_handler *iterator;
143953 +};
143954 +
143955 +/* Each cpu has one of these */
143956 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
143957 +
143958 +/* links together the hp_cpu structs, in first-come first-serve order. */
143959 +static LIST_HEAD(hp_cpu_list);
143960 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
143961 +
143962 +static unsigned int hp_cpu_list_length;
143963 +
143964 +/* the "special" handler, that starts and terminates the test. */
143965 +static struct hp_handler *special_handler;
143966 +static int loop_counter;
143967 +
143968 +/* handlers are allocated out of this, so they're properly aligned. */
143969 +static struct kmem_cache *hp_handler_slab;
143970 +
143971 +/* this is the frame data */
143972 +static void *__frame_ptr;
143973 +static u32 *frame_ptr;
143974 +static dma_addr_t frame_dma;
143975 +
143976 +/* the main function waits on this */
143977 +static DECLARE_WAIT_QUEUE_HEAD(queue);
143978 +
143979 +#define HP_PER_CPU 2
143980 +#define HP_LOOPS 8
143981 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
143982 +#define HP_NUM_WORDS 80
143983 +/* First word of the LFSR-based frame data */
143984 +#define HP_FIRST_WORD 0xabbaf00d
143985 +
143986 +static inline u32 do_lfsr(u32 prev)
143987 +{
143988 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
143989 +}
143990 +
143991 +static void allocate_frame_data(void)
143992 +{
143993 + u32 lfsr = HP_FIRST_WORD;
143994 + int loop;
143995 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
143996 + if (!pdev)
143997 + panic("platform_device_alloc() failed");
143998 + if (platform_device_add(pdev))
143999 + panic("platform_device_add() failed");
144000 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
144001 + if (!__frame_ptr)
144002 + panic("kmalloc() failed");
144003 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
144004 + ~(unsigned long)63);
144005 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
144006 + frame_ptr[loop] = lfsr;
144007 + lfsr = do_lfsr(lfsr);
144008 + }
144009 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
144010 + DMA_BIDIRECTIONAL);
144011 + platform_device_del(pdev);
144012 + platform_device_put(pdev);
144013 +}
144014 +
144015 +static void deallocate_frame_data(void)
144016 +{
144017 + kfree(__frame_ptr);
144018 +}
144019 +
144020 +static inline void process_frame_data(struct hp_handler *handler,
144021 + const struct qm_fd *fd)
144022 +{
144023 + u32 *p = handler->frame_ptr;
144024 + u32 lfsr = HP_FIRST_WORD;
144025 + int loop;
144026 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
144027 + pr_err("Got 0x%llx expected 0x%llx\n",
144028 + qm_fd_addr_get64(fd), handler->addr);
144029 + panic("bad frame address");
144030 + }
144031 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144032 + *p ^= handler->rx_mixer;
144033 + if (*p != lfsr)
144034 + panic("corrupt frame data");
144035 + *p ^= handler->tx_mixer;
144036 + lfsr = do_lfsr(lfsr);
144037 + }
144038 +}
144039 +
144040 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
144041 + struct qman_fq *fq,
144042 + const struct qm_dqrr_entry *dqrr)
144043 +{
144044 + struct hp_handler *handler = (struct hp_handler *)fq;
144045 +
144046 + process_frame_data(handler, &dqrr->fd);
144047 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144048 + panic("qman_enqueue() failed");
144049 + return qman_cb_dqrr_consume;
144050 +}
144051 +
144052 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
144053 + struct qman_fq *fq,
144054 + const struct qm_dqrr_entry *dqrr)
144055 +{
144056 + struct hp_handler *handler = (struct hp_handler *)fq;
144057 +
144058 + process_frame_data(handler, &dqrr->fd);
144059 + if (++loop_counter < HP_LOOPS) {
144060 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
144061 + panic("qman_enqueue() failed");
144062 + } else {
144063 + pr_info("Received final (%dth) frame\n", loop_counter);
144064 + wake_up(&queue);
144065 + }
144066 + return qman_cb_dqrr_consume;
144067 +}
144068 +
144069 +static void create_per_cpu_handlers(void)
144070 +{
144071 + struct hp_handler *handler;
144072 + int loop;
144073 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144074 +
144075 + hp_cpu->processor_id = smp_processor_id();
144076 + spin_lock(&hp_lock);
144077 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
144078 + hp_cpu_list_length++;
144079 + spin_unlock(&hp_lock);
144080 + INIT_LIST_HEAD(&hp_cpu->handlers);
144081 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144082 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
144083 + if (!handler)
144084 + panic("kmem_cache_alloc() failed");
144085 + handler->processor_id = hp_cpu->processor_id;
144086 + handler->addr = frame_dma;
144087 + handler->frame_ptr = frame_ptr;
144088 + list_add_tail(&handler->node, &hp_cpu->handlers);
144089 + }
144090 + put_cpu_var(hp_cpus);
144091 +}
144092 +
144093 +static void destroy_per_cpu_handlers(void)
144094 +{
144095 + struct list_head *loop, *tmp;
144096 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
144097 +
144098 + spin_lock(&hp_lock);
144099 + list_del(&hp_cpu->node);
144100 + spin_unlock(&hp_lock);
144101 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
144102 + u32 flags;
144103 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
144104 + node);
144105 + if (qman_retire_fq(&handler->rx, &flags))
144106 + panic("qman_retire_fq(rx) failed");
144107 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
144108 + if (qman_oos_fq(&handler->rx))
144109 + panic("qman_oos_fq(rx) failed");
144110 + qman_destroy_fq(&handler->rx, 0);
144111 + qman_destroy_fq(&handler->tx, 0);
144112 + qman_release_fqid(handler->fqid_rx);
144113 + list_del(&handler->node);
144114 + kmem_cache_free(hp_handler_slab, handler);
144115 + }
144116 + put_cpu_var(hp_cpus);
144117 +}
144118 +
144119 +static inline u8 num_cachelines(u32 offset)
144120 +{
144121 + u8 res = (offset + (L1_CACHE_BYTES - 1))
144122 + / (L1_CACHE_BYTES);
144123 + if (res > 3)
144124 + return 3;
144125 + return res;
144126 +}
144127 +#define STASH_DATA_CL \
144128 + num_cachelines(HP_NUM_WORDS * 4)
144129 +#define STASH_CTX_CL \
144130 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
144131 +
144132 +static void init_handler(void *__handler)
144133 +{
144134 + struct qm_mcc_initfq opts;
144135 + struct hp_handler *handler = __handler;
144136 + BUG_ON(handler->processor_id != smp_processor_id());
144137 + /* Set up rx */
144138 + memset(&handler->rx, 0, sizeof(handler->rx));
144139 + if (handler == special_handler)
144140 + handler->rx.cb.dqrr = special_dqrr;
144141 + else
144142 + handler->rx.cb.dqrr = normal_dqrr;
144143 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
144144 + panic("qman_create_fq(rx) failed");
144145 + memset(&opts, 0, sizeof(opts));
144146 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
144147 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
144148 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
144149 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
144150 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
144151 + QMAN_INITFQ_FLAG_LOCAL, &opts))
144152 + panic("qman_init_fq(rx) failed");
144153 + /* Set up tx */
144154 + memset(&handler->tx, 0, sizeof(handler->tx));
144155 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
144156 + &handler->tx))
144157 + panic("qman_create_fq(tx) failed");
144158 +}
144159 +
144160 +static void init_phase2(void)
144161 +{
144162 + int loop;
144163 + u32 fqid = 0;
144164 + u32 lfsr = 0xdeadbeef;
144165 + struct hp_cpu *hp_cpu;
144166 + struct hp_handler *handler;
144167 +
144168 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144169 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144170 + int ret;
144171 + if (!loop)
144172 + hp_cpu->iterator = list_first_entry(
144173 + &hp_cpu->handlers,
144174 + struct hp_handler, node);
144175 + else
144176 + hp_cpu->iterator = list_entry(
144177 + hp_cpu->iterator->node.next,
144178 + struct hp_handler, node);
144179 + /* Rx FQID is the previous handler's Tx FQID */
144180 + hp_cpu->iterator->fqid_rx = fqid;
144181 + /* Allocate new FQID for Tx */
144182 + ret = qman_alloc_fqid(&fqid);
144183 + if (ret)
144184 + panic("qman_alloc_fqid() failed");
144185 + hp_cpu->iterator->fqid_tx = fqid;
144186 + /* Rx mixer is the previous handler's Tx mixer */
144187 + hp_cpu->iterator->rx_mixer = lfsr;
144188 + /* Get new mixer for Tx */
144189 + lfsr = do_lfsr(lfsr);
144190 + hp_cpu->iterator->tx_mixer = lfsr;
144191 + }
144192 + }
144193 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
144194 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
144195 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
144196 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
144197 + handler->fqid_rx = fqid;
144198 + handler->rx_mixer = lfsr;
144199 + /* and tag it as our "special" handler */
144200 + special_handler = handler;
144201 +}
144202 +
144203 +static void init_phase3(void)
144204 +{
144205 + int loop;
144206 + struct hp_cpu *hp_cpu;
144207 +
144208 + for (loop = 0; loop < HP_PER_CPU; loop++) {
144209 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
144210 + if (!loop)
144211 + hp_cpu->iterator = list_first_entry(
144212 + &hp_cpu->handlers,
144213 + struct hp_handler, node);
144214 + else
144215 + hp_cpu->iterator = list_entry(
144216 + hp_cpu->iterator->node.next,
144217 + struct hp_handler, node);
144218 + preempt_disable();
144219 + if (hp_cpu->processor_id == smp_processor_id())
144220 + init_handler(hp_cpu->iterator);
144221 + else
144222 + smp_call_function_single(hp_cpu->processor_id,
144223 + init_handler, hp_cpu->iterator, 1);
144224 + preempt_enable();
144225 + }
144226 + }
144227 +}
144228 +
144229 +static void send_first_frame(void *ignore)
144230 +{
144231 + u32 *p = special_handler->frame_ptr;
144232 + u32 lfsr = HP_FIRST_WORD;
144233 + int loop;
144234 + struct qm_fd fd;
144235 +
144236 + BUG_ON(special_handler->processor_id != smp_processor_id());
144237 + memset(&fd, 0, sizeof(fd));
144238 + qm_fd_addr_set64(&fd, special_handler->addr);
144239 + fd.format = qm_fd_contig_big;
144240 + fd.length29 = HP_NUM_WORDS * 4;
144241 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
144242 + if (*p != lfsr)
144243 + panic("corrupt frame data");
144244 + *p ^= special_handler->tx_mixer;
144245 + lfsr = do_lfsr(lfsr);
144246 + }
144247 + pr_info("Sending first frame\n");
144248 + if (qman_enqueue(&special_handler->tx, &fd, 0))
144249 + panic("qman_enqueue() failed");
144250 +}
144251 +
144252 +void qman_test_hotpotato(void)
144253 +{
144254 + if (cpumask_weight(cpu_online_mask) < 2) {
144255 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
144256 + return;
144257 + }
144258 +
144259 + pr_info("qman_test_hotpotato starting\n");
144260 +
144261 + hp_cpu_list_length = 0;
144262 + loop_counter = 0;
144263 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
144264 + sizeof(struct hp_handler), L1_CACHE_BYTES,
144265 + SLAB_HWCACHE_ALIGN, NULL);
144266 + if (!hp_handler_slab)
144267 + panic("kmem_cache_create() failed");
144268 +
144269 + allocate_frame_data();
144270 +
144271 + /* Init phase 1 */
144272 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
144273 + if (on_all_cpus(create_per_cpu_handlers))
144274 + panic("on_each_cpu() failed");
144275 + pr_info("Number of cpus: %d, total of %d handlers\n",
144276 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
144277 +
144278 + init_phase2();
144279 +
144280 + init_phase3();
144281 +
144282 + preempt_disable();
144283 + if (special_handler->processor_id == smp_processor_id())
144284 + send_first_frame(NULL);
144285 + else
144286 + smp_call_function_single(special_handler->processor_id,
144287 + send_first_frame, NULL, 1);
144288 + preempt_enable();
144289 +
144290 + wait_event(queue, loop_counter == HP_LOOPS);
144291 + deallocate_frame_data();
144292 + if (on_all_cpus(destroy_per_cpu_handlers))
144293 + panic("on_each_cpu() failed");
144294 + kmem_cache_destroy(hp_handler_slab);
144295 + pr_info("qman_test_hotpotato finished\n");
144296 +}
144297 --- /dev/null
144298 +++ b/drivers/staging/fsl_qbman/qman_utility.c
144299 @@ -0,0 +1,129 @@
144300 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
144301 + *
144302 + * Redistribution and use in source and binary forms, with or without
144303 + * modification, are permitted provided that the following conditions are met:
144304 + * * Redistributions of source code must retain the above copyright
144305 + * notice, this list of conditions and the following disclaimer.
144306 + * * Redistributions in binary form must reproduce the above copyright
144307 + * notice, this list of conditions and the following disclaimer in the
144308 + * documentation and/or other materials provided with the distribution.
144309 + * * Neither the name of Freescale Semiconductor nor the
144310 + * names of its contributors may be used to endorse or promote products
144311 + * derived from this software without specific prior written permission.
144312 + *
144313 + *
144314 + * ALTERNATIVELY, this software may be distributed under the terms of the
144315 + * GNU General Public License ("GPL") as published by the Free Software
144316 + * Foundation, either version 2 of that License or (at your option) any
144317 + * later version.
144318 + *
144319 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144320 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144321 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144322 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144323 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144324 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144325 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144326 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144327 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144328 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144329 + */
144330 +
144331 +#include "qman_private.h"
144332 +
144333 +/* ----------------- */
144334 +/* --- FQID Pool --- */
144335 +
144336 +struct qman_fqid_pool {
144337 + /* Base and size of the FQID range */
144338 + u32 fqid_base;
144339 + u32 total;
144340 + /* Number of FQIDs currently "allocated" */
144341 + u32 used;
144342 + /* Allocation optimisation. When 'used<total', it is the index of an
144343 + * available FQID. Otherwise there are no available FQIDs, and this
144344 + * will be set when the next deallocation occurs. */
144345 + u32 next;
144346 + /* A bit-field representation of the FQID range. */
144347 + unsigned long *bits;
144348 +};
144349 +
144350 +#define QLONG_BYTES sizeof(unsigned long)
144351 +#define QLONG_BITS (QLONG_BYTES * 8)
144352 +/* Number of 'longs' required for the given number of bits */
144353 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
144354 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
144355 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
144356 +/* And in bits */
144357 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
144358 +
144359 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
144360 +{
144361 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
144362 + unsigned int i;
144363 +
144364 + BUG_ON(!num);
144365 + if (!pool)
144366 + return NULL;
144367 + pool->fqid_base = fqid_start;
144368 + pool->total = num;
144369 + pool->used = 0;
144370 + pool->next = 0;
144371 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
144372 + if (!pool->bits) {
144373 + kfree(pool);
144374 + return NULL;
144375 + }
144376 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
144377 + * byte-oriented searching) then we fill the trailing bits with 1, to
144378 + * make them look allocated (permanently). */
144379 + for (i = num + 1; i < QNUM_BITS(num); i++)
144380 + set_bit(i, pool->bits);
144381 + return pool;
144382 +}
144383 +EXPORT_SYMBOL(qman_fqid_pool_create);
144384 +
144385 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
144386 +{
144387 + int ret = pool->used;
144388 + kfree(pool->bits);
144389 + kfree(pool);
144390 + return ret;
144391 +}
144392 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
144393 +
144394 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
144395 +{
144396 + int ret;
144397 + if (pool->used == pool->total)
144398 + return -ENOMEM;
144399 + *fqid = pool->fqid_base + pool->next;
144400 + ret = test_and_set_bit(pool->next, pool->bits);
144401 + BUG_ON(ret);
144402 + if (++pool->used == pool->total)
144403 + return 0;
144404 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
144405 + if (pool->next >= pool->total)
144406 + pool->next = find_first_zero_bit(pool->bits, pool->total);
144407 + BUG_ON(pool->next >= pool->total);
144408 + return 0;
144409 +}
144410 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
144411 +
144412 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
144413 +{
144414 + int ret;
144415 +
144416 + fqid -= pool->fqid_base;
144417 + ret = test_and_clear_bit(fqid, pool->bits);
144418 + BUG_ON(!ret);
144419 + if (pool->used-- == pool->total)
144420 + pool->next = fqid;
144421 +}
144422 +EXPORT_SYMBOL(qman_fqid_pool_free);
144423 +
144424 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
144425 +{
144426 + return pool->used;
144427 +}
144428 +EXPORT_SYMBOL(qman_fqid_pool_used);
144429 --- /dev/null
144430 +++ b/include/linux/fsl_bman.h
144431 @@ -0,0 +1,532 @@
144432 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144433 + *
144434 + * Redistribution and use in source and binary forms, with or without
144435 + * modification, are permitted provided that the following conditions are met:
144436 + * * Redistributions of source code must retain the above copyright
144437 + * notice, this list of conditions and the following disclaimer.
144438 + * * Redistributions in binary form must reproduce the above copyright
144439 + * notice, this list of conditions and the following disclaimer in the
144440 + * documentation and/or other materials provided with the distribution.
144441 + * * Neither the name of Freescale Semiconductor nor the
144442 + * names of its contributors may be used to endorse or promote products
144443 + * derived from this software without specific prior written permission.
144444 + *
144445 + *
144446 + * ALTERNATIVELY, this software may be distributed under the terms of the
144447 + * GNU General Public License ("GPL") as published by the Free Software
144448 + * Foundation, either version 2 of that License or (at your option) any
144449 + * later version.
144450 + *
144451 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144452 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144453 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144454 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144455 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144456 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144457 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144458 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144459 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144460 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144461 + */
144462 +
144463 +#ifndef FSL_BMAN_H
144464 +#define FSL_BMAN_H
144465 +
144466 +#ifdef __cplusplus
144467 +extern "C" {
144468 +#endif
144469 +
144470 +/* Last updated for v00.79 of the BG */
144471 +
144472 +/* Portal processing (interrupt) sources */
144473 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
144474 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
144475 +
144476 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
144477 + * buffer pools. */
144478 +struct bman_depletion {
144479 + u32 __state[2];
144480 +};
144481 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
144482 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
144483 +#define __bmdep_word(x) ((x) >> 5)
144484 +#define __bmdep_shift(x) ((x) & 0x1f)
144485 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
144486 +static inline void bman_depletion_init(struct bman_depletion *c)
144487 +{
144488 + c->__state[0] = c->__state[1] = 0;
144489 +}
144490 +static inline void bman_depletion_fill(struct bman_depletion *c)
144491 +{
144492 + c->__state[0] = c->__state[1] = ~0;
144493 +}
144494 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
144495 +{
144496 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
144497 +}
144498 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
144499 +{
144500 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
144501 +}
144502 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
144503 +{
144504 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
144505 +}
144506 +
144507 +/* ------------------------------------------------------- */
144508 +/* --- Bman data structures (and associated constants) --- */
144509 +
144510 +/* Represents s/w corenet portal mapped data structures */
144511 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
144512 +struct bm_mc_command; /* MC (Management Command) command */
144513 +struct bm_mc_result; /* MC result */
144514 +
144515 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
144516 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
144517 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
144518 +struct bm_buffer {
144519 + union {
144520 + struct {
144521 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144522 + u8 __reserved1;
144523 + u8 bpid;
144524 + u16 hi; /* High 16-bits of 48-bit address */
144525 + u32 lo; /* Low 32-bits of 48-bit address */
144526 +#else
144527 + u32 lo;
144528 + u16 hi;
144529 + u8 bpid;
144530 + u8 __reserved;
144531 +#endif
144532 + };
144533 + struct {
144534 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
144535 + u64 __notaddress:16;
144536 + u64 addr:48;
144537 +#else
144538 + u64 addr:48;
144539 + u64 __notaddress:16;
144540 +#endif
144541 + };
144542 + u64 opaque;
144543 + };
144544 +} __aligned(8);
144545 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
144546 +{
144547 + return buf->addr;
144548 +}
144549 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
144550 +{
144551 + return (dma_addr_t)buf->addr;
144552 +}
144553 +/* Macro, so we compile better if 'v' isn't always 64-bit */
144554 +#define bm_buffer_set64(buf, v) \
144555 + do { \
144556 + struct bm_buffer *__buf931 = (buf); \
144557 + __buf931->hi = upper_32_bits(v); \
144558 + __buf931->lo = lower_32_bits(v); \
144559 + } while (0)
144560 +
144561 +/* See 1.5.3.5.4: "Release Command" */
144562 +struct bm_rcr_entry {
144563 + union {
144564 + struct {
144565 + u8 __dont_write_directly__verb;
144566 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
144567 + u8 __reserved1[62];
144568 + };
144569 + struct bm_buffer bufs[8];
144570 + };
144571 +} __packed;
144572 +#define BM_RCR_VERB_VBIT 0x80
144573 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
144574 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
144575 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
144576 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
144577 +
144578 +/* See 1.5.3.1: "Acquire Command" */
144579 +/* See 1.5.3.2: "Query Command" */
144580 +struct bm_mcc_acquire {
144581 + u8 bpid;
144582 + u8 __reserved1[62];
144583 +} __packed;
144584 +struct bm_mcc_query {
144585 + u8 __reserved2[63];
144586 +} __packed;
144587 +struct bm_mc_command {
144588 + u8 __dont_write_directly__verb;
144589 + union {
144590 + struct bm_mcc_acquire acquire;
144591 + struct bm_mcc_query query;
144592 + };
144593 +} __packed;
144594 +#define BM_MCC_VERB_VBIT 0x80
144595 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
144596 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
144597 +#define BM_MCC_VERB_CMD_QUERY 0x40
144598 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
144599 +
144600 +/* See 1.5.3.3: "Acquire Response" */
144601 +/* See 1.5.3.4: "Query Response" */
144602 +struct bm_pool_state {
144603 + u8 __reserved1[32];
144604 + /* "availability state" and "depletion state" */
144605 + struct {
144606 + u8 __reserved1[8];
144607 + /* Access using bman_depletion_***() */
144608 + struct bman_depletion state;
144609 + } as, ds;
144610 +};
144611 +struct bm_mc_result {
144612 + union {
144613 + struct {
144614 + u8 verb;
144615 + u8 __reserved1[63];
144616 + };
144617 + union {
144618 + struct {
144619 + u8 __reserved1;
144620 + u8 bpid;
144621 + u8 __reserved2[62];
144622 + };
144623 + struct bm_buffer bufs[8];
144624 + } acquire;
144625 + struct bm_pool_state query;
144626 + };
144627 +} __packed;
144628 +#define BM_MCR_VERB_VBIT 0x80
144629 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
144630 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
144631 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
144632 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
144633 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
144634 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
144635 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
144636 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
144637 + bman_depletion_get(&r->query.as.state, p)
144638 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
144639 +#define BM_MCR_QUERY_DEPLETION(r, p) \
144640 + bman_depletion_get(&r->query.ds.state, p)
144641 +
144642 +/*******************************************************************/
144643 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
144644 +/*******************************************************************/
144645 +
144646 + /* Portal and Buffer Pools */
144647 + /* ----------------------- */
144648 +/* Represents a managed portal */
144649 +struct bman_portal;
144650 +
144651 +/* This object type represents Bman buffer pools. */
144652 +struct bman_pool;
144653 +
144654 +struct bman_portal_config {
144655 + /* This is used for any "core-affine" portals, ie. default portals
144656 + * associated to the corresponding cpu. -1 implies that there is no core
144657 + * affinity configured. */
144658 + int cpu;
144659 + /* portal interrupt line */
144660 + int irq;
144661 + /* the unique index of this portal */
144662 + u32 index;
144663 + /* Is this portal shared? (If so, it has coarser locking and demuxes
144664 + * processing on behalf of other CPUs.) */
144665 + int is_shared;
144666 + /* These are the buffer pool IDs that may be used via this portal. */
144667 + struct bman_depletion mask;
144668 +};
144669 +
144670 +/* This callback type is used when handling pool depletion entry/exit. The
144671 + * 'cb_ctx' value is the opaque value associated with the pool object in
144672 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
144673 + * depletion-exit. */
144674 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
144675 + struct bman_pool *pool, void *cb_ctx, int depleted);
144676 +
144677 +/* This struct specifies parameters for a bman_pool object. */
144678 +struct bman_pool_params {
144679 + /* index of the buffer pool to encapsulate (0-63), ignored if
144680 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
144681 + u32 bpid;
144682 + /* bit-mask of BMAN_POOL_FLAG_*** options */
144683 + u32 flags;
144684 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
144685 + bman_cb_depletion cb;
144686 + /* opaque user value passed as a parameter to 'cb' */
144687 + void *cb_ctx;
144688 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
144689 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
144690 + * when run in the control plane (which controls Bman CCSR). This array
144691 + * matches the definition of bm_pool_set(). */
144692 + u32 thresholds[4];
144693 +};
144694 +
144695 +/* Flags to bman_new_pool() */
144696 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
144697 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
144698 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
144699 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
144700 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
144701 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
144702 +
144703 +/* Flags to bman_release() */
144704 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
144705 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
144706 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
144707 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
144708 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
144709 +#endif
144710 +#endif
144711 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
144712 +
144713 +/* Flags to bman_acquire() */
144714 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
144715 +
144716 + /* Portal Management */
144717 + /* ----------------- */
144718 +/**
144719 + * bman_get_portal_config - get portal configuration settings
144720 + *
144721 + * This returns a read-only view of the current cpu's affine portal settings.
144722 + */
144723 +const struct bman_portal_config *bman_get_portal_config(void);
144724 +
144725 +/**
144726 + * bman_irqsource_get - return the portal work that is interrupt-driven
144727 + *
144728 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
144729 + * enabled for interrupt handling on the current cpu's affine portal. These
144730 + * sources will trigger the portal interrupt and the interrupt handler (or a
144731 + * tasklet/bottom-half it defers to) will perform the corresponding processing
144732 + * work. The bman_poll_***() functions will only process sources that are not in
144733 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
144734 + * this always returns zero.
144735 + */
144736 +u32 bman_irqsource_get(void);
144737 +
144738 +/**
144739 + * bman_irqsource_add - add processing sources to be interrupt-driven
144740 + * @bits: bitmask of BM_PIRQ_**I processing sources
144741 + *
144742 + * Adds processing sources that should be interrupt-driven (rather than
144743 + * processed via bman_poll_***() functions). Returns zero for success, or
144744 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144745 +int bman_irqsource_add(u32 bits);
144746 +
144747 +/**
144748 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
144749 + * @bits: bitmask of BM_PIRQ_**I processing sources
144750 + *
144751 + * Removes processing sources from being interrupt-driven, so that they will
144752 + * instead be processed via bman_poll_***() functions. Returns zero for success,
144753 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
144754 +int bman_irqsource_remove(u32 bits);
144755 +
144756 +/**
144757 + * bman_affine_cpus - return a mask of cpus that have affine portals
144758 + */
144759 +const cpumask_t *bman_affine_cpus(void);
144760 +
144761 +/**
144762 + * bman_poll_slow - process anything that isn't interrupt-driven.
144763 + *
144764 + * This function does any portal processing that isn't interrupt-driven. If the
144765 + * current CPU is sharing a portal hosted on another CPU, this function will
144766 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
144767 + * indicating what interrupt sources were actually processed by the call.
144768 + *
144769 + * NB, unlike the legacy wrapper bman_poll(), this function will
144770 + * deterministically check for the presence of portal processing work and do it,
144771 + * which implies some latency even if there's nothing to do. The bman_poll()
144772 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
144773 + * checking for (and doing) portal processing infrequently. Ie. such that
144774 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
144775 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
144776 + * processing.
144777 + */
144778 +u32 bman_poll_slow(void);
144779 +
144780 +/**
144781 + * bman_poll - process anything that isn't interrupt-driven.
144782 + *
144783 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
144784 + * affine portal. This function does whatever processing is not triggered by
144785 + * interrupts. This is a legacy wrapper that can be used in core-processing
144786 + * loops but mitigates the performance overhead of portal processing by
144787 + * adaptively bypassing true portal processing most of the time. (Processing is
144788 + * done once every 10 calls if the previous processing revealed that work needed
144789 + * to be done, or once very 1000 calls if the previous processing revealed no
144790 + * work needed doing.) If you wish to control this yourself, call
144791 + * bman_poll_slow() instead, which always checks for portal processing work.
144792 + */
144793 +void bman_poll(void);
144794 +
144795 +/**
144796 + * bman_rcr_is_empty - Determine if portal's RCR is empty
144797 + *
144798 + * For use in situations where a cpu-affine caller needs to determine when all
144799 + * releases for the local portal have been processed by Bman but can't use the
144800 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
144801 + * The function forces tracking of RCR consumption (which normally doesn't
144802 + * happen until release processing needs to find space to put new release
144803 + * commands), and returns zero if the ring still has unprocessed entries,
144804 + * non-zero if it is empty.
144805 + */
144806 +int bman_rcr_is_empty(void);
144807 +
144808 +/**
144809 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
144810 + * @result: is set by the API to the base BPID of the allocated range
144811 + * @count: the number of BPIDs required
144812 + * @align: required alignment of the allocated range
144813 + * @partial: non-zero if the API can return fewer than @count BPIDs
144814 + *
144815 + * Returns the number of buffer pools allocated, or a negative error code. If
144816 + * @partial is non zero, the allocation request may return a smaller range of
144817 + * BPs than requested (though alignment will be as requested). If @partial is
144818 + * zero, the return value will either be 'count' or negative.
144819 + */
144820 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
144821 +static inline int bman_alloc_bpid(u32 *result)
144822 +{
144823 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
144824 + return (ret > 0) ? 0 : ret;
144825 +}
144826 +
144827 +/**
144828 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
144829 + * @bpid: the base BPID of the range to deallocate
144830 + * @count: the number of BPIDs in the range
144831 + *
144832 + * This function can also be used to seed the allocator with ranges of BPIDs
144833 + * that it can subsequently allocate from.
144834 + */
144835 +void bman_release_bpid_range(u32 bpid, unsigned int count);
144836 +static inline void bman_release_bpid(u32 bpid)
144837 +{
144838 + bman_release_bpid_range(bpid, 1);
144839 +}
144840 +
144841 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
144842 +static inline int bman_reserve_bpid(u32 bpid)
144843 +{
144844 + return bman_reserve_bpid_range(bpid, 1);
144845 +}
144846 +
144847 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
144848 +
144849 +
144850 +int bman_shutdown_pool(u32 bpid);
144851 +
144852 + /* Pool management */
144853 + /* --------------- */
144854 +/**
144855 + * bman_new_pool - Allocates a Buffer Pool object
144856 + * @params: parameters specifying the buffer pool ID and behaviour
144857 + *
144858 + * Creates a pool object for the given @params. A portal and the depletion
144859 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
144860 + * is set. NB, the fields from @params are copied into the new pool object, so
144861 + * the structure provided by the caller can be released or reused after the
144862 + * function returns.
144863 + */
144864 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
144865 +
144866 +/**
144867 + * bman_free_pool - Deallocates a Buffer Pool object
144868 + * @pool: the pool object to release
144869 + *
144870 + */
144871 +void bman_free_pool(struct bman_pool *pool);
144872 +
144873 +/**
144874 + * bman_get_params - Returns a pool object's parameters.
144875 + * @pool: the pool object
144876 + *
144877 + * The returned pointer refers to state within the pool object so must not be
144878 + * modified and can no longer be read once the pool object is destroyed.
144879 + */
144880 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
144881 +
144882 +/**
144883 + * bman_release - Release buffer(s) to the buffer pool
144884 + * @pool: the buffer pool object to release to
144885 + * @bufs: an array of buffers to release
144886 + * @num: the number of buffers in @bufs (1-8)
144887 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144888 + *
144889 + * Adds the given buffers to RCR entries. If the portal @p was created with the
144890 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
144891 + * utilisation of RCR. As such, these buffers may join an existing ring entry
144892 + * and/or it may not be issued right away so as to allow future releases to join
144893 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
144894 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
144895 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
144896 + * is selected, in which case it will sleep waiting for space to become
144897 + * available in RCR. If the function receives a signal before such time (and
144898 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
144899 + * it returns zero.
144900 + */
144901 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
144902 + u32 flags);
144903 +
144904 +/**
144905 + * bman_acquire - Acquire buffer(s) from a buffer pool
144906 + * @pool: the buffer pool object to acquire from
144907 + * @bufs: array for storing the acquired buffers
144908 + * @num: the number of buffers desired (@bufs is at least this big)
144909 + *
144910 + * Issues an "Acquire" command via the portal's management command interface.
144911 + * The return value will be the number of buffers obtained from the pool, or a
144912 + * negative error code if a h/w error or pool starvation was encountered. In
144913 + * the latter case, the content of @bufs is undefined.
144914 + */
144915 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
144916 + u32 flags);
144917 +
144918 +/**
144919 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
144920 + * @pool: the buffer pool object the stockpile belongs
144921 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
144922 + *
144923 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
144924 + * The return value will be a negative error code if a h/w error occurred.
144925 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
144926 + * -EAGAIN will be returned.
144927 + */
144928 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
144929 +
144930 +/**
144931 + * bman_query_pools - Query all buffer pool states
144932 + * @state: storage for the queried availability and depletion states
144933 + */
144934 +int bman_query_pools(struct bm_pool_state *state);
144935 +
144936 +#ifdef CONFIG_FSL_BMAN_CONFIG
144937 +/**
144938 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
144939 + * @pool: the buffer pool object to query
144940 + *
144941 + * Return the number of the free buffers
144942 + */
144943 +u32 bman_query_free_buffers(struct bman_pool *pool);
144944 +
144945 +/**
144946 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
144947 + * @pool: the buffer pool object to which the thresholds will be set
144948 + * @thresholds: the new thresholds
144949 + */
144950 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
144951 +#endif
144952 +
144953 +/**
144954 + * The below bman_p_***() variant might be called in a situation that the cpu
144955 + * which the portal affine to is not online yet.
144956 + * @bman_portal specifies which portal the API will use.
144957 +*/
144958 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
144959 +#ifdef __cplusplus
144960 +}
144961 +#endif
144962 +
144963 +#endif /* FSL_BMAN_H */
144964 --- /dev/null
144965 +++ b/include/linux/fsl_qman.h
144966 @@ -0,0 +1,3900 @@
144967 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144968 + *
144969 + * Redistribution and use in source and binary forms, with or without
144970 + * modification, are permitted provided that the following conditions are met:
144971 + * * Redistributions of source code must retain the above copyright
144972 + * notice, this list of conditions and the following disclaimer.
144973 + * * Redistributions in binary form must reproduce the above copyright
144974 + * notice, this list of conditions and the following disclaimer in the
144975 + * documentation and/or other materials provided with the distribution.
144976 + * * Neither the name of Freescale Semiconductor nor the
144977 + * names of its contributors may be used to endorse or promote products
144978 + * derived from this software without specific prior written permission.
144979 + *
144980 + *
144981 + * ALTERNATIVELY, this software may be distributed under the terms of the
144982 + * GNU General Public License ("GPL") as published by the Free Software
144983 + * Foundation, either version 2 of that License or (at your option) any
144984 + * later version.
144985 + *
144986 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144987 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144988 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144989 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144990 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144991 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144992 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144993 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144994 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144995 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144996 + */
144997 +
144998 +#ifndef FSL_QMAN_H
144999 +#define FSL_QMAN_H
145000 +
145001 +#ifdef __cplusplus
145002 +extern "C" {
145003 +#endif
145004 +
145005 +/* Last updated for v00.800 of the BG */
145006 +
145007 +/* Hardware constants */
145008 +#define QM_CHANNEL_SWPORTAL0 0
145009 +#define QMAN_CHANNEL_POOL1 0x21
145010 +#define QMAN_CHANNEL_CAAM 0x80
145011 +#define QMAN_CHANNEL_PME 0xa0
145012 +#define QMAN_CHANNEL_POOL1_REV3 0x401
145013 +#define QMAN_CHANNEL_CAAM_REV3 0x840
145014 +#define QMAN_CHANNEL_PME_REV3 0x860
145015 +#define QMAN_CHANNEL_DCE 0x8a0
145016 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
145017 +extern u16 qm_channel_pool1;
145018 +extern u16 qm_channel_caam;
145019 +extern u16 qm_channel_pme;
145020 +extern u16 qm_channel_dce;
145021 +enum qm_dc_portal {
145022 + qm_dc_portal_fman0 = 0,
145023 + qm_dc_portal_fman1 = 1,
145024 + qm_dc_portal_caam = 2,
145025 + qm_dc_portal_pme = 3,
145026 + qm_dc_portal_rman = 4,
145027 + qm_dc_portal_dce = 5
145028 +};
145029 +
145030 +/* Portal processing (interrupt) sources */
145031 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
145032 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
145033 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
145034 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
145035 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
145036 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
145037 +/* This mask contains all the interrupt sources that need handling except DQRI,
145038 + * ie. that if present should trigger slow-path processing. */
145039 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
145040 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
145041 +
145042 +/* --- Clock speed --- */
145043 +/* A qman driver instance may or may not know the current qman clock speed.
145044 + * However, certain CEETM calculations may not be possible if this is not known.
145045 + * The 'set' function will only succeed (return zero) if the driver did not
145046 + * already know the clock speed. Likewise, the 'get' function will only succeed
145047 + * if the driver does know the clock speed (either because it knew when booting,
145048 + * or was told via 'set'). In cases where software is running on a driver
145049 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
145050 + * and the user can obtain the current qman clock speed by other means (eg. from
145051 + * a message sent from the control-plane), then the 'set' function can be used
145052 + * to enable rate-calculations in a driver where it would otherwise not be
145053 + * possible. */
145054 +int qm_get_clock(u64 *clock_hz);
145055 +int qm_set_clock(u64 clock_hz);
145056 +
145057 +/* For qman_static_dequeue_*** APIs */
145058 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
145059 +/* for n in [1,15] */
145060 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
145061 +/* for conversion from n of qm_channel */
145062 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
145063 +{
145064 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
145065 +}
145066 +
145067 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
145068 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
145069 + * FQID(n) to fill in the frame queue ID. */
145070 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
145071 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
145072 +#define QM_VDQCR_EXACT 0x40000000
145073 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
145074 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
145075 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
145076 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
145077 +
145078 +
145079 +/* ------------------------------------------------------- */
145080 +/* --- Qman data structures (and associated constants) --- */
145081 +
145082 +/* Represents s/w corenet portal mapped data structures */
145083 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
145084 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
145085 +struct qm_mr_entry; /* MR (Message Ring) entries */
145086 +struct qm_mc_command; /* MC (Management Command) command */
145087 +struct qm_mc_result; /* MC result */
145088 +
145089 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
145090 +#define QM_FD_FORMAT_SG 0x4
145091 +#define QM_FD_FORMAT_LONG 0x2
145092 +#define QM_FD_FORMAT_COMPOUND 0x1
145093 +enum qm_fd_format {
145094 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
145095 + * scatter-gather table. 'big' implies a 29-bit length with no offset
145096 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
145097 + * implies a s/g-like table, where each entry itself represents a frame
145098 + * (contiguous or scatter-gather) and the 29-bit "length" is
145099 + * interpreted purely for congestion calculations, ie. a "congestion
145100 + * weight". */
145101 + qm_fd_contig = 0,
145102 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
145103 + qm_fd_sg = QM_FD_FORMAT_SG,
145104 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
145105 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
145106 +};
145107 +
145108 +/* Capitalised versions are un-typed but can be used in static expressions */
145109 +#define QM_FD_CONTIG 0
145110 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
145111 +#define QM_FD_SG QM_FD_FORMAT_SG
145112 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
145113 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
145114 +
145115 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
145116 +struct qm_fd {
145117 + union {
145118 + struct {
145119 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145120 + u8 dd:2; /* dynamic debug */
145121 + u8 liodn_offset:6;
145122 + u8 bpid:8; /* Buffer Pool ID */
145123 + u8 eliodn_offset:4;
145124 + u8 __reserved:4;
145125 + u8 addr_hi; /* high 8-bits of 40-bit address */
145126 + u32 addr_lo; /* low 32-bits of 40-bit address */
145127 +#else
145128 + u32 addr_lo; /* low 32-bits of 40-bit address */
145129 + u8 addr_hi; /* high 8-bits of 40-bit address */
145130 + u8 __reserved:4;
145131 + u8 eliodn_offset:4;
145132 + u8 bpid:8; /* Buffer Pool ID */
145133 + u8 liodn_offset:6;
145134 + u8 dd:2; /* dynamic debug */
145135 +#endif
145136 + };
145137 + struct {
145138 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145139 + u64 __notaddress:24;
145140 + u64 addr:40;
145141 +#else
145142 + u64 addr:40;
145143 + u64 __notaddress:24;
145144 +#endif
145145 + };
145146 + u64 opaque_addr;
145147 + };
145148 + /* The 'format' field indicates the interpretation of the remaining 29
145149 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
145150 + * other union elements. Note, union'd structs are difficult to use with
145151 + * static initialisation under gcc, in which case use the "opaque" form
145152 + * with one of the macros. */
145153 + union {
145154 + /* For easier/faster copying of this part of the fd (eg. from a
145155 + * DQRR entry to an EQCR entry) copy 'opaque' */
145156 + u32 opaque;
145157 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
145158 + struct {
145159 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145160 + enum qm_fd_format format:3;
145161 + u16 offset:9;
145162 + u32 length20:20;
145163 +#else
145164 + u32 length20:20;
145165 + u16 offset:9;
145166 + enum qm_fd_format format:3;
145167 +#endif
145168 + };
145169 + /* If 'format' is _contig_big or _sg_big, 29b length */
145170 + struct {
145171 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145172 + enum qm_fd_format _format1:3;
145173 + u32 length29:29;
145174 +#else
145175 + u32 length29:29;
145176 + enum qm_fd_format _format1:3;
145177 +#endif
145178 + };
145179 + /* If 'format' is _compound, 29b "congestion weight" */
145180 + struct {
145181 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145182 + enum qm_fd_format _format2:3;
145183 + u32 cong_weight:29;
145184 +#else
145185 + u32 cong_weight:29;
145186 + enum qm_fd_format _format2:3;
145187 +#endif
145188 + };
145189 + };
145190 + union {
145191 + u32 cmd;
145192 + u32 status;
145193 + };
145194 +} __aligned(8);
145195 +#define QM_FD_DD_NULL 0x00
145196 +#define QM_FD_PID_MASK 0x3f
145197 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
145198 +{
145199 + return fd->addr;
145200 +}
145201 +
145202 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
145203 +{
145204 + return (dma_addr_t)fd->addr;
145205 +}
145206 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145207 +#define qm_fd_addr_set64(fd, v) \
145208 + do { \
145209 + struct qm_fd *__fd931 = (fd); \
145210 + __fd931->addr = v; \
145211 + } while (0)
145212 +
145213 +/* For static initialisation of FDs (which is complicated by the use of unions
145214 + * in "struct qm_fd"), use the following macros. Note that;
145215 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
145216 + * use-case),
145217 + * - use capitalised QM_FD_*** formats for static initialisation.
145218 + */
145219 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
145220 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145221 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
145222 + { cmd } }
145223 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
145224 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
145225 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
145226 + { cmd } }
145227 +
145228 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
145229 +#define QM_SG_OFFSET_MASK 0x1FFF
145230 +struct qm_sg_entry {
145231 + union {
145232 + struct {
145233 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145234 + u8 __reserved1[3];
145235 + u8 addr_hi; /* high 8-bits of 40-bit address */
145236 + u32 addr_lo; /* low 32-bits of 40-bit address */
145237 +#else
145238 + u32 addr_lo; /* low 32-bits of 40-bit address */
145239 + u8 addr_hi; /* high 8-bits of 40-bit address */
145240 + u8 __reserved1[3];
145241 +#endif
145242 + };
145243 + struct {
145244 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145245 + u64 __notaddress:24;
145246 + u64 addr:40;
145247 +#else
145248 + u64 addr:40;
145249 + u64 __notaddress:24;
145250 +#endif
145251 + };
145252 + u64 opaque;
145253 + };
145254 + union {
145255 + struct {
145256 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145257 + u32 extension:1; /* Extension bit */
145258 + u32 final:1; /* Final bit */
145259 + u32 length:30;
145260 +#else
145261 + u32 length:30;
145262 + u32 final:1; /* Final bit */
145263 + u32 extension:1; /* Extension bit */
145264 +#endif
145265 + };
145266 + u32 sgt_efl;
145267 + };
145268 + u8 __reserved2;
145269 + u8 bpid;
145270 + union {
145271 + struct {
145272 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145273 + u16 __reserved3:3;
145274 + u16 offset:13;
145275 +#else
145276 + u16 offset:13;
145277 + u16 __reserved3:3;
145278 +#endif
145279 + };
145280 + u16 opaque_offset;
145281 + };
145282 +} __packed;
145283 +union qm_sg_efl {
145284 + struct {
145285 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145286 + u32 extension:1; /* Extension bit */
145287 + u32 final:1; /* Final bit */
145288 + u32 length:30;
145289 +#else
145290 + u32 length:30;
145291 + u32 final:1; /* Final bit */
145292 + u32 extension:1; /* Extension bit */
145293 +#endif
145294 + };
145295 + u32 efl;
145296 +};
145297 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
145298 +{
145299 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
145300 +}
145301 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
145302 +{
145303 + union qm_sg_efl u;
145304 +
145305 + u.efl = be32_to_cpu(sg->sgt_efl);
145306 + return u.extension;
145307 +}
145308 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
145309 +{
145310 + union qm_sg_efl u;
145311 +
145312 + u.efl = be32_to_cpu(sg->sgt_efl);
145313 + return u.final;
145314 +}
145315 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
145316 +{
145317 + union qm_sg_efl u;
145318 +
145319 + u.efl = be32_to_cpu(sg->sgt_efl);
145320 + return u.length;
145321 +}
145322 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
145323 +{
145324 + return sg->bpid;
145325 +}
145326 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
145327 +{
145328 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
145329 +
145330 + return opaque_offset & 0x1fff;
145331 +}
145332 +
145333 +/* Macro, so we compile better if 'v' isn't always 64-bit */
145334 +#define qm_sg_entry_set64(sg, v) \
145335 + do { \
145336 + struct qm_sg_entry *__sg931 = (sg); \
145337 + __sg931->opaque = cpu_to_be64(v); \
145338 + } while (0)
145339 +#define qm_sg_entry_set_ext(sg, v) \
145340 + do { \
145341 + union qm_sg_efl __u932; \
145342 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
145343 + __u932.extension = v; \
145344 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
145345 + } while (0)
145346 +#define qm_sg_entry_set_final(sg, v) \
145347 + do { \
145348 + union qm_sg_efl __u933; \
145349 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
145350 + __u933.final = v; \
145351 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
145352 + } while (0)
145353 +#define qm_sg_entry_set_len(sg, v) \
145354 + do { \
145355 + union qm_sg_efl __u934; \
145356 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
145357 + __u934.length = v; \
145358 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
145359 + } while (0)
145360 +#define qm_sg_entry_set_bpid(sg, v) \
145361 + do { \
145362 + struct qm_sg_entry *__u935 = (sg); \
145363 + __u935->bpid = v; \
145364 + } while (0)
145365 +#define qm_sg_entry_set_offset(sg, v) \
145366 + do { \
145367 + struct qm_sg_entry *__u936 = (sg); \
145368 + __u936->opaque_offset = cpu_to_be16(v); \
145369 + } while (0)
145370 +
145371 +/* See 1.5.8.1: "Enqueue Command" */
145372 +struct qm_eqcr_entry {
145373 + u8 __dont_write_directly__verb;
145374 + u8 dca;
145375 + u16 seqnum;
145376 + u32 orp; /* 24-bit */
145377 + u32 fqid; /* 24-bit */
145378 + u32 tag;
145379 + struct qm_fd fd;
145380 + u8 __reserved3[32];
145381 +} __packed;
145382 +#define QM_EQCR_VERB_VBIT 0x80
145383 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
145384 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
145385 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
145386 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
145387 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
145388 +#define QM_EQCR_VERB_COLOUR_RED 0x10
145389 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
145390 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
145391 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
145392 +#define QM_EQCR_DCA_ENABLE 0x80
145393 +#define QM_EQCR_DCA_PARK 0x40
145394 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
145395 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
145396 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
145397 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
145398 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
145399 +
145400 +/* See 1.5.8.2: "Frame Dequeue Response" */
145401 +struct qm_dqrr_entry {
145402 + u8 verb;
145403 + u8 stat;
145404 + u16 seqnum; /* 15-bit */
145405 + u8 tok;
145406 + u8 __reserved2[3];
145407 + u32 fqid; /* 24-bit */
145408 + u32 contextB;
145409 + struct qm_fd fd;
145410 + u8 __reserved4[32];
145411 +};
145412 +#define QM_DQRR_VERB_VBIT 0x80
145413 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
145414 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
145415 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
145416 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
145417 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
145418 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
145419 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
145420 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
145421 +
145422 +/* See 1.5.8.3: "ERN Message Response" */
145423 +/* See 1.5.8.4: "FQ State Change Notification" */
145424 +struct qm_mr_entry {
145425 + u8 verb;
145426 + union {
145427 + struct {
145428 + u8 dca;
145429 + u16 seqnum;
145430 + u8 rc; /* Rejection Code */
145431 + u32 orp:24;
145432 + u32 fqid; /* 24-bit */
145433 + u32 tag;
145434 + struct qm_fd fd;
145435 + } __packed ern;
145436 + struct {
145437 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145438 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145439 + u8 __reserved1:3;
145440 + enum qm_dc_portal portal:3;
145441 +#else
145442 + enum qm_dc_portal portal:3;
145443 + u8 __reserved1:3;
145444 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
145445 +#endif
145446 + u16 __reserved2;
145447 + u8 rc; /* Rejection Code */
145448 + u32 __reserved3:24;
145449 + u32 fqid; /* 24-bit */
145450 + u32 tag;
145451 + struct qm_fd fd;
145452 + } __packed dcern;
145453 + struct {
145454 + u8 fqs; /* Frame Queue Status */
145455 + u8 __reserved1[6];
145456 + u32 fqid; /* 24-bit */
145457 + u32 contextB;
145458 + u8 __reserved2[16];
145459 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
145460 + };
145461 + u8 __reserved2[32];
145462 +} __packed;
145463 +#define QM_MR_VERB_VBIT 0x80
145464 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
145465 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
145466 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
145467 + * the other MR types by noting if the 0x20 bit is unset. */
145468 +#define QM_MR_VERB_TYPE_MASK 0x27
145469 +#define QM_MR_VERB_DC_ERN 0x20
145470 +#define QM_MR_VERB_FQRN 0x21
145471 +#define QM_MR_VERB_FQRNI 0x22
145472 +#define QM_MR_VERB_FQRL 0x23
145473 +#define QM_MR_VERB_FQPN 0x24
145474 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
145475 +#define QM_MR_RC_CGR_TAILDROP 0x00
145476 +#define QM_MR_RC_WRED 0x10
145477 +#define QM_MR_RC_ERROR 0x20
145478 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
145479 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
145480 +#define QM_MR_RC_FQ_TAILDROP 0x50
145481 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
145482 +#define QM_MR_RC_ORP_ZERO 0x70
145483 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
145484 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
145485 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
145486 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
145487 +#define QM_MR_DCERN_COLOUR_RED 0x02
145488 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
145489 +
145490 +/* An identical structure of FQD fields is present in the "Init FQ" command and
145491 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
145492 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
145493 + * latter has two inlines to assist with converting to/from the mant+exp
145494 + * representation. */
145495 +struct qm_fqd_stashing {
145496 + /* See QM_STASHING_EXCL_<...> */
145497 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145498 + u8 exclusive;
145499 + u8 __reserved1:2;
145500 + /* Numbers of cachelines */
145501 + u8 annotation_cl:2;
145502 + u8 data_cl:2;
145503 + u8 context_cl:2;
145504 +#else
145505 + u8 context_cl:2;
145506 + u8 data_cl:2;
145507 + u8 annotation_cl:2;
145508 + u8 __reserved1:2;
145509 + u8 exclusive;
145510 +#endif
145511 +} __packed;
145512 +struct qm_fqd_taildrop {
145513 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145514 + u16 __reserved1:3;
145515 + u16 mant:8;
145516 + u16 exp:5;
145517 +#else
145518 + u16 exp:5;
145519 + u16 mant:8;
145520 + u16 __reserved1:3;
145521 +#endif
145522 +} __packed;
145523 +struct qm_fqd_oac {
145524 + /* See QM_OAC_<...> */
145525 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145526 + u8 oac:2; /* "Overhead Accounting Control" */
145527 + u8 __reserved1:6;
145528 +#else
145529 + u8 __reserved1:6;
145530 + u8 oac:2; /* "Overhead Accounting Control" */
145531 +#endif
145532 + /* Two's-complement value (-128 to +127) */
145533 + signed char oal; /* "Overhead Accounting Length" */
145534 +} __packed;
145535 +struct qm_fqd {
145536 + union {
145537 + u8 orpc;
145538 + struct {
145539 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145540 + u8 __reserved1:2;
145541 + u8 orprws:3;
145542 + u8 oa:1;
145543 + u8 olws:2;
145544 +#else
145545 + u8 olws:2;
145546 + u8 oa:1;
145547 + u8 orprws:3;
145548 + u8 __reserved1:2;
145549 +#endif
145550 + } __packed;
145551 + };
145552 + u8 cgid;
145553 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
145554 + union {
145555 + u16 dest_wq;
145556 + struct {
145557 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145558 + u16 channel:13; /* qm_channel */
145559 + u16 wq:3;
145560 +#else
145561 + u16 wq:3;
145562 + u16 channel:13; /* qm_channel */
145563 +#endif
145564 + } __packed dest;
145565 + };
145566 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145567 + u16 __reserved2:1;
145568 + u16 ics_cred:15;
145569 +#else
145570 + u16 __reserved2:1;
145571 + u16 ics_cred:15;
145572 +#endif
145573 + /* For "Initialize Frame Queue" commands, the write-enable mask
145574 + * determines whether 'td' or 'oac_init' is observed. For query
145575 + * commands, this field is always 'td', and 'oac_query' (below) reflects
145576 + * the Overhead ACcounting values. */
145577 + union {
145578 + struct qm_fqd_taildrop td;
145579 + struct qm_fqd_oac oac_init;
145580 + };
145581 + u32 context_b;
145582 + union {
145583 + /* Treat it as 64-bit opaque */
145584 + u64 opaque;
145585 + struct {
145586 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145587 + u32 hi;
145588 + u32 lo;
145589 +#else
145590 + u32 lo;
145591 + u32 hi;
145592 +#endif
145593 + };
145594 + /* Treat it as s/w portal stashing config */
145595 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145596 + struct {
145597 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145598 + struct qm_fqd_stashing stashing;
145599 + /* 48-bit address of FQ context to
145600 + * stash, must be cacheline-aligned */
145601 + u16 context_hi;
145602 + u32 context_lo;
145603 +#else
145604 + u32 context_lo;
145605 + u16 context_hi;
145606 + struct qm_fqd_stashing stashing;
145607 +#endif
145608 + } __packed;
145609 + } context_a;
145610 + struct qm_fqd_oac oac_query;
145611 +} __packed;
145612 +/* 64-bit converters for context_hi/lo */
145613 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
145614 +{
145615 + return ((u64)fqd->context_a.context_hi << 32) |
145616 + (u64)fqd->context_a.context_lo;
145617 +}
145618 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
145619 +{
145620 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
145621 +}
145622 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
145623 +{
145624 + return ((u64)fqd->context_a.hi << 32) |
145625 + (u64)fqd->context_a.lo;
145626 +}
145627 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
145628 +#define qm_fqd_stashing_set64(fqd, v) \
145629 + do { \
145630 + struct qm_fqd *__fqd931 = (fqd); \
145631 + __fqd931->context_a.context_hi = upper_32_bits(v); \
145632 + __fqd931->context_a.context_lo = lower_32_bits(v); \
145633 + } while (0)
145634 +#define qm_fqd_context_a_set64(fqd, v) \
145635 + do { \
145636 + struct qm_fqd *__fqd931 = (fqd); \
145637 + __fqd931->context_a.hi = upper_32_bits(v); \
145638 + __fqd931->context_a.lo = lower_32_bits(v); \
145639 + } while (0)
145640 +/* convert a threshold value into mant+exp representation */
145641 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
145642 + int roundup)
145643 +{
145644 + u32 e = 0;
145645 + int oddbit = 0;
145646 + if (val > 0xe0000000)
145647 + return -ERANGE;
145648 + while (val > 0xff) {
145649 + oddbit = val & 1;
145650 + val >>= 1;
145651 + e++;
145652 + if (roundup && oddbit)
145653 + val++;
145654 + }
145655 + td->exp = e;
145656 + td->mant = val;
145657 + return 0;
145658 +}
145659 +/* and the other direction */
145660 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
145661 +{
145662 + return (u32)td->mant << td->exp;
145663 +}
145664 +
145665 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
145666 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
145667 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
145668 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
145669 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
145670 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
145671 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
145672 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
145673 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
145674 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
145675 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
145676 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
145677 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
145678 +
145679 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
145680 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
145681 +#define QM_STASHING_EXCL_ANNOTATION 0x04
145682 +#define QM_STASHING_EXCL_DATA 0x02
145683 +#define QM_STASHING_EXCL_CTX 0x01
145684 +
145685 +/* See 1.5.5.3: "Intra Class Scheduling" */
145686 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
145687 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
145688 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
145689 +
145690 +/* See 1.5.8.4: "FQ State Change Notification" */
145691 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
145692 + * and associated commands/responses. The WRED parameters are calculated from
145693 + * these fields as follows;
145694 + * MaxTH = MA * (2 ^ Mn)
145695 + * Slope = SA / (2 ^ Sn)
145696 + * MaxP = 4 * (Pn + 1)
145697 + */
145698 +struct qm_cgr_wr_parm {
145699 + union {
145700 + u32 word;
145701 + struct {
145702 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145703 + u32 MA:8;
145704 + u32 Mn:5;
145705 + u32 SA:7; /* must be between 64-127 */
145706 + u32 Sn:6;
145707 + u32 Pn:6;
145708 +#else
145709 + u32 Pn:6;
145710 + u32 Sn:6;
145711 + u32 SA:7; /* must be between 64-127 */
145712 + u32 Mn:5;
145713 + u32 MA:8;
145714 +#endif
145715 + } __packed;
145716 + };
145717 +} __packed;
145718 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
145719 + * management commands, this is padded to a 16-bit structure field, so that's
145720 + * how we represent it here. The congestion state threshold is calculated from
145721 + * these fields as follows;
145722 + * CS threshold = TA * (2 ^ Tn)
145723 + */
145724 +struct qm_cgr_cs_thres {
145725 + union {
145726 + u16 hword;
145727 + struct {
145728 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145729 + u16 __reserved:3;
145730 + u16 TA:8;
145731 + u16 Tn:5;
145732 +#else
145733 + u16 Tn:5;
145734 + u16 TA:8;
145735 + u16 __reserved:3;
145736 +#endif
145737 + } __packed;
145738 + };
145739 +} __packed;
145740 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
145741 + * commands and the "Query CGR" result. It's suctioned out here into its own
145742 + * struct. */
145743 +struct __qm_mc_cgr {
145744 + struct qm_cgr_wr_parm wr_parm_g;
145745 + struct qm_cgr_wr_parm wr_parm_y;
145746 + struct qm_cgr_wr_parm wr_parm_r;
145747 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
145748 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
145749 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
145750 + u8 cscn_en; /* boolean, use QM_CGR_EN */
145751 + union {
145752 + struct {
145753 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145754 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145755 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145756 +#else
145757 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
145758 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
145759 +#endif
145760 + };
145761 + u32 cscn_targ; /* use QM_CGR_TARG_* */
145762 + };
145763 + u8 cstd_en; /* boolean, use QM_CGR_EN */
145764 + u8 cs; /* boolean, only used in query response */
145765 + union {
145766 + /* use qm_cgr_cs_thres_set64() */
145767 + struct qm_cgr_cs_thres cs_thres;
145768 + u16 __cs_thres;
145769 + };
145770 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
145771 +} __packed;
145772 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
145773 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
145774 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
145775 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
145776 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
145777 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
145778 +/* Convert CGR thresholds to/from "cs_thres" format */
145779 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
145780 +{
145781 + return (u64)th->TA << th->Tn;
145782 +}
145783 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
145784 + int roundup)
145785 +{
145786 + u32 e = 0;
145787 + int oddbit = 0;
145788 + while (val > 0xff) {
145789 + oddbit = val & 1;
145790 + val >>= 1;
145791 + e++;
145792 + if (roundup && oddbit)
145793 + val++;
145794 + }
145795 + th->Tn = e;
145796 + th->TA = val;
145797 + return 0;
145798 +}
145799 +
145800 +/* See 1.5.8.5.1: "Initialize FQ" */
145801 +/* See 1.5.8.5.2: "Query FQ" */
145802 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
145803 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
145804 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
145805 +/* See 1.5.8.6.2: "CGR Test Write" */
145806 +/* See 1.5.8.6.3: "Query CGR" */
145807 +/* See 1.5.8.6.4: "Query Congestion Group State" */
145808 +struct qm_mcc_initfq {
145809 + u8 __reserved1;
145810 + u16 we_mask; /* Write Enable Mask */
145811 + u32 fqid; /* 24-bit */
145812 + u16 count; /* Initialises 'count+1' FQDs */
145813 + struct qm_fqd fqd; /* the FQD fields go here */
145814 + u8 __reserved3[30];
145815 +} __packed;
145816 +struct qm_mcc_queryfq {
145817 + u8 __reserved1[3];
145818 + u32 fqid; /* 24-bit */
145819 + u8 __reserved2[56];
145820 +} __packed;
145821 +struct qm_mcc_queryfq_np {
145822 + u8 __reserved1[3];
145823 + u32 fqid; /* 24-bit */
145824 + u8 __reserved2[56];
145825 +} __packed;
145826 +struct qm_mcc_alterfq {
145827 + u8 __reserved1[3];
145828 + u32 fqid; /* 24-bit */
145829 + u8 __reserved2;
145830 + u8 count; /* number of consecutive FQID */
145831 + u8 __reserved3[10];
145832 + u32 context_b; /* frame queue context b */
145833 + u8 __reserved4[40];
145834 +} __packed;
145835 +struct qm_mcc_initcgr {
145836 + u8 __reserved1;
145837 + u16 we_mask; /* Write Enable Mask */
145838 + struct __qm_mc_cgr cgr; /* CGR fields */
145839 + u8 __reserved2[2];
145840 + u8 cgid;
145841 + u8 __reserved4[32];
145842 +} __packed;
145843 +struct qm_mcc_cgrtestwrite {
145844 + u8 __reserved1[2];
145845 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
145846 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
145847 + u8 __reserved2[23];
145848 + u8 cgid;
145849 + u8 __reserved3[32];
145850 +} __packed;
145851 +struct qm_mcc_querycgr {
145852 + u8 __reserved1[30];
145853 + u8 cgid;
145854 + u8 __reserved2[32];
145855 +} __packed;
145856 +struct qm_mcc_querycongestion {
145857 + u8 __reserved[63];
145858 +} __packed;
145859 +struct qm_mcc_querywq {
145860 + u8 __reserved;
145861 + /* select channel if verb != QUERYWQ_DEDICATED */
145862 + union {
145863 + u16 channel_wq; /* ignores wq (3 lsbits) */
145864 + struct {
145865 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145866 + u16 id:13; /* qm_channel */
145867 + u16 __reserved1:3;
145868 +#else
145869 + u16 __reserved1:3;
145870 + u16 id:13; /* qm_channel */
145871 +#endif
145872 + } __packed channel;
145873 + };
145874 + u8 __reserved2[60];
145875 +} __packed;
145876 +
145877 +struct qm_mcc_ceetm_lfqmt_config {
145878 + u8 __reserved1[4];
145879 + u32 lfqid:24;
145880 + u8 __reserved2[2];
145881 + u16 cqid;
145882 + u8 __reserved3[2];
145883 + u16 dctidx;
145884 + u8 __reserved4[48];
145885 +} __packed;
145886 +
145887 +struct qm_mcc_ceetm_lfqmt_query {
145888 + u8 __reserved1[4];
145889 + u32 lfqid:24;
145890 + u8 __reserved2[56];
145891 +} __packed;
145892 +
145893 +struct qm_mcc_ceetm_cq_config {
145894 + u8 __reserved1;
145895 + u16 cqid;
145896 + u8 dcpid;
145897 + u8 __reserved2;
145898 + u16 ccgid;
145899 + u8 __reserved3[56];
145900 +} __packed;
145901 +
145902 +struct qm_mcc_ceetm_cq_query {
145903 + u8 __reserved1;
145904 + u16 cqid;
145905 + u8 dcpid;
145906 + u8 __reserved2[59];
145907 +} __packed;
145908 +
145909 +struct qm_mcc_ceetm_dct_config {
145910 + u8 __reserved1;
145911 + u16 dctidx;
145912 + u8 dcpid;
145913 + u8 __reserved2[15];
145914 + u32 context_b;
145915 + u64 context_a;
145916 + u8 __reserved3[32];
145917 +} __packed;
145918 +
145919 +struct qm_mcc_ceetm_dct_query {
145920 + u8 __reserved1;
145921 + u16 dctidx;
145922 + u8 dcpid;
145923 + u8 __reserved2[59];
145924 +} __packed;
145925 +
145926 +struct qm_mcc_ceetm_class_scheduler_config {
145927 + u8 __reserved1;
145928 + u16 cqcid;
145929 + u8 dcpid;
145930 + u8 __reserved2[6];
145931 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145932 + u8 gpc_reserved:1;
145933 + u8 gpc_combine_flag:1;
145934 + u8 gpc_prio_b:3;
145935 + u8 gpc_prio_a:3;
145936 +#else
145937 + u8 gpc_prio_a:3;
145938 + u8 gpc_prio_b:3;
145939 + u8 gpc_combine_flag:1;
145940 + u8 gpc_reserved:1;
145941 +#endif
145942 + u16 crem;
145943 + u16 erem;
145944 + u8 w[8];
145945 + u8 __reserved3[40];
145946 +} __packed;
145947 +
145948 +struct qm_mcc_ceetm_class_scheduler_query {
145949 + u8 __reserved1;
145950 + u16 cqcid;
145951 + u8 dcpid;
145952 + u8 __reserved2[59];
145953 +} __packed;
145954 +
145955 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
145956 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
145957 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
145958 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
145959 +#define CEETM_COMMAND_TCFC (4 << 12)
145960 +
145961 +#define CEETM_CCGRID_MASK 0x01FF
145962 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
145963 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
145964 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
145965 +#define CEETM_CCGR_CM_QUERY (0 << 14)
145966 +#define CEETM_CCGR_DN_QUERY (1 << 14)
145967 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
145968 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
145969 +
145970 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
145971 + u8 __reserved1;
145972 + u16 cid;
145973 + u8 dcpid;
145974 + union {
145975 + struct {
145976 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145977 + u8 map_shaped:1;
145978 + u8 map_reserved:4;
145979 + u8 map_lni_id:3;
145980 +#else
145981 + u8 map_lni_id:3;
145982 + u8 map_reserved:4;
145983 + u8 map_shaped:1;
145984 +#endif
145985 + u8 __reserved2[58];
145986 + } __packed channel_mapping;
145987 + struct {
145988 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145989 + u8 map_reserved:5;
145990 + u8 map_lni_id:3;
145991 +#else
145992 + u8 map_lni_id:3;
145993 + u8 map_reserved:5;
145994 +#endif
145995 + u8 __reserved2[58];
145996 + } __packed sp_mapping;
145997 + struct {
145998 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
145999 + u8 cpl:1;
146000 + u8 cpl_reserved:2;
146001 + u8 oal:5;
146002 +#else
146003 + u8 oal:5;
146004 + u8 cpl_reserved:2;
146005 + u8 cpl:1;
146006 +#endif
146007 + u32 crtcr:24;
146008 + u32 ertcr:24;
146009 + u16 crtbl;
146010 + u16 ertbl;
146011 + u8 mps; /* This will be hardcoded by driver with 60 */
146012 + u8 __reserved2[47];
146013 + } __packed shaper_config;
146014 + struct {
146015 + u8 __reserved2[11];
146016 + u64 lnitcfcc;
146017 + u8 __reserved3[40];
146018 + } __packed tcfc_config;
146019 + };
146020 +} __packed;
146021 +
146022 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
146023 + u8 __reserved1;
146024 + u16 cid;
146025 + u8 dcpid;
146026 + u8 __reserved2[59];
146027 +} __packed;
146028 +
146029 +struct qm_mcc_ceetm_ccgr_config {
146030 + u8 __reserved1;
146031 + u16 ccgrid;
146032 + u8 dcpid;
146033 + u8 __reserved2;
146034 + u16 we_mask;
146035 + union {
146036 + struct {
146037 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146038 + u8 ctl_reserved:1;
146039 + u8 ctl_wr_en_g:1;
146040 + u8 ctl_wr_en_y:1;
146041 + u8 ctl_wr_en_r:1;
146042 + u8 ctl_td_en:1;
146043 + u8 ctl_td_mode:1;
146044 + u8 ctl_cscn_en:1;
146045 + u8 ctl_mode:1;
146046 +#else
146047 + u8 ctl_mode:1;
146048 + u8 ctl_cscn_en:1;
146049 + u8 ctl_td_mode:1;
146050 + u8 ctl_td_en:1;
146051 + u8 ctl_wr_en_r:1;
146052 + u8 ctl_wr_en_y:1;
146053 + u8 ctl_wr_en_g:1;
146054 + u8 ctl_reserved:1;
146055 +#endif
146056 + u8 cdv;
146057 + u16 cscn_tupd;
146058 + u8 oal;
146059 + u8 __reserved3;
146060 + struct qm_cgr_cs_thres cs_thres;
146061 + struct qm_cgr_cs_thres cs_thres_x;
146062 + struct qm_cgr_cs_thres td_thres;
146063 + struct qm_cgr_wr_parm wr_parm_g;
146064 + struct qm_cgr_wr_parm wr_parm_y;
146065 + struct qm_cgr_wr_parm wr_parm_r;
146066 + } __packed cm_config;
146067 + struct {
146068 + u8 dnc;
146069 + u8 dn0;
146070 + u8 dn1;
146071 + u64 dnba:40;
146072 + u8 __reserved3[2];
146073 + u16 dnth_0;
146074 + u8 __reserved4[2];
146075 + u16 dnth_1;
146076 + u8 __reserved5[8];
146077 + } __packed dn_config;
146078 + struct {
146079 + u8 __reserved3[3];
146080 + u64 i_cnt:40;
146081 + u8 __reserved4[16];
146082 + } __packed test_write;
146083 + };
146084 + u8 __reserved5[32];
146085 +} __packed;
146086 +
146087 +struct qm_mcc_ceetm_ccgr_query {
146088 + u8 __reserved1;
146089 + u16 ccgrid;
146090 + u8 dcpid;
146091 + u8 __reserved2[59];
146092 +} __packed;
146093 +
146094 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
146095 + u8 __reserved1;
146096 + u16 cqid;
146097 + u8 dcpid;
146098 + u8 ct;
146099 + u16 xsfdr;
146100 + u8 __reserved2[56];
146101 +} __packed;
146102 +
146103 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
146104 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
146105 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
146106 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
146107 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
146108 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
146109 +struct qm_mcc_ceetm_statistics_query_write {
146110 + u8 __reserved1;
146111 + u16 cid;
146112 + u8 dcpid;
146113 + u8 ct;
146114 + u8 __reserved2[13];
146115 + u64 frm_cnt:40;
146116 + u8 __reserved3[2];
146117 + u64 byte_cnt:48;
146118 + u8 __reserved[32];
146119 +} __packed;
146120 +
146121 +struct qm_mc_command {
146122 + u8 __dont_write_directly__verb;
146123 + union {
146124 + struct qm_mcc_initfq initfq;
146125 + struct qm_mcc_queryfq queryfq;
146126 + struct qm_mcc_queryfq_np queryfq_np;
146127 + struct qm_mcc_alterfq alterfq;
146128 + struct qm_mcc_initcgr initcgr;
146129 + struct qm_mcc_cgrtestwrite cgrtestwrite;
146130 + struct qm_mcc_querycgr querycgr;
146131 + struct qm_mcc_querycongestion querycongestion;
146132 + struct qm_mcc_querywq querywq;
146133 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
146134 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
146135 + struct qm_mcc_ceetm_cq_config cq_config;
146136 + struct qm_mcc_ceetm_cq_query cq_query;
146137 + struct qm_mcc_ceetm_dct_config dct_config;
146138 + struct qm_mcc_ceetm_dct_query dct_query;
146139 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
146140 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
146141 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
146142 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
146143 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
146144 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
146145 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146146 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
146147 + };
146148 +} __packed;
146149 +#define QM_MCC_VERB_VBIT 0x80
146150 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
146151 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
146152 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
146153 +#define QM_MCC_VERB_QUERYFQ 0x44
146154 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
146155 +#define QM_MCC_VERB_QUERYWQ 0x46
146156 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
146157 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
146158 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
146159 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
146160 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
146161 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
146162 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
146163 +#define QM_MCC_VERB_INITCGR 0x50
146164 +#define QM_MCC_VERB_MODIFYCGR 0x51
146165 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
146166 +#define QM_MCC_VERB_QUERYCGR 0x58
146167 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
146168 +/* INITFQ-specific flags */
146169 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
146170 +#define QM_INITFQ_WE_OAC 0x0100
146171 +#define QM_INITFQ_WE_ORPC 0x0080
146172 +#define QM_INITFQ_WE_CGID 0x0040
146173 +#define QM_INITFQ_WE_FQCTRL 0x0020
146174 +#define QM_INITFQ_WE_DESTWQ 0x0010
146175 +#define QM_INITFQ_WE_ICSCRED 0x0008
146176 +#define QM_INITFQ_WE_TDTHRESH 0x0004
146177 +#define QM_INITFQ_WE_CONTEXTB 0x0002
146178 +#define QM_INITFQ_WE_CONTEXTA 0x0001
146179 +/* INITCGR/MODIFYCGR-specific flags */
146180 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
146181 +#define QM_CGR_WE_WR_PARM_G 0x0400
146182 +#define QM_CGR_WE_WR_PARM_Y 0x0200
146183 +#define QM_CGR_WE_WR_PARM_R 0x0100
146184 +#define QM_CGR_WE_WR_EN_G 0x0080
146185 +#define QM_CGR_WE_WR_EN_Y 0x0040
146186 +#define QM_CGR_WE_WR_EN_R 0x0020
146187 +#define QM_CGR_WE_CSCN_EN 0x0010
146188 +#define QM_CGR_WE_CSCN_TARG 0x0008
146189 +#define QM_CGR_WE_CSTD_EN 0x0004
146190 +#define QM_CGR_WE_CS_THRES 0x0002
146191 +#define QM_CGR_WE_MODE 0x0001
146192 +
146193 +/* See 1.5.9.7 CEETM Management Commands */
146194 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
146195 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
146196 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
146197 +#define QM_CEETM_VERB_CQ_QUERY 0x73
146198 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
146199 +#define QM_CEETM_VERB_DCT_QUERY 0x75
146200 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
146201 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
146202 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
146203 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
146204 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
146205 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
146206 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
146207 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
146208 +
146209 +/* See 1.5.8.5.1: "Initialize FQ" */
146210 +/* See 1.5.8.5.2: "Query FQ" */
146211 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
146212 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
146213 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
146214 +/* See 1.5.8.6.2: "CGR Test Write" */
146215 +/* See 1.5.8.6.3: "Query CGR" */
146216 +/* See 1.5.8.6.4: "Query Congestion Group State" */
146217 +struct qm_mcr_initfq {
146218 + u8 __reserved1[62];
146219 +} __packed;
146220 +struct qm_mcr_queryfq {
146221 + u8 __reserved1[8];
146222 + struct qm_fqd fqd; /* the FQD fields are here */
146223 + u8 __reserved2[30];
146224 +} __packed;
146225 +struct qm_mcr_queryfq_np {
146226 + u8 __reserved1;
146227 + u8 state; /* QM_MCR_NP_STATE_*** */
146228 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146229 + u8 __reserved2;
146230 + u32 fqd_link:24;
146231 + u16 __reserved3:2;
146232 + u16 odp_seq:14;
146233 + u16 __reserved4:2;
146234 + u16 orp_nesn:14;
146235 + u16 __reserved5:1;
146236 + u16 orp_ea_hseq:15;
146237 + u16 __reserved6:1;
146238 + u16 orp_ea_tseq:15;
146239 + u8 __reserved7;
146240 + u32 orp_ea_hptr:24;
146241 + u8 __reserved8;
146242 + u32 orp_ea_tptr:24;
146243 + u8 __reserved9;
146244 + u32 pfdr_hptr:24;
146245 + u8 __reserved10;
146246 + u32 pfdr_tptr:24;
146247 + u8 __reserved11[5];
146248 + u8 __reserved12:7;
146249 + u8 is:1;
146250 + u16 ics_surp;
146251 + u32 byte_cnt;
146252 + u8 __reserved13;
146253 + u32 frm_cnt:24;
146254 + u32 __reserved14;
146255 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146256 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146257 + u16 __reserved15;
146258 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146259 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146260 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146261 +#else
146262 + u8 __reserved2;
146263 + u32 fqd_link:24;
146264 +
146265 + u16 odp_seq:14;
146266 + u16 __reserved3:2;
146267 +
146268 + u16 orp_nesn:14;
146269 + u16 __reserved4:2;
146270 +
146271 + u16 orp_ea_hseq:15;
146272 + u16 __reserved5:1;
146273 +
146274 + u16 orp_ea_tseq:15;
146275 + u16 __reserved6:1;
146276 +
146277 + u8 __reserved7;
146278 + u32 orp_ea_hptr:24;
146279 +
146280 + u8 __reserved8;
146281 + u32 orp_ea_tptr:24;
146282 +
146283 + u8 __reserved9;
146284 + u32 pfdr_hptr:24;
146285 +
146286 + u8 __reserved10;
146287 + u32 pfdr_tptr:24;
146288 +
146289 + u8 __reserved11[5];
146290 + u8 is:1;
146291 + u8 __reserved12:7;
146292 + u16 ics_surp;
146293 + u32 byte_cnt;
146294 + u8 __reserved13;
146295 + u32 frm_cnt:24;
146296 + u32 __reserved14;
146297 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
146298 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
146299 + u16 __reserved15;
146300 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
146301 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
146302 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
146303 +#endif
146304 +} __packed;
146305 +
146306 +
146307 +struct qm_mcr_alterfq {
146308 + u8 fqs; /* Frame Queue Status */
146309 + u8 __reserved1[61];
146310 +} __packed;
146311 +struct qm_mcr_initcgr {
146312 + u8 __reserved1[62];
146313 +} __packed;
146314 +struct qm_mcr_cgrtestwrite {
146315 + u16 __reserved1;
146316 + struct __qm_mc_cgr cgr; /* CGR fields */
146317 + u8 __reserved2[3];
146318 + u32 __reserved3:24;
146319 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146320 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146321 + u32 __reserved4:24;
146322 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146323 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146324 + u16 lgt; /* Last Group Tick */
146325 + u16 wr_prob_g;
146326 + u16 wr_prob_y;
146327 + u16 wr_prob_r;
146328 + u8 __reserved5[8];
146329 +} __packed;
146330 +struct qm_mcr_querycgr {
146331 + u16 __reserved1;
146332 + struct __qm_mc_cgr cgr; /* CGR fields */
146333 + u8 __reserved2[3];
146334 + union {
146335 + struct {
146336 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146337 + u32 __reserved3:24;
146338 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146339 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146340 +#else
146341 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
146342 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
146343 + u32 __reserved3:24;
146344 +#endif
146345 + };
146346 + u64 i_bcnt;
146347 + };
146348 + union {
146349 + struct {
146350 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146351 + u32 __reserved4:24;
146352 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146353 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146354 +#else
146355 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
146356 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
146357 + u32 __reserved4:24;
146358 +#endif
146359 + };
146360 + u64 a_bcnt;
146361 + };
146362 + union {
146363 + u32 cscn_targ_swp[4];
146364 + u8 __reserved5[16];
146365 + };
146366 +} __packed;
146367 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
146368 +{
146369 + return be64_to_cpu(q->i_bcnt);
146370 +}
146371 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
146372 +{
146373 + return be64_to_cpu(q->a_bcnt);
146374 +}
146375 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
146376 + const struct qm_mcr_cgrtestwrite *q)
146377 +{
146378 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
146379 +}
146380 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
146381 + const struct qm_mcr_cgrtestwrite *q)
146382 +{
146383 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
146384 +}
146385 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146386 +#define qm_mcr_querycgr_i_set64(q, v) \
146387 + do { \
146388 + struct qm_mcr_querycgr *__q931 = (fd); \
146389 + __q931->i_bcnt_hi = upper_32_bits(v); \
146390 + __q931->i_bcnt_lo = lower_32_bits(v); \
146391 + } while (0)
146392 +#define qm_mcr_querycgr_a_set64(q, v) \
146393 + do { \
146394 + struct qm_mcr_querycgr *__q931 = (fd); \
146395 + __q931->a_bcnt_hi = upper_32_bits(v); \
146396 + __q931->a_bcnt_lo = lower_32_bits(v); \
146397 + } while (0)
146398 +struct __qm_mcr_querycongestion {
146399 + u32 __state[8];
146400 +};
146401 +struct qm_mcr_querycongestion {
146402 + u8 __reserved[30];
146403 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
146404 + struct __qm_mcr_querycongestion state;
146405 +} __packed;
146406 +struct qm_mcr_querywq {
146407 + union {
146408 + u16 channel_wq; /* ignores wq (3 lsbits) */
146409 + struct {
146410 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146411 + u16 id:13; /* qm_channel */
146412 + u16 __reserved:3;
146413 +#else
146414 + u16 __reserved:3;
146415 + u16 id:13; /* qm_channel */
146416 +#endif
146417 + } __packed channel;
146418 + };
146419 + u8 __reserved[28];
146420 + u32 wq_len[8];
146421 +} __packed;
146422 +
146423 +/* QMAN CEETM Management Command Response */
146424 +struct qm_mcr_ceetm_lfqmt_config {
146425 + u8 __reserved1[62];
146426 +} __packed;
146427 +struct qm_mcr_ceetm_lfqmt_query {
146428 + u8 __reserved1[8];
146429 + u16 cqid;
146430 + u8 __reserved2[2];
146431 + u16 dctidx;
146432 + u8 __reserved3[2];
146433 + u16 ccgid;
146434 + u8 __reserved4[44];
146435 +} __packed;
146436 +
146437 +struct qm_mcr_ceetm_cq_config {
146438 + u8 __reserved1[62];
146439 +} __packed;
146440 +
146441 +struct qm_mcr_ceetm_cq_query {
146442 + u8 __reserved1[4];
146443 + u16 ccgid;
146444 + u16 state;
146445 + u32 pfdr_hptr:24;
146446 + u32 pfdr_tptr:24;
146447 + u16 od1_xsfdr;
146448 + u16 od2_xsfdr;
146449 + u16 od3_xsfdr;
146450 + u16 od4_xsfdr;
146451 + u16 od5_xsfdr;
146452 + u16 od6_xsfdr;
146453 + u16 ra1_xsfdr;
146454 + u16 ra2_xsfdr;
146455 + u8 __reserved2;
146456 + u32 frm_cnt:24;
146457 + u8 __reserved333[28];
146458 +} __packed;
146459 +
146460 +struct qm_mcr_ceetm_dct_config {
146461 + u8 __reserved1[62];
146462 +} __packed;
146463 +
146464 +struct qm_mcr_ceetm_dct_query {
146465 + u8 __reserved1[18];
146466 + u32 context_b;
146467 + u64 context_a;
146468 + u8 __reserved2[32];
146469 +} __packed;
146470 +
146471 +struct qm_mcr_ceetm_class_scheduler_config {
146472 + u8 __reserved1[62];
146473 +} __packed;
146474 +
146475 +struct qm_mcr_ceetm_class_scheduler_query {
146476 + u8 __reserved1[9];
146477 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146478 + u8 gpc_reserved:1;
146479 + u8 gpc_combine_flag:1;
146480 + u8 gpc_prio_b:3;
146481 + u8 gpc_prio_a:3;
146482 +#else
146483 + u8 gpc_prio_a:3;
146484 + u8 gpc_prio_b:3;
146485 + u8 gpc_combine_flag:1;
146486 + u8 gpc_reserved:1;
146487 +#endif
146488 + u16 crem;
146489 + u16 erem;
146490 + u8 w[8];
146491 + u8 __reserved2[5];
146492 + u32 wbfslist:24;
146493 + u32 d8;
146494 + u32 d9;
146495 + u32 d10;
146496 + u32 d11;
146497 + u32 d12;
146498 + u32 d13;
146499 + u32 d14;
146500 + u32 d15;
146501 +} __packed;
146502 +
146503 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
146504 + u16 cid;
146505 + u8 __reserved2[60];
146506 +} __packed;
146507 +
146508 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
146509 + u16 cid;
146510 + u8 __reserved1;
146511 + union {
146512 + struct {
146513 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146514 + u8 map_shaped:1;
146515 + u8 map_reserved:4;
146516 + u8 map_lni_id:3;
146517 +#else
146518 + u8 map_lni_id:3;
146519 + u8 map_reserved:4;
146520 + u8 map_shaped:1;
146521 +#endif
146522 + u8 __reserved2[58];
146523 + } __packed channel_mapping_query;
146524 + struct {
146525 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146526 + u8 map_reserved:5;
146527 + u8 map_lni_id:3;
146528 +#else
146529 + u8 map_lni_id:3;
146530 + u8 map_reserved:5;
146531 +#endif
146532 + u8 __reserved2[58];
146533 + } __packed sp_mapping_query;
146534 + struct {
146535 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146536 + u8 cpl:1;
146537 + u8 cpl_reserved:2;
146538 + u8 oal:5;
146539 +#else
146540 + u8 oal:5;
146541 + u8 cpl_reserved:2;
146542 + u8 cpl:1;
146543 +#endif
146544 + u32 crtcr:24;
146545 + u32 ertcr:24;
146546 + u16 crtbl;
146547 + u16 ertbl;
146548 + u8 mps;
146549 + u8 __reserved2[15];
146550 + u32 crat;
146551 + u32 erat;
146552 + u8 __reserved3[24];
146553 + } __packed shaper_query;
146554 + struct {
146555 + u8 __reserved1[11];
146556 + u64 lnitcfcc;
146557 + u8 __reserved3[40];
146558 + } __packed tcfc_query;
146559 + };
146560 +} __packed;
146561 +
146562 +struct qm_mcr_ceetm_ccgr_config {
146563 + u8 __reserved1[46];
146564 + union {
146565 + u8 __reserved2[8];
146566 + struct {
146567 + u16 timestamp;
146568 + u16 wr_porb_g;
146569 + u16 wr_prob_y;
146570 + u16 wr_prob_r;
146571 + } __packed test_write;
146572 + };
146573 + u8 __reserved3[8];
146574 +} __packed;
146575 +
146576 +struct qm_mcr_ceetm_ccgr_query {
146577 + u8 __reserved1[6];
146578 + union {
146579 + struct {
146580 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146581 + u8 ctl_reserved:1;
146582 + u8 ctl_wr_en_g:1;
146583 + u8 ctl_wr_en_y:1;
146584 + u8 ctl_wr_en_r:1;
146585 + u8 ctl_td_en:1;
146586 + u8 ctl_td_mode:1;
146587 + u8 ctl_cscn_en:1;
146588 + u8 ctl_mode:1;
146589 +#else
146590 + u8 ctl_mode:1;
146591 + u8 ctl_cscn_en:1;
146592 + u8 ctl_td_mode:1;
146593 + u8 ctl_td_en:1;
146594 + u8 ctl_wr_en_r:1;
146595 + u8 ctl_wr_en_y:1;
146596 + u8 ctl_wr_en_g:1;
146597 + u8 ctl_reserved:1;
146598 +#endif
146599 + u8 cdv;
146600 + u8 __reserved2[2];
146601 + u8 oal;
146602 + u8 __reserved3;
146603 + struct qm_cgr_cs_thres cs_thres;
146604 + struct qm_cgr_cs_thres cs_thres_x;
146605 + struct qm_cgr_cs_thres td_thres;
146606 + struct qm_cgr_wr_parm wr_parm_g;
146607 + struct qm_cgr_wr_parm wr_parm_y;
146608 + struct qm_cgr_wr_parm wr_parm_r;
146609 + u16 cscn_targ_dcp;
146610 + u8 dcp_lsn;
146611 + u64 i_cnt:40;
146612 + u8 __reserved4[3];
146613 + u64 a_cnt:40;
146614 + u32 cscn_targ_swp[4];
146615 + } __packed cm_query;
146616 + struct {
146617 + u8 dnc;
146618 + u8 dn0;
146619 + u8 dn1;
146620 + u64 dnba:40;
146621 + u8 __reserved2[2];
146622 + u16 dnth_0;
146623 + u8 __reserved3[2];
146624 + u16 dnth_1;
146625 + u8 __reserved4[10];
146626 + u16 dnacc_0;
146627 + u8 __reserved5[2];
146628 + u16 dnacc_1;
146629 + u8 __reserved6[24];
146630 + } __packed dn_query;
146631 + struct {
146632 + u8 __reserved2[24];
146633 + struct __qm_mcr_querycongestion state;
146634 + } __packed congestion_state;
146635 +
146636 + };
146637 +} __packed;
146638 +
146639 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
146640 + u8 stat;
146641 + u8 __reserved1[11];
146642 + u16 dctidx;
146643 + struct qm_fd fd;
146644 + u8 __reserved2[32];
146645 +} __packed;
146646 +
146647 +struct qm_mcr_ceetm_statistics_query {
146648 + u8 __reserved1[17];
146649 + u64 frm_cnt:40;
146650 + u8 __reserved2[2];
146651 + u64 byte_cnt:48;
146652 + u8 __reserved3[32];
146653 +} __packed;
146654 +
146655 +struct qm_mc_result {
146656 + u8 verb;
146657 + u8 result;
146658 + union {
146659 + struct qm_mcr_initfq initfq;
146660 + struct qm_mcr_queryfq queryfq;
146661 + struct qm_mcr_queryfq_np queryfq_np;
146662 + struct qm_mcr_alterfq alterfq;
146663 + struct qm_mcr_initcgr initcgr;
146664 + struct qm_mcr_cgrtestwrite cgrtestwrite;
146665 + struct qm_mcr_querycgr querycgr;
146666 + struct qm_mcr_querycongestion querycongestion;
146667 + struct qm_mcr_querywq querywq;
146668 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
146669 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
146670 + struct qm_mcr_ceetm_cq_config cq_config;
146671 + struct qm_mcr_ceetm_cq_query cq_query;
146672 + struct qm_mcr_ceetm_dct_config dct_config;
146673 + struct qm_mcr_ceetm_dct_query dct_query;
146674 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
146675 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
146676 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
146677 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
146678 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
146679 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
146680 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
146681 + struct qm_mcr_ceetm_statistics_query stats_query;
146682 + };
146683 +} __packed;
146684 +
146685 +#define QM_MCR_VERB_RRID 0x80
146686 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
146687 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
146688 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
146689 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
146690 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
146691 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
146692 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
146693 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
146694 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
146695 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
146696 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
146697 +#define QM_MCR_RESULT_NULL 0x00
146698 +#define QM_MCR_RESULT_OK 0xf0
146699 +#define QM_MCR_RESULT_ERR_FQID 0xf1
146700 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
146701 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
146702 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
146703 +#define QM_MCR_RESULT_PENDING 0xf8
146704 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
146705 +#define QM_MCR_NP_STATE_FE 0x10
146706 +#define QM_MCR_NP_STATE_R 0x08
146707 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
146708 +#define QM_MCR_NP_STATE_OOS 0x00
146709 +#define QM_MCR_NP_STATE_RETIRED 0x01
146710 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
146711 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
146712 +#define QM_MCR_NP_STATE_PARKED 0x04
146713 +#define QM_MCR_NP_STATE_ACTIVE 0x05
146714 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
146715 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
146716 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
146717 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
146718 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
146719 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
146720 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
146721 +/* This extracts the state for congestion group 'n' from a query response.
146722 + * Eg.
146723 + * u8 cgr = [...];
146724 + * struct qm_mc_result *res = [...];
146725 + * printf("congestion group %d congestion state: %d\n", cgr,
146726 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
146727 + */
146728 +#define __CGR_WORD(num) (num >> 5)
146729 +#define __CGR_SHIFT(num) (num & 0x1f)
146730 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
146731 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
146732 + u8 cgr)
146733 +{
146734 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
146735 +}
146736 +
146737 +
146738 +/*********************/
146739 +/* Utility interface */
146740 +/*********************/
146741 +
146742 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
146743 + * spinlock them yourself if needed. */
146744 +struct qman_fqid_pool;
146745 +
146746 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
146747 + * always succeeds, but returns non-zero if there were "leaked" FQID
146748 + * allocations. */
146749 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
146750 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
146751 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
146752 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
146753 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
146754 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
146755 +
146756 +/*******************************************************************/
146757 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146758 +/*******************************************************************/
146759 +
146760 + /* Portal and Frame Queues */
146761 + /* ----------------------- */
146762 +/* Represents a managed portal */
146763 +struct qman_portal;
146764 +
146765 +/* This object type represents Qman frame queue descriptors (FQD), it is
146766 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
146767 + * defined further down. */
146768 +struct qman_fq;
146769 +
146770 +/* This object type represents a Qman congestion group, it is defined further
146771 + * down. */
146772 +struct qman_cgr;
146773 +
146774 +struct qman_portal_config {
146775 + /* If the caller enables DQRR stashing (and thus wishes to operate the
146776 + * portal from only one cpu), this is the logical CPU that the portal
146777 + * will stash to. Whether stashing is enabled or not, this setting is
146778 + * also used for any "core-affine" portals, ie. default portals
146779 + * associated to the corresponding cpu. -1 implies that there is no core
146780 + * affinity configured. */
146781 + int cpu;
146782 + /* portal interrupt line */
146783 + int irq;
146784 + /* the unique index of this portal */
146785 + u32 index;
146786 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146787 + * processing on behalf of other CPUs.) */
146788 + int is_shared;
146789 + /* The portal's dedicated channel id, use this value for initialising
146790 + * frame queues to target this portal when scheduled. */
146791 + u16 channel;
146792 + /* A mask of which pool channels this portal has dequeue access to
146793 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
146794 + u32 pools;
146795 +};
146796 +
146797 +/* This enum, and the callback type that returns it, are used when handling
146798 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
146799 + * portal object (for handling dequeues that do not demux because contextB is
146800 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
146801 +enum qman_cb_dqrr_result {
146802 + /* DQRR entry can be consumed */
146803 + qman_cb_dqrr_consume,
146804 + /* Like _consume, but requests parking - FQ must be held-active */
146805 + qman_cb_dqrr_park,
146806 + /* Does not consume, for DCA mode only. This allows out-of-order
146807 + * consumes by explicit calls to qman_dca() and/or the use of implicit
146808 + * DCA via EQCR entries. */
146809 + qman_cb_dqrr_defer,
146810 + /* Stop processing without consuming this ring entry. Exits the current
146811 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
146812 + * interrupt handler, the callback would typically call
146813 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
146814 + * otherwise the interrupt will reassert immediately. */
146815 + qman_cb_dqrr_stop,
146816 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
146817 + qman_cb_dqrr_consume_stop
146818 +};
146819 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
146820 + struct qman_fq *fq,
146821 + const struct qm_dqrr_entry *dqrr);
146822 +
146823 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
146824 + * are always consumed after the callback returns. */
146825 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
146826 + const struct qm_mr_entry *msg);
146827 +
146828 +/* This callback type is used when handling DCP ERNs */
146829 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
146830 + const struct qm_mr_entry *msg);
146831 +
146832 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
146833 + * held-active + held-suspended are just "sched". Things like "retired" will not
146834 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
146835 + * then, to indicate it's completing and to gate attempts to retry the retire
146836 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
146837 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
146838 + * index rather than the FQ that ring entry corresponds to), so repeated park
146839 + * commands are allowed (if you're silly enough to try) but won't change FQ
146840 + * state, and the resulting park notifications move FQs from "sched" to
146841 + * "parked". */
146842 +enum qman_fq_state {
146843 + qman_fq_state_oos,
146844 + qman_fq_state_parked,
146845 + qman_fq_state_sched,
146846 + qman_fq_state_retired
146847 +};
146848 +
146849 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
146850 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
146851 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
146852 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
146853 + * they should;
146854 + *
146855 + * (a) extend the qman_fq structure with their state; eg.
146856 + *
146857 + * // myfq is allocated and driver_fq callbacks filled in;
146858 + * struct my_fq {
146859 + * struct qman_fq base;
146860 + * int an_extra_field;
146861 + * [ ... add other fields to be associated with each FQ ...]
146862 + * } *myfq = some_my_fq_allocator();
146863 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
146864 + *
146865 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
146866 + * struct my_fq *myfq = (struct my_fq *)fq;
146867 + * do_something_with(myfq->an_extra_field);
146868 + * [...]
146869 + *
146870 + * (b) when and if configuring the FQ for context stashing, specify how ever
146871 + * many cachelines are required to stash 'struct my_fq', to accelerate not
146872 + * only the Qman driver but the callback as well.
146873 + */
146874 +
146875 +struct qman_fq_cb {
146876 + qman_cb_dqrr dqrr; /* for dequeued frames */
146877 + qman_cb_mr ern; /* for s/w ERNs */
146878 + qman_cb_mr fqs; /* frame-queue state changes*/
146879 +};
146880 +
146881 +struct qman_fq {
146882 + /* Caller of qman_create_fq() provides these demux callbacks */
146883 + struct qman_fq_cb cb;
146884 + /* These are internal to the driver, don't touch. In particular, they
146885 + * may change, be removed, or extended (so you shouldn't rely on
146886 + * sizeof(qman_fq) being a constant). */
146887 + spinlock_t fqlock;
146888 + u32 fqid;
146889 + volatile unsigned long flags;
146890 + enum qman_fq_state state;
146891 + int cgr_groupid;
146892 + struct rb_node node;
146893 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
146894 + u32 key;
146895 +#endif
146896 +};
146897 +
146898 +/* This callback type is used when handling congestion group entry/exit.
146899 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
146900 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
146901 + struct qman_cgr *cgr, int congested);
146902 +
146903 +struct qman_cgr {
146904 + /* Set these prior to qman_create_cgr() */
146905 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
146906 + qman_cb_cgr cb;
146907 + /* These are private to the driver */
146908 + u16 chan; /* portal channel this object is created on */
146909 + struct list_head node;
146910 +};
146911 +
146912 +/* Flags to qman_create_fq() */
146913 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
146914 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
146915 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
146916 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
146917 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
146918 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
146919 +
146920 +/* Flags to qman_destroy_fq() */
146921 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
146922 +
146923 +/* Flags from qman_fq_state() */
146924 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
146925 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
146926 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
146927 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
146928 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
146929 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
146930 +
146931 +/* Flags to qman_init_fq() */
146932 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
146933 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
146934 +
146935 +/* Flags to qman_volatile_dequeue() */
146936 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146937 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
146938 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
146939 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
146940 +#endif
146941 +
146942 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
146943 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
146944 + * any change here should be audited in PME.) */
146945 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146946 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
146947 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
146948 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146949 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146950 +#endif
146951 +#endif
146952 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
146953 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
146954 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
146955 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
146956 + (((u32)(p) << 2) & 0x00000f00)
146957 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
146958 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
146959 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
146960 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
146961 +/* For the ORP-specific qman_enqueue_orp() variant;
146962 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
146963 + * of a frame. */
146964 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
146965 +/* - this flag performs no enqueue but fills in an ORP sequence number that
146966 + * would otherwise block it (eg. if a frame has been dropped). */
146967 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
146968 +/* - this flag performs no enqueue but advances NESN to the given sequence
146969 + * number. */
146970 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
146971 +
146972 +/* Flags to qman_modify_cgr() */
146973 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
146974 +#define QMAN_CGR_MODE_FRAME 0x00000001
146975 +
146976 + /* Portal Management */
146977 + /* ----------------- */
146978 +/**
146979 + * qman_get_portal_config - get portal configuration settings
146980 + *
146981 + * This returns a read-only view of the current cpu's affine portal settings.
146982 + */
146983 +const struct qman_portal_config *qman_get_portal_config(void);
146984 +
146985 +/**
146986 + * qman_irqsource_get - return the portal work that is interrupt-driven
146987 + *
146988 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
146989 + * enabled for interrupt handling on the current cpu's affine portal. These
146990 + * sources will trigger the portal interrupt and the interrupt handler (or a
146991 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146992 + * work. The qman_poll_***() functions will only process sources that are not in
146993 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146994 + * this always returns zero.
146995 + */
146996 +u32 qman_irqsource_get(void);
146997 +
146998 +/**
146999 + * qman_irqsource_add - add processing sources to be interrupt-driven
147000 + * @bits: bitmask of QM_PIRQ_**I processing sources
147001 + *
147002 + * Adds processing sources that should be interrupt-driven (rather than
147003 + * processed via qman_poll_***() functions). Returns zero for success, or
147004 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147005 + */
147006 +int qman_irqsource_add(u32 bits);
147007 +
147008 +/**
147009 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
147010 + * @bits: bitmask of QM_PIRQ_**I processing sources
147011 + *
147012 + * Removes processing sources from being interrupt-driven, so that they will
147013 + * instead be processed via qman_poll_***() functions. Returns zero for success,
147014 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
147015 + */
147016 +int qman_irqsource_remove(u32 bits);
147017 +
147018 +/**
147019 + * qman_affine_cpus - return a mask of cpus that have affine portals
147020 + */
147021 +const cpumask_t *qman_affine_cpus(void);
147022 +
147023 +/**
147024 + * qman_affine_channel - return the channel ID of an portal
147025 + * @cpu: the cpu whose affine portal is the subject of the query
147026 + *
147027 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
147028 + * bug to call this function for any value of @cpu (other than -1) that is not a
147029 + * member of the mask returned from qman_affine_cpus().
147030 + */
147031 +u16 qman_affine_channel(int cpu);
147032 +
147033 +/**
147034 + * qman_get_affine_portal - return the portal pointer affine to cpu
147035 + * @cpu: the cpu whose affine portal is the subject of the query
147036 + *
147037 + */
147038 +void *qman_get_affine_portal(int cpu);
147039 +
147040 +/**
147041 + * qman_poll_dqrr - process DQRR (fast-path) entries
147042 + * @limit: the maximum number of DQRR entries to process
147043 + *
147044 + * Use of this function requires that DQRR processing not be interrupt-driven.
147045 + * Ie. the value returned by qman_irqsource_get() should not include
147046 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
147047 + * this function will return -EINVAL, otherwise the return value is >=0 and
147048 + * represents the number of DQRR entries processed.
147049 + */
147050 +int qman_poll_dqrr(unsigned int limit);
147051 +
147052 +/**
147053 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
147054 + *
147055 + * This function does any portal processing that isn't interrupt-driven. If the
147056 + * current CPU is sharing a portal hosted on another CPU, this function will
147057 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
147058 + * indicating what interrupt sources were actually processed by the call.
147059 + */
147060 +u32 qman_poll_slow(void);
147061 +
147062 +/**
147063 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
147064 + *
147065 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
147066 + * affine portal. There are two classes of portal processing in question;
147067 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
147068 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
147069 + * thresholds, congestion state changes, etc). This function does whatever
147070 + * processing is not triggered by interrupts.
147071 + *
147072 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
147073 + * interrupt-driven) then this function uses a heuristic to determine how often
147074 + * to run slow-path processing - as slow-path processing introduces at least a
147075 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
147076 + * close to zero-cost if there is no work to be done. Applications can tune this
147077 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
147078 + * rather than going via this wrapper.
147079 + */
147080 +void qman_poll(void);
147081 +
147082 +/**
147083 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
147084 + *
147085 + * Disables DQRR processing of the portal. This is reference-counted, so
147086 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147087 + * truly re-enable dequeuing.
147088 + */
147089 +void qman_stop_dequeues(void);
147090 +
147091 +/**
147092 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
147093 + *
147094 + * Enables DQRR processing of the portal. This is reference-counted, so
147095 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
147096 + * truly re-enable dequeuing.
147097 + */
147098 +void qman_start_dequeues(void);
147099 +
147100 +/**
147101 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
147102 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147103 + *
147104 + * Adds a set of pool channels to the portal's static dequeue command register
147105 + * (SDQCR). The requested pools are limited to those the portal has dequeue
147106 + * access to.
147107 + */
147108 +void qman_static_dequeue_add(u32 pools);
147109 +
147110 +/**
147111 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
147112 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
147113 + *
147114 + * Removes a set of pool channels from the portal's static dequeue command
147115 + * register (SDQCR). The requested pools are limited to those the portal has
147116 + * dequeue access to.
147117 + */
147118 +void qman_static_dequeue_del(u32 pools);
147119 +
147120 +/**
147121 + * qman_static_dequeue_get - return the portal's current SDQCR
147122 + *
147123 + * Returns the portal's current static dequeue command register (SDQCR). The
147124 + * entire register is returned, so if only the currently-enabled pool channels
147125 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
147126 + */
147127 +u32 qman_static_dequeue_get(void);
147128 +
147129 +/**
147130 + * qman_dca - Perform a Discrete Consumption Acknowledgement
147131 + * @dq: the DQRR entry to be consumed
147132 + * @park_request: indicates whether the held-active @fq should be parked
147133 + *
147134 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
147135 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
147136 + * does not take a 'portal' argument but implies the core affine portal from the
147137 + * cpu that is currently executing the function. For reasons of locking, this
147138 + * function must be called from the same CPU as that which processed the DQRR
147139 + * entry in the first place.
147140 + */
147141 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
147142 +
147143 +/**
147144 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
147145 + *
147146 + * For use in situations where a cpu-affine caller needs to determine when all
147147 + * enqueues for the local portal have been processed by Qman but can't use the
147148 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
147149 + * The function forces tracking of EQCR consumption (which normally doesn't
147150 + * happen until enqueue processing needs to find space to put new enqueue
147151 + * commands), and returns zero if the ring still has unprocessed entries,
147152 + * non-zero if it is empty.
147153 + */
147154 +int qman_eqcr_is_empty(void);
147155 +
147156 +/**
147157 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
147158 + * @handler: callback for processing DCP ERNs
147159 + * @affine: whether this handler is specific to the locally affine portal
147160 + *
147161 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
147162 + * DCP) is configured not to receive enqueue rejections, then any enqueues
147163 + * through that DCP that are rejected will be sent to a given software portal.
147164 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
147165 + * received on the portal affine to the current CPU. If multiple CPUs share a
147166 + * portal and they all call this function, they will be setting the handler for
147167 + * the same portal! If @affine is zero, then this handler will be global to all
147168 + * portals handled by this instance of the driver. Only those portals that do
147169 + * not have their own affine handler will use the global handler.
147170 + */
147171 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
147172 +
147173 + /* FQ management */
147174 + /* ------------- */
147175 +/**
147176 + * qman_create_fq - Allocates a FQ
147177 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
147178 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
147179 + * @fq: memory for storing the 'fq', with callbacks filled in
147180 + *
147181 + * Creates a frame queue object for the given @fqid, unless the
147182 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
147183 + * dynamically allocated (or the function fails if none are available). Once
147184 + * created, the caller should not touch the memory at 'fq' except as extended to
147185 + * adjacent memory for user-defined fields (see the definition of "struct
147186 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
147187 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
147188 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
147189 + * causes the driver to honour any contextB modifications requested in the
147190 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
147191 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
147192 + * software portals, the contextB field is controlled by the driver and can't be
147193 + * modified by the caller. If the AS_IS flag is specified, management commands
147194 + * will be used on portal @p to query state for frame queue @fqid and construct
147195 + * a frame queue object based on that, rather than assuming/requiring that it be
147196 + * Out of Service.
147197 + */
147198 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
147199 +
147200 +/**
147201 + * qman_destroy_fq - Deallocates a FQ
147202 + * @fq: the frame queue object to release
147203 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
147204 + *
147205 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
147206 + * not deallocated but the caller regains ownership, to do with as desired. The
147207 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
147208 + * is specified, in which case it may also be in the 'parked' state.
147209 + */
147210 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
147211 +
147212 +/**
147213 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
147214 + * @fq: the frame queue object to query
147215 + */
147216 +u32 qman_fq_fqid(struct qman_fq *fq);
147217 +
147218 +/**
147219 + * qman_fq_state - Queries the state of a FQ object
147220 + * @fq: the frame queue object to query
147221 + * @state: pointer to state enum to return the FQ scheduling state
147222 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
147223 + *
147224 + * Queries the state of the FQ object, without performing any h/w commands.
147225 + * This captures the state, as seen by the driver, at the time the function
147226 + * executes.
147227 + */
147228 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
147229 +
147230 +/**
147231 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
147232 + * @fq: the frame queue object to modify, must be 'parked' or new.
147233 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
147234 + * @opts: the FQ-modification settings, as defined in the low-level API
147235 + *
147236 + * The @opts parameter comes from the low-level portal API. Select
147237 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
147238 + * rather than parked. NB, @opts can be NULL.
147239 + *
147240 + * Note that some fields and options within @opts may be ignored or overwritten
147241 + * by the driver;
147242 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
147243 + * affects one frame queue: @fq).
147244 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
147245 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
147246 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
147247 + * initialised to a value used by the driver for demux.
147248 + * - if context_b is initialised for demux, so is context_a in case stashing
147249 + * is requested (see item 4).
147250 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
147251 + * objects.)
147252 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
147253 + * 'dest::channel' field will be overwritten to match the portal used to issue
147254 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
147255 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
147256 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
147257 + * isn't set, the destination channel/workqueue fields and the write-enable bit
147258 + * are left as-is.
147259 + * 4. if the driver overwrites context_a/b for demux, then if
147260 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
147261 + * context_a.address fields and will leave the stashing fields provided by the
147262 + * user alone, otherwise it will zero out the context_a.stashing fields.
147263 + */
147264 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
147265 +
147266 +/**
147267 + * qman_schedule_fq - Schedules a FQ
147268 + * @fq: the frame queue object to schedule, must be 'parked'
147269 + *
147270 + * Schedules the frame queue, which must be Parked, which takes it to
147271 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
147272 + */
147273 +int qman_schedule_fq(struct qman_fq *fq);
147274 +
147275 +/**
147276 + * qman_retire_fq - Retires a FQ
147277 + * @fq: the frame queue object to retire
147278 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
147279 + *
147280 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
147281 + * the retirement was started asynchronously, otherwise it returns negative for
147282 + * failure. When this function returns zero, @flags is set to indicate whether
147283 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
147284 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
147285 + * FQRN message shows up on the portal's message ring.
147286 + *
147287 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
147288 + * Active state), the completion will be via the message ring as a FQRN - but
147289 + * the corresponding callback may occur before this function returns!! Ie. the
147290 + * caller should be prepared to accept the callback as the function is called,
147291 + * not only once it has returned.
147292 + */
147293 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
147294 +
147295 +/**
147296 + * qman_oos_fq - Puts a FQ "out of service"
147297 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
147298 + *
147299 + * The frame queue must be retired and empty, and if any order restoration list
147300 + * was released as ERNs at the time of retirement, they must all be consumed.
147301 + */
147302 +int qman_oos_fq(struct qman_fq *fq);
147303 +
147304 +/**
147305 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
147306 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
147307 + * or 'retired' or 'parked' state
147308 + * @xon: boolean to set fq in XON or XOFF state
147309 + *
147310 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
147311 + * otherwise the IFSI interrupt will be asserted.
147312 + */
147313 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
147314 +
147315 +/**
147316 + * qman_query_fq - Queries FQD fields (via h/w query command)
147317 + * @fq: the frame queue object to be queried
147318 + * @fqd: storage for the queried FQD fields
147319 + */
147320 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
147321 +
147322 +/**
147323 + * qman_query_fq_np - Queries non-programmable FQD fields
147324 + * @fq: the frame queue object to be queried
147325 + * @np: storage for the queried FQD fields
147326 + */
147327 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
147328 +
147329 +/**
147330 + * qman_query_wq - Queries work queue lengths
147331 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
147332 + * to this software portal. Otherwise, query length of WQs in a
147333 + * channel specified in wq.
147334 + * @wq: storage for the queried WQs lengths. Also specified the channel to
147335 + * to query if query_dedicated is zero.
147336 + */
147337 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
147338 +
147339 +/**
147340 + * qman_volatile_dequeue - Issue a volatile dequeue command
147341 + * @fq: the frame queue object to dequeue from
147342 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
147343 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
147344 + *
147345 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
147346 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
147347 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
147348 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
147349 + * the VDQCR command has finished executing (ie. once the callback for the last
147350 + * DQRR entry resulting from the VDQCR command has been called). If not using
147351 + * the FINISH flag, completion can be determined either by detecting the
147352 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
147353 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
147354 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
147355 + * "flags" retrieved from qman_fq_state().
147356 + */
147357 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
147358 +
147359 +/**
147360 + * qman_enqueue - Enqueue a frame to a frame queue
147361 + * @fq: the frame queue object to enqueue to
147362 + * @fd: a descriptor of the frame to be enqueued
147363 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147364 + *
147365 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
147366 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
147367 + * field is ignored. The return value is non-zero on error, such as ring full
147368 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
147369 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
147370 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
147371 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
147372 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
147373 + * perform an implied "discrete consumption acknowledgement" on the dequeue
147374 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
147375 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
147376 + * this implicit DCA can delay the release of a "held active" frame queue
147377 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
147378 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
147379 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
147380 + * acknowledgement should "park request" the "held active" frame queue. Ie.
147381 + * when the portal eventually releases that frame queue, it will be left in the
147382 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
147383 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
147384 + * is requested, and the FQ is a member of a congestion group, then this
147385 + * function returns -EAGAIN if the congestion group is currently congested.
147386 + * Note, this does not eliminate ERNs, as the async interface means we can be
147387 + * sending enqueue commands to an un-congested FQ that becomes congested before
147388 + * the enqueue commands are processed, but it does minimise needless thrashing
147389 + * of an already busy hardware resource by throttling many of the to-be-dropped
147390 + * enqueues "at the source".
147391 + */
147392 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
147393 +
147394 +typedef int (*qman_cb_precommit) (void *arg);
147395 +/**
147396 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
147397 + * @fq: the frame queue object to enqueue to
147398 + * @fd: a descriptor of the frame to be enqueued
147399 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147400 + * @cb: user supplied callback function to invoke before writing commit verb.
147401 + * @cb_arg: callback function argument
147402 + *
147403 + * This is similar to qman_enqueue except that it will invoke a user supplied
147404 + * callback function just before writng the commit verb. This is useful
147405 + * when the user want to do something *just before* enqueuing the request and
147406 + * the enqueue can't fail.
147407 + */
147408 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
147409 + u32 flags, qman_cb_precommit cb, void *cb_arg);
147410 +
147411 +/**
147412 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
147413 + * @fq: the frame queue object to enqueue to
147414 + * @fd: a descriptor of the frame to be enqueued
147415 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
147416 + * @orp: the frame queue object used as an order restoration point.
147417 + * @orp_seqnum: the sequence number of this frame in the order restoration path
147418 + *
147419 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
147420 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
147421 + * enqueue operation to employ order restoration. Each frame queue object acts
147422 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
147423 + * with an incrementing sequence number, this value is generally ignored unless
147424 + * that sequence of dequeued frames will need order restoration later. Each
147425 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
147426 + * is a re-assembly context for re-ordering frames relative to their sequence
147427 + * numbers as they are enqueued. The ORP does not have to be within the frame
147428 + * queue that receives the enqueued frame, in fact it is usually the frame
147429 + * queue from which the frames were originally dequeued. For the purposes of
147430 + * order restoration, multiple frames (or "fragments") can be enqueued for a
147431 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
147432 + * enqueues except the final fragment of a given sequence number. Ordering
147433 + * between sequence numbers is guaranteed, even if fragments of different
147434 + * sequence numbers are interlaced with one another. Fragments of the same
147435 + * sequence number will retain the order in which they are enqueued. If no
147436 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
147437 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
147438 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
147439 + * sequence number should become the ORP's "Next Expected Sequence Number".
147440 + *
147441 + * Side note: a frame queue object can be used purely as an ORP, without
147442 + * carrying any frames at all. Care should be taken not to deallocate a frame
147443 + * queue object that is being actively used as an ORP, as a future allocation
147444 + * of the frame queue object may start using the internal ORP before the
147445 + * previous use has finished.
147446 + */
147447 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
147448 + struct qman_fq *orp, u16 orp_seqnum);
147449 +
147450 +/**
147451 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
147452 + * @result: is set by the API to the base FQID of the allocated range
147453 + * @count: the number of FQIDs required
147454 + * @align: required alignment of the allocated range
147455 + * @partial: non-zero if the API can return fewer than @count FQIDs
147456 + *
147457 + * Returns the number of frame queues allocated, or a negative error code. If
147458 + * @partial is non zero, the allocation request may return a smaller range of
147459 + * FQs than requested (though alignment will be as requested). If @partial is
147460 + * zero, the return value will either be 'count' or negative.
147461 + */
147462 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
147463 +static inline int qman_alloc_fqid(u32 *result)
147464 +{
147465 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
147466 + return (ret > 0) ? 0 : ret;
147467 +}
147468 +
147469 +/**
147470 + * qman_release_fqid_range - Release the specified range of frame queue IDs
147471 + * @fqid: the base FQID of the range to deallocate
147472 + * @count: the number of FQIDs in the range
147473 + *
147474 + * This function can also be used to seed the allocator with ranges of FQIDs
147475 + * that it can subsequently allocate from.
147476 + */
147477 +void qman_release_fqid_range(u32 fqid, unsigned int count);
147478 +static inline void qman_release_fqid(u32 fqid)
147479 +{
147480 + qman_release_fqid_range(fqid, 1);
147481 +}
147482 +
147483 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
147484 +
147485 +
147486 +int qman_shutdown_fq(u32 fqid);
147487 +
147488 +/**
147489 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
147490 + * @fqid: the base FQID of the range to deallocate
147491 + * @count: the number of FQIDs in the range
147492 + */
147493 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
147494 +static inline int qman_reserve_fqid(u32 fqid)
147495 +{
147496 + return qman_reserve_fqid_range(fqid, 1);
147497 +}
147498 +
147499 + /* Pool-channel management */
147500 + /* ----------------------- */
147501 +/**
147502 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
147503 + * @result: is set by the API to the base pool-channel ID of the allocated range
147504 + * @count: the number of pool-channel IDs required
147505 + * @align: required alignment of the allocated range
147506 + * @partial: non-zero if the API can return fewer than @count
147507 + *
147508 + * Returns the number of pool-channel IDs allocated, or a negative error code.
147509 + * If @partial is non zero, the allocation request may return a smaller range of
147510 + * than requested (though alignment will be as requested). If @partial is zero,
147511 + * the return value will either be 'count' or negative.
147512 + */
147513 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
147514 +static inline int qman_alloc_pool(u32 *result)
147515 +{
147516 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
147517 + return (ret > 0) ? 0 : ret;
147518 +}
147519 +
147520 +/**
147521 + * qman_release_pool_range - Release the specified range of pool-channel IDs
147522 + * @id: the base pool-channel ID of the range to deallocate
147523 + * @count: the number of pool-channel IDs in the range
147524 + */
147525 +void qman_release_pool_range(u32 id, unsigned int count);
147526 +static inline void qman_release_pool(u32 id)
147527 +{
147528 + qman_release_pool_range(id, 1);
147529 +}
147530 +
147531 +/**
147532 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
147533 + * @id: the base pool-channel ID of the range to reserve
147534 + * @count: the number of pool-channel IDs in the range
147535 + */
147536 +int qman_reserve_pool_range(u32 id, unsigned int count);
147537 +static inline int qman_reserve_pool(u32 id)
147538 +{
147539 + return qman_reserve_pool_range(id, 1);
147540 +}
147541 +
147542 +void qman_seed_pool_range(u32 id, unsigned int count);
147543 +
147544 + /* CGR management */
147545 + /* -------------- */
147546 +/**
147547 + * qman_create_cgr - Register a congestion group object
147548 + * @cgr: the 'cgr' object, with fields filled in
147549 + * @flags: QMAN_CGR_FLAG_* values
147550 + * @opts: optional state of CGR settings
147551 + *
147552 + * Registers this object to receiving congestion entry/exit callbacks on the
147553 + * portal affine to the cpu portal on which this API is executed. If opts is
147554 + * NULL then only the callback (cgr->cb) function is registered. If @flags
147555 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
147556 + * any unspecified parameters) will be used rather than a modify hw hardware
147557 + * (which only modifies the specified parameters).
147558 + */
147559 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
147560 + struct qm_mcc_initcgr *opts);
147561 +
147562 +/**
147563 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
147564 + * @cgr: the 'cgr' object, with fields filled in
147565 + * @flags: QMAN_CGR_FLAG_* values
147566 + * @dcp_portal: the DCP portal to which the cgr object is registered.
147567 + * @opts: optional state of CGR settings
147568 + *
147569 + */
147570 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
147571 + struct qm_mcc_initcgr *opts);
147572 +
147573 +/**
147574 + * qman_delete_cgr - Deregisters a congestion group object
147575 + * @cgr: the 'cgr' object to deregister
147576 + *
147577 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
147578 + * is executed. This must be excuted on the same affine portal on which it was
147579 + * created.
147580 + */
147581 +int qman_delete_cgr(struct qman_cgr *cgr);
147582 +
147583 +/**
147584 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
147585 + * @cgr: the 'cgr' object to deregister
147586 + *
147587 + * This will select the proper CPU and run there qman_delete_cgr().
147588 + */
147589 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
147590 +
147591 +/**
147592 + * qman_modify_cgr - Modify CGR fields
147593 + * @cgr: the 'cgr' object to modify
147594 + * @flags: QMAN_CGR_FLAG_* values
147595 + * @opts: the CGR-modification settings
147596 + *
147597 + * The @opts parameter comes from the low-level portal API, and can be NULL.
147598 + * Note that some fields and options within @opts may be ignored or overwritten
147599 + * by the driver, in particular the 'cgrid' field is ignored (this operation
147600 + * only affects the given CGR object). If @flags contains
147601 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
147602 + * unspecified parameters) will be used rather than a modify hw hardware (which
147603 + * only modifies the specified parameters).
147604 + */
147605 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
147606 + struct qm_mcc_initcgr *opts);
147607 +
147608 +/**
147609 +* qman_query_cgr - Queries CGR fields
147610 +* @cgr: the 'cgr' object to query
147611 +* @result: storage for the queried congestion group record
147612 +*/
147613 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
147614 +
147615 +/**
147616 + * qman_query_congestion - Queries the state of all congestion groups
147617 + * @congestion: storage for the queried state of all congestion groups
147618 + */
147619 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
147620 +
147621 +/**
147622 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
147623 + * @result: is set by the API to the base CGR ID of the allocated range
147624 + * @count: the number of CGR IDs required
147625 + * @align: required alignment of the allocated range
147626 + * @partial: non-zero if the API can return fewer than @count
147627 + *
147628 + * Returns the number of CGR IDs allocated, or a negative error code.
147629 + * If @partial is non zero, the allocation request may return a smaller range of
147630 + * than requested (though alignment will be as requested). If @partial is zero,
147631 + * the return value will either be 'count' or negative.
147632 + */
147633 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
147634 +static inline int qman_alloc_cgrid(u32 *result)
147635 +{
147636 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
147637 + return (ret > 0) ? 0 : ret;
147638 +}
147639 +
147640 +/**
147641 + * qman_release_cgrid_range - Release the specified range of CGR IDs
147642 + * @id: the base CGR ID of the range to deallocate
147643 + * @count: the number of CGR IDs in the range
147644 + */
147645 +void qman_release_cgrid_range(u32 id, unsigned int count);
147646 +static inline void qman_release_cgrid(u32 id)
147647 +{
147648 + qman_release_cgrid_range(id, 1);
147649 +}
147650 +
147651 +/**
147652 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
147653 + * @id: the base CGR ID of the range to reserve
147654 + * @count: the number of CGR IDs in the range
147655 + */
147656 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
147657 +static inline int qman_reserve_cgrid(u32 id)
147658 +{
147659 + return qman_reserve_cgrid_range(id, 1);
147660 +}
147661 +
147662 +void qman_seed_cgrid_range(u32 id, unsigned int count);
147663 +
147664 +
147665 + /* Helpers */
147666 + /* ------- */
147667 +/**
147668 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
147669 + * @fqid: the FQID that will be initialised by other s/w
147670 + *
147671 + * In many situations, a FQID is provided for communication between s/w
147672 + * entities, and whilst the consumer is responsible for initialising and
147673 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
147674 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
147675 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
147676 + * However, data can not be enqueued to the FQ until it is initialised out of
147677 + * the OOS state - this function polls for that condition. It is particularly
147678 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
147679 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
147680 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
147681 + * synchronise. The function returns zero for success, +1 if the FQ is still in
147682 + * the OOS state, or negative if there was an error.
147683 + */
147684 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
147685 +{
147686 + struct qm_mcr_queryfq_np np;
147687 + int err;
147688 + err = qman_query_fq_np(fq, &np);
147689 + if (err)
147690 + return err;
147691 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
147692 + return 1;
147693 + return 0;
147694 +}
147695 +
147696 + /* -------------- */
147697 + /* CEETM :: types */
147698 + /* -------------- */
147699 +/**
147700 + * Token Rate Structure
147701 + * Shaping rates are based on a "credit" system and a pre-configured h/w
147702 + * internal timer. The following type represents a shaper "rate" parameter as a
147703 + * fractional number of "tokens". Here's how it works. This (fractional) number
147704 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
147705 + * (up to a limit which is set by another shaper parameter). Every time a frame
147706 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
147707 + * bytes of data in the enqueued frame. A shaper will not allow itself to
147708 + * enqueue any frames if its token count is negative. As such;
147709 + *
147710 + * The rate at which data is enqueued is limited by the
147711 + * rate at which tokens are added.
147712 + *
147713 + * Therefore if the user knows the period between these h/w timer updates in
147714 + * seconds, they can calculate the maximum traffic rate of the shaper (in
147715 + * bytes-per-second) from the token rate. And vice versa, they can calculate
147716 + * the token rate to use in order to achieve a given traffic rate.
147717 + */
147718 +struct qm_ceetm_rate {
147719 + /* The token rate is; whole + (fraction/8192) */
147720 + u32 whole:11; /* 0..2047 */
147721 + u32 fraction:13; /* 0..8191 */
147722 +};
147723 +
147724 +struct qm_ceetm_weight_code {
147725 + /* The weight code is; 5 msbits + 3 lsbits */
147726 + u8 y:5;
147727 + u8 x:3;
147728 +};
147729 +
147730 +struct qm_ceetm {
147731 + unsigned int idx;
147732 + struct list_head sub_portals;
147733 + struct list_head lnis;
147734 + unsigned int sp_range[2];
147735 + unsigned int lni_range[2];
147736 +};
147737 +
147738 +struct qm_ceetm_sp {
147739 + struct list_head node;
147740 + unsigned int idx;
147741 + unsigned int dcp_idx;
147742 + int is_claimed;
147743 + struct qm_ceetm_lni *lni;
147744 +};
147745 +
147746 +/* Logical Network Interface */
147747 +struct qm_ceetm_lni {
147748 + struct list_head node;
147749 + unsigned int idx;
147750 + unsigned int dcp_idx;
147751 + int is_claimed;
147752 + struct qm_ceetm_sp *sp;
147753 + struct list_head channels;
147754 + int shaper_enable;
147755 + int shaper_couple;
147756 + int oal;
147757 + struct qm_ceetm_rate cr_token_rate;
147758 + struct qm_ceetm_rate er_token_rate;
147759 + u16 cr_token_bucket_limit;
147760 + u16 er_token_bucket_limit;
147761 +};
147762 +
147763 +/* Class Queue Channel */
147764 +struct qm_ceetm_channel {
147765 + struct list_head node;
147766 + unsigned int idx;
147767 + unsigned int lni_idx;
147768 + unsigned int dcp_idx;
147769 + struct list_head class_queues;
147770 + struct list_head ccgs;
147771 + u8 shaper_enable;
147772 + u8 shaper_couple;
147773 + struct qm_ceetm_rate cr_token_rate;
147774 + struct qm_ceetm_rate er_token_rate;
147775 + u16 cr_token_bucket_limit;
147776 + u16 er_token_bucket_limit;
147777 +};
147778 +
147779 +struct qm_ceetm_ccg;
147780 +
147781 +/* This callback type is used when handling congestion entry/exit. The
147782 + * 'cb_ctx' value is the opaque value associated with ccg object.
147783 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
147784 + */
147785 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
147786 + int congested);
147787 +
147788 +/* Class Congestion Group */
147789 +struct qm_ceetm_ccg {
147790 + struct qm_ceetm_channel *parent;
147791 + struct list_head node;
147792 + struct list_head cb_node;
147793 + qman_cb_ccgr cb;
147794 + void *cb_ctx;
147795 + unsigned int idx;
147796 +};
147797 +
147798 +/* Class Queue */
147799 +struct qm_ceetm_cq {
147800 + struct qm_ceetm_channel *parent;
147801 + struct qm_ceetm_ccg *ccg;
147802 + struct list_head node;
147803 + unsigned int idx;
147804 + int is_claimed;
147805 + struct list_head bound_lfqids;
147806 + struct list_head binding_node;
147807 +};
147808 +
147809 +/* Logical Frame Queue */
147810 +struct qm_ceetm_lfq {
147811 + struct qm_ceetm_channel *parent;
147812 + struct list_head node;
147813 + unsigned int idx;
147814 + unsigned int dctidx;
147815 + u64 context_a;
147816 + u32 context_b;
147817 + qman_cb_mr ern;
147818 +};
147819 +
147820 +/**
147821 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
147822 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
147823 + * approximates that rate.
147824 + * @bps: the desired shaper rate in bps.
147825 + * @token_rate: the output token rate computed with the given kbps.
147826 + * @rounding: dictates how to round if an exact conversion is not possible; if
147827 + * it is negative then 'token_rate' will round down to the highest value that
147828 + * does not exceed the desired rate, if it is positive then 'token_rate' will
147829 + * round up to the lowest value that is greater than or equal to the desired
147830 + * rate, and if it is zero then it will round to the nearest approximation,
147831 + * whether that be up or down.
147832 + *
147833 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147834 + */
147835 +int qman_ceetm_bps2tokenrate(u64 bps,
147836 + struct qm_ceetm_rate *token_rate,
147837 + int rounding);
147838 +
147839 +/**
147840 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
147841 + * corresponding number of 'bps'.
147842 + * @token_rate: the input desired token_rate fraction.
147843 + * @bps: the output shaper rate in bps computed with the give token rate.
147844 + * @rounding: has the same semantics as the previous function.
147845 + *
147846 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
147847 + */
147848 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
147849 + u64 *bps,
147850 + int rounding);
147851 +
147852 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
147853 + int partial);
147854 +static inline int qman_alloc_ceetm0_channel(u32 *result)
147855 +{
147856 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
147857 + return (ret > 0) ? 0 : ret;
147858 +}
147859 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
147860 +static inline void qman_release_ceetm0_channelid(u32 channelid)
147861 +{
147862 + qman_release_ceetm0_channel_range(channelid, 1);
147863 +}
147864 +
147865 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
147866 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
147867 +{
147868 + return qman_reserve_ceetm0_channel_range(channelid, 1);
147869 +}
147870 +
147871 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
147872 +
147873 +
147874 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
147875 + int partial);
147876 +static inline int qman_alloc_ceetm1_channel(u32 *result)
147877 +{
147878 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
147879 + return (ret > 0) ? 0 : ret;
147880 +}
147881 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
147882 +static inline void qman_release_ceetm1_channelid(u32 channelid)
147883 +{
147884 + qman_release_ceetm1_channel_range(channelid, 1);
147885 +}
147886 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
147887 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
147888 +{
147889 + return qman_reserve_ceetm1_channel_range(channelid, 1);
147890 +}
147891 +
147892 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
147893 +
147894 +
147895 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
147896 + int partial);
147897 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
147898 +{
147899 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
147900 + return (ret > 0) ? 0 : ret;
147901 +}
147902 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
147903 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
147904 +{
147905 + qman_release_ceetm0_lfqid_range(lfqid, 1);
147906 +}
147907 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
147908 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
147909 +{
147910 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
147911 +}
147912 +
147913 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
147914 +
147915 +
147916 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
147917 + int partial);
147918 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
147919 +{
147920 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
147921 + return (ret > 0) ? 0 : ret;
147922 +}
147923 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
147924 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
147925 +{
147926 + qman_release_ceetm1_lfqid_range(lfqid, 1);
147927 +}
147928 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
147929 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
147930 +{
147931 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
147932 +}
147933 +
147934 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
147935 +
147936 +
147937 + /* ----------------------------- */
147938 + /* CEETM :: sub-portals */
147939 + /* ----------------------------- */
147940 +
147941 +/**
147942 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
147943 + * to us and configured for traffic-management.
147944 + * @sp: the returned sub-portal object, if successful.
147945 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147946 + * instance),
147947 + * @sp_idx" is the desired sub-portal index from 0 to 15.
147948 + *
147949 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
147950 + * if the sp_idx is out of range.
147951 + *
147952 + * Note that if there are multiple driver domains (eg. a linux kernel versus
147953 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
147954 + * then a sub-portal may be accessible by more than one instance of a qman
147955 + * driver and so it may be claimed multiple times. If this is the case, it is
147956 + * up to the system architect to prevent conflicting configuration actions
147957 + * coming from the different driver domains. The qman drivers do not have any
147958 + * behind-the-scenes coordination to prevent this from happening.
147959 + */
147960 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
147961 + enum qm_dc_portal dcp_idx,
147962 + unsigned int sp_idx);
147963 +
147964 +/**
147965 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
147966 + * @sp: the sub-portal to be released.
147967 + *
147968 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
147969 + * released.
147970 + */
147971 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
147972 +
147973 + /* ----------------------------------- */
147974 + /* CEETM :: logical network interfaces */
147975 + /* ----------------------------------- */
147976 +
147977 +/**
147978 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
147979 + * @lni: the returned LNI object, if successful.
147980 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
147981 + * instance)
147982 + * @lni_idx: is the desired LNI index.
147983 + *
147984 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
147985 + * is not available or has already been claimed (and not yet successfully
147986 + * released), or lni_dix is out of range.
147987 + *
147988 + * Note that there may be multiple driver domains (or instances) that need to
147989 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
147990 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
147991 + * qman_ceetm_sp_get_lni() for more information.
147992 + */
147993 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
147994 + enum qm_dc_portal dcp_id,
147995 + unsigned int lni_idx);
147996 +
147997 +/**
147998 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
147999 + * @lni: the lni needs to be released.
148000 + *
148001 + * This will only succeed if all dependent objects have been released.
148002 + * Returns zero for success, or -EBUSY if the dependencies are not released.
148003 + */
148004 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
148005 +
148006 +/**
148007 + * qman_ceetm_sp_set_lni
148008 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
148009 + * mapped to.
148010 + * @sp: the given sub-portal.
148011 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
148012 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
148013 + *
148014 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
148015 + * mapping has been set, or configure mapping command returns error, and
148016 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
148017 + * mapping command returns error.
148018 + *
148019 + * This may be useful in situations where multiple driver domains have access
148020 + * to the same sub-portals in order to all be able to transmit out the same
148021 + * physical interface (perhaps they're on different IP addresses or VPNs, so
148022 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
148023 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
148024 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
148025 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
148026 + * in order to determine the LNI that the control-plane had assigned. This is
148027 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
148028 + * LNI object.
148029 + */
148030 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
148031 + struct qm_ceetm_lni *lni);
148032 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
148033 + unsigned int *lni_idx);
148034 +
148035 +/**
148036 + * qman_ceetm_lni_enable_shaper
148037 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
148038 + * @lni: the given LNI.
148039 + * @coupled: indicates whether CR and ER are coupled.
148040 + * @oal: the overhead accounting length which is added to the actual length of
148041 + * each frame when performing shaper calculations.
148042 + *
148043 + * When the number of (unused) committed-rate tokens reach the committed-rate
148044 + * token limit, 'coupled' indicates whether surplus tokens should be added to
148045 + * the excess-rate token count (up to the excess-rate token limit).
148046 + * When LNI is claimed, the shaper is disabled by default. The enable function
148047 + * will turn on this shaper for this lni.
148048 + * Whenever a claimed LNI is first enabled for shaping, its committed and
148049 + * excess token rates and limits are zero, so will need to be changed to do
148050 + * anything useful. The shaper can subsequently be enabled/disabled without
148051 + * resetting the shaping parameters, but the shaping parameters will be reset
148052 + * when the LNI is released.
148053 + *
148054 + * Returns zero for success, or errno for "enable" function in the cases as:
148055 + * a) -EINVAL if the shaper is already enabled,
148056 + * b) -EIO if the configure shaper command returns error.
148057 + * For "disable" function, returns:
148058 + * a) -EINVAL if the shaper is has already disabled.
148059 + * b) -EIO if calling configure shaper command returns error.
148060 + */
148061 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
148062 + int oal);
148063 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
148064 +
148065 +/**
148066 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
148067 + * @lni: the give LNI
148068 + */
148069 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
148070 +
148071 +/**
148072 + * qman_ceetm_lni_set_commit_rate
148073 + * qman_ceetm_lni_get_commit_rate
148074 + * qman_ceetm_lni_set_excess_rate
148075 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
148076 + * token limit for the given LNI.
148077 + * @lni: the given LNI.
148078 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
148079 + * the LNI queried by "get" function.
148080 + * @token_limit: the desired token bucket limit for "set" function, or the token
148081 + * limit of the given LNI queried by "get" function.
148082 + *
148083 + * Returns zero for success. The "set" function returns -EINVAL if the given
148084 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148085 + * The "get" function returns -EINVAL if the token rate or the token limit is
148086 + * not set or the query command returns error.
148087 + */
148088 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
148089 + const struct qm_ceetm_rate *token_rate,
148090 + u16 token_limit);
148091 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
148092 + struct qm_ceetm_rate *token_rate,
148093 + u16 *token_limit);
148094 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
148095 + const struct qm_ceetm_rate *token_rate,
148096 + u16 token_limit);
148097 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
148098 + struct qm_ceetm_rate *token_rate,
148099 + u16 *token_limit);
148100 +/**
148101 + * qman_ceetm_lni_set_commit_rate_bps
148102 + * qman_ceetm_lni_get_commit_rate_bps
148103 + * qman_ceetm_lni_set_excess_rate_bps
148104 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
148105 + * and token limit for the given LNI.
148106 + * @lni: the given LNI.
148107 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
148108 + * of the LNI queried by "get" function.
148109 + * @token_limit: the desired token bucket limit for "set" function, or the token
148110 + * limit of the given LNI queried by "get" function.
148111 + *
148112 + * Returns zero for success. The "set" function returns -EINVAL if the given
148113 + * LNI is unshapped or -EIO if the configure shaper command returns error.
148114 + * The "get" function returns -EINVAL if the token rate or the token limit is
148115 + * not set or the query command returns error.
148116 + */
148117 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
148118 + u64 bps,
148119 + u16 token_limit);
148120 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
148121 + u64 *bps, u16 *token_limit);
148122 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
148123 + u64 bps,
148124 + u16 token_limit);
148125 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
148126 + u64 *bps, u16 *token_limit);
148127 +
148128 +/**
148129 + * qman_ceetm_lni_set_tcfcc
148130 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
148131 + * @lni: the given LNI.
148132 + * @cq_level: is between 0 and 15, representing individual class queue levels
148133 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
148134 + * for every channel).
148135 + * @traffic_class: is between 0 and 7 when associating a given class queue level
148136 + * to a traffic class, or -1 when disabling traffic class flow control for this
148137 + * class queue level.
148138 + *
148139 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
148140 + * of range as indicated above, or -EIO if the configure/query tcfcc command
148141 + * returns error.
148142 + *
148143 + * Refer to the section of QMan CEETM traffic class flow control in the
148144 + * Reference Manual.
148145 + */
148146 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
148147 + unsigned int cq_level,
148148 + int traffic_class);
148149 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
148150 + unsigned int cq_level,
148151 + int *traffic_class);
148152 +
148153 + /* ----------------------------- */
148154 + /* CEETM :: class queue channels */
148155 + /* ----------------------------- */
148156 +
148157 +/**
148158 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
148159 + * the given LNI.
148160 + * @channel: the returned class queue channel object, if successful.
148161 + * @lni: the LNI that the channel belongs to.
148162 + *
148163 + * Channels are always initially "unshaped".
148164 + *
148165 + * Return zero for success, or -ENODEV if there is no channel available(all 32
148166 + * channels are claimed) or -EINVAL if the channel mapping command returns
148167 + * error.
148168 + */
148169 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
148170 + struct qm_ceetm_lni *lni);
148171 +
148172 +/**
148173 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
148174 + * @channel: the channel needs to be released.
148175 + *
148176 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
148177 + *
148178 + * Note any shaping of the channel will be cleared to leave it in an unshaped
148179 + * state.
148180 + */
148181 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
148182 +
148183 +/**
148184 + * qman_ceetm_channel_enable_shaper
148185 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
148186 + * @channel: the given channel.
148187 + * @coupled: indicates whether surplus CR tokens should be added to the
148188 + * excess-rate token count (up to the excess-rate token limit) when the number
148189 + * of (unused) committed-rate tokens reach the committed_rate token limit.
148190 + *
148191 + * Whenever a claimed channel is first enabled for shaping, its committed and
148192 + * excess token rates and limits are zero, so will need to be changed to do
148193 + * anything useful. The shaper can subsequently be enabled/disabled without
148194 + * resetting the shaping parameters, but the shaping parameters will be reset
148195 + * when the channel is released.
148196 + *
148197 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
148198 + * shaper has been enabled/disabled or the management command returns error.
148199 + */
148200 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
148201 + int coupled);
148202 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
148203 +
148204 +/**
148205 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
148206 + * @channel: the give channel.
148207 + */
148208 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
148209 +
148210 +/**
148211 + * qman_ceetm_channel_set_commit_rate
148212 + * qman_ceetm_channel_get_commit_rate
148213 + * qman_ceetm_channel_set_excess_rate
148214 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
148215 + * @channel: the given channel.
148216 + * @token_rate: the desired token rate for "set" function, or the queried token
148217 + * rate for "get" function.
148218 + * @token_limit: the desired token limit for "set" function, or the queried
148219 + * token limit for "get" function.
148220 + *
148221 + * Return zero for success. The "set" function returns -EINVAL if the channel
148222 + * is unshaped, or -EIO if the configure shapper command returns error. The
148223 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148224 + * the query shaper command returns error.
148225 + */
148226 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
148227 + const struct qm_ceetm_rate *token_rate,
148228 + u16 token_limit);
148229 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
148230 + struct qm_ceetm_rate *token_rate,
148231 + u16 *token_limit);
148232 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
148233 + const struct qm_ceetm_rate *token_rate,
148234 + u16 token_limit);
148235 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
148236 + struct qm_ceetm_rate *token_rate,
148237 + u16 *token_limit);
148238 +/**
148239 + * qman_ceetm_channel_set_commit_rate_bps
148240 + * qman_ceetm_channel_get_commit_rate_bps
148241 + * qman_ceetm_channel_set_excess_rate_bps
148242 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
148243 + * parameters.
148244 + * @channel: the given channel.
148245 + * @token_rate: the desired shaper rate in bps for "set" function, or the
148246 + * shaper rate in bps for "get" function.
148247 + * @token_limit: the desired token limit for "set" function, or the queried
148248 + * token limit for "get" function.
148249 + *
148250 + * Return zero for success. The "set" function returns -EINVAL if the channel
148251 + * is unshaped, or -EIO if the configure shapper command returns error. The
148252 + * "get" function returns -EINVAL if token rate of token limit is not set, or
148253 + * the query shaper command returns error.
148254 + */
148255 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
148256 + u64 bps, u16 token_limit);
148257 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
148258 + u64 *bps, u16 *token_limit);
148259 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
148260 + u64 bps, u16 token_limit);
148261 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
148262 + u64 *bps, u16 *token_limit);
148263 +
148264 +/**
148265 + * qman_ceetm_channel_set_weight
148266 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
148267 + * @channel: the given channel.
148268 + * @token_limit: the desired token limit as the weight of the unshaped channel
148269 + * for "set" function, or the queried token limit for "get" function.
148270 + *
148271 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
148272 + * It allows the unshaped channels to be included in the CR time eligible list,
148273 + * and thus use the configured CR token limit value as their fair queuing
148274 + * weight.
148275 + *
148276 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
148277 + * the management command returns error.
148278 + */
148279 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
148280 + u16 token_limit);
148281 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
148282 + u16 *token_limit);
148283 +
148284 +/**
148285 + * qman_ceetm_channel_set_group
148286 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
148287 + * @channel: the given channel.
148288 + * @group_b: indicates whether there is group B in this channel.
148289 + * @prio_a: the priority of group A.
148290 + * @prio_b: the priority of group B.
148291 + *
148292 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
148293 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
148294 + * group A, otherwise they are split into group A (CQ8-11) and group B
148295 + * (CQ12-C15). The individual class queues and the group(s) are in strict
148296 + * priority order relative to each other. Within the group(s), the scheduling
148297 + * is not strict priority order, but the result of scheduling within a group
148298 + * is in strict priority order relative to the other class queues in the
148299 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
148300 + * relative to the individual class queues, and take values from 0-7. Eg. if
148301 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
148302 + * priority order would be;
148303 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
148304 + *
148305 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
148306 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
148307 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
148308 + * the configure scheduler command returns error. For "get" function, return
148309 + * -EINVAL if the query scheduler command returns error.
148310 + */
148311 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
148312 + int group_b,
148313 + unsigned int prio_a,
148314 + unsigned int prio_b);
148315 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
148316 + int *group_b,
148317 + unsigned int *prio_a,
148318 + unsigned int *prio_b);
148319 +
148320 +/**
148321 + * qman_ceetm_channel_set_group_cr_eligibility
148322 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
148323 + * @channel: the given channel object
148324 + * @group_b: indicates whether there is group B in this channel.
148325 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148326 + *
148327 + * Return zero for success, or -EINVAL if eligibility setting fails.
148328 +*/
148329 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
148330 + *channel, int group_b, int cre);
148331 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
148332 + *channel, int group_b, int ere);
148333 +
148334 +/**
148335 + * qman_ceetm_channel_set_cq_cr_eligibility
148336 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
148337 + * @channel: the given channel object
148338 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148339 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
148340 + *
148341 + * Return zero for success, or -EINVAL if eligibility setting fails.
148342 +*/
148343 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
148344 + unsigned int idx, int cre);
148345 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
148346 + unsigned int idx, int ere);
148347 +
148348 + /* --------------------- */
148349 + /* CEETM :: class queues */
148350 + /* --------------------- */
148351 +
148352 +/**
148353 + * qman_ceetm_cq_claim - Claims an individual class queue.
148354 + * @cq: the returned class queue object, if successful.
148355 + * @channel: the class queue channel.
148356 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
148357 + * @ccg: represents the class congestion group that this class queue should be
148358 + * subscribed to, or NULL if no congestion group membership is desired.
148359 + *
148360 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
148361 + * if this class queue has been claimed, or configure class queue command
148362 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
148363 + */
148364 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
148365 + struct qm_ceetm_channel *channel,
148366 + unsigned int idx,
148367 + struct qm_ceetm_ccg *ccg);
148368 +
148369 +/**
148370 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
148371 + * @cq: the returned class queue object, if successful.
148372 + * @channel: the class queue channel.
148373 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
148374 + * @ccg: represents the class congestion group that this class queue should be
148375 + * subscribed to, or NULL if no congestion group membership is desired.
148376 + *
148377 + * Return zero for success, or -EINVAL if @idx is out the range or if
148378 + * this class queue has been claimed or configure class queue command returns
148379 + * error, or returns -ENOMEM if allocating CQ memory fails.
148380 + */
148381 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
148382 + struct qm_ceetm_channel *channel,
148383 + unsigned int idx,
148384 + struct qm_ceetm_ccg *ccg);
148385 +
148386 +/**
148387 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
148388 + * @cq: the returned class queue object, if successful.
148389 + * @channel: the class queue channel.
148390 + * @idx: is from 0 to 3 (CQ12 to CQ15).
148391 + * @ccg: represents the class congestion group that this class queue should be
148392 + * subscribed to, or NULL if no congestion group membership is desired.
148393 + *
148394 + * Return zero for success, or -EINVAL if @idx is out the range or if
148395 + * this class queue has been claimed or configure class queue command returns
148396 + * error, or returns -ENOMEM if allocating CQ memory fails.
148397 + */
148398 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
148399 + struct qm_ceetm_channel *channel,
148400 + unsigned int idx,
148401 + struct qm_ceetm_ccg *ccg);
148402 +
148403 +/**
148404 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
148405 + * @cq: The class queue to be released.
148406 + *
148407 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
148408 + * FQIDs) have not been released.
148409 + */
148410 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
148411 +
148412 +/**
148413 + * qman_ceetm_set_queue_weight
148414 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
148415 + * queue.
148416 + * @cq: the given class queue.
148417 + * @weight_code: the desired weight code to set for the given class queue for
148418 + * "set" function or the queired weight code for "get" function.
148419 + *
148420 + * Grouped class queues have a default weight code of zero, which corresponds to
148421 + * a scheduler weighting of 1. This function can be used to modify a grouped
148422 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
148423 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
148424 + * and the corresponding sharing weight.)
148425 + *
148426 + * Returns zero for success, or -EIO if the configure weight command returns
148427 + * error for "set" function, or -EINVAL if the query command returns
148428 + * error for "get" function.
148429 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
148430 + * Manual for weight and weight code.
148431 + */
148432 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
148433 + struct qm_ceetm_weight_code *weight_code);
148434 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
148435 + struct qm_ceetm_weight_code *weight_code);
148436 +
148437 +/**
148438 + * qman_ceetm_set_queue_weight_in_ratio
148439 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
148440 + * grouped class queue.
148441 + * @cq: the given class queue.
148442 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
148443 + * by 100 to get rid of fraction.
148444 + *
148445 + * Returns zero for success, or -EIO if the configure weight command returns
148446 + * error for "set" function, or -EINVAL if the query command returns
148447 + * error for "get" function.
148448 + */
148449 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
148450 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
148451 +
148452 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
148453 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
148454 + * corresponding to intermediate weight codes are calculated using linear
148455 + * interpolation on the inverted values. Or put another way, the inverse weights
148456 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
148457 + * between these are divided linearly into 32 intermediate values, the inverses
148458 + * of which form the remaining weight codes.
148459 + *
148460 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
148461 + * scheduling within a group of class queues (group A or B). Weights are used to
148462 + * normalise the class queues to an underlying BFS algorithm where all class
148463 + * queues are assumed to require "equal bandwidth". So the weights referred to
148464 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
148465 + * one class queue in a group is assigned a weight of 2 whilst the other class
148466 + * queues in the group keep the default weight of 1, then the WBFS scheduler
148467 + * will effectively treat all frames enqueued on the weight-2 class queue as
148468 + * having half the number of bytes they really have. Ie. if all other things are
148469 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
148470 + * the others. So weights should be chosen to provide bandwidth ratios between
148471 + * members of the same class queue group. These weights have no bearing on
148472 + * behaviour outside that group's WBFS mechanism though.
148473 + */
148474 +
148475 +/**
148476 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
148477 + * representation of the corresponding weight is given (in order to not lose
148478 + * any precision).
148479 + * @weight_code: The given weight code in WBFS.
148480 + * @numerator: the numerator part of the weight computed by the weight code.
148481 + * @denominator: the denominator part of the weight computed by the weight code
148482 + *
148483 + * Returns zero for success or -EINVAL if the given weight code is illegal.
148484 + */
148485 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
148486 + u32 *numerator,
148487 + u32 *denominator);
148488 +/**
148489 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
148490 + * If the user needs to know how close this is, convert the resulting weight
148491 + * code back to a weight and compare.
148492 + * @numerator: numerator part of the given weight.
148493 + * @denominator: denominator part of the given weight.
148494 + * @weight_code: the weight code computed from the given weight.
148495 + *
148496 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
148497 + * the range of weights.
148498 + */
148499 +int qman_ceetm_ratio2wbfs(u32 numerator,
148500 + u32 denominator,
148501 + struct qm_ceetm_weight_code *weight_code,
148502 + int rounding);
148503 +
148504 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
148505 +/**
148506 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
148507 + * CQ counters.
148508 + * @cq: the given CQ object.
148509 + * @flags: indicates whether the statistics counter will be cleared after query.
148510 + * @frame_count: The number of the frames that have been counted since the
148511 + * counter was cleared last time.
148512 + * @byte_count: the number of bytes in all frames that have been counted.
148513 + *
148514 + * Return zero for success or -EINVAL if query statistics command returns error.
148515 + *
148516 + */
148517 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
148518 + u64 *frame_count, u64 *byte_count);
148519 +
148520 +/**
148521 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
148522 + * @cq: the give CQ object.
148523 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
148524 + */
148525 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
148526 +
148527 + /* ---------------------- */
148528 + /* CEETM :: logical FQIDs */
148529 + /* ---------------------- */
148530 +/**
148531 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
148532 + * the given class queue.
148533 + * @lfq: the returned lfq object, if successful.
148534 + * @cq: the class queue which needs to claim a LFQID.
148535 + *
148536 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
148537 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
148538 + */
148539 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
148540 + struct qm_ceetm_cq *cq);
148541 +
148542 +/**
148543 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
148544 + * @lfq: the lfq to be released.
148545 + *
148546 + * Return zero for success.
148547 + */
148548 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
148549 +
148550 +/**
148551 + * qman_ceetm_lfq_set_context
148552 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
148553 + * "dequeue context table" associated with the logical FQID.
148554 + * @lfq: the given logical FQ object.
148555 + * @context_a: contextA of the dequeue context.
148556 + * @context_b: contextB of the dequeue context.
148557 + *
148558 + * Returns zero for success, or -EINVAL if there is error to set/get the
148559 + * context pair.
148560 + */
148561 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
148562 + u64 context_a,
148563 + u32 context_b);
148564 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
148565 + u64 *context_a,
148566 + u32 *context_b);
148567 +
148568 +/**
148569 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
148570 + * @lfq: the given logic fq.
148571 + * @fq: the fq object created for the given logic fq.
148572 + *
148573 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
148574 + * target a logical FQID (and the class queue it is associated with).
148575 + * Note that this FQ object can only be used for enqueues, and
148576 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
148577 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
148578 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
148579 + * responsibility to ensure that the underlying 'lfq' is not released until any
148580 + * enqueues to this FQ object have completed. The only field the user needs to
148581 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
148582 + * could conceivably be called on this FQ object. This API can be called
148583 + * multiple times to create multiple FQ objects referring to the same logical
148584 + * FQID, and any enqueue rejections will respect the callback of the object that
148585 + * issued the enqueue (and will identify the object via the parameter passed to
148586 + * the callback too). There is no 'flags' parameter to this API as there is for
148587 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
148588 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
148589 + *
148590 + * Returns 0 for success.
148591 + */
148592 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
148593 +
148594 + /* -------------------------------- */
148595 + /* CEETM :: class congestion groups */
148596 + /* -------------------------------- */
148597 +
148598 +/**
148599 + * qman_ceetm_ccg_claim - Claims an unused CCG.
148600 + * @ccg: the returned CCG object, if successful.
148601 + * @channel: the given class queue channel
148602 + * @cscn: the callback function of this CCG.
148603 + * @cb_ctx: the corresponding context to be used used if state change
148604 + * notifications are later enabled for this CCG.
148605 + *
148606 + * The congestion group is local to the given class queue channel, so only
148607 + * class queues within the channel can be associated with that congestion group.
148608 + * The association of class queues to congestion groups occurs when the class
148609 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
148610 + * Congestion groups are in a "zero" state when initially claimed, and they are
148611 + * returned to that state when released.
148612 + *
148613 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
148614 + */
148615 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
148616 + struct qm_ceetm_channel *channel,
148617 + unsigned int idx,
148618 + void (*cscn)(struct qm_ceetm_ccg *,
148619 + void *cb_ctx,
148620 + int congested),
148621 + void *cb_ctx);
148622 +
148623 +/**
148624 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
148625 + * @ccg: the given ccg.
148626 + *
148627 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
148628 + * (class queues that are associated with the CCG) have not been released.
148629 + */
148630 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
148631 +
148632 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
148633 + * controls which CCG attributes are to be updated, and the remainder specify
148634 + * the values for those attributes. A CCG counts either frames or the bytes
148635 + * within those frames, but not both ('mode'). A CCG can optionally cause
148636 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
148637 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
148638 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
148639 + * to a "congestion state", but not both ('td_mode'). Congestion state has
148640 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
148641 + * notifications can be sent to software the CCG goes in to and out of this
148642 + * congested state ('cscn_en'). */
148643 +struct qm_ceetm_ccg_params {
148644 + /* Boolean fields together in a single bitfield struct */
148645 + struct {
148646 + /* Whether to count bytes or frames. 1==frames */
148647 + u8 mode:1;
148648 + /* En/disable tail-drop. 1==enable */
148649 + u8 td_en:1;
148650 + /* Tail-drop on congestion-state or threshold. 1=threshold */
148651 + u8 td_mode:1;
148652 + /* Generate congestion state change notifications. 1==enable */
148653 + u8 cscn_en:1;
148654 + /* Enable WRED rejections (per colour). 1==enable */
148655 + u8 wr_en_g:1;
148656 + u8 wr_en_y:1;
148657 + u8 wr_en_r:1;
148658 + } __packed;
148659 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
148660 + struct qm_cgr_cs_thres td_thres;
148661 + /* Congestion state thresholds, for entry and exit. */
148662 + struct qm_cgr_cs_thres cs_thres_in;
148663 + struct qm_cgr_cs_thres cs_thres_out;
148664 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
148665 + signed char oal;
148666 + /* Congestion state change notification for DCP portal, virtual CCGID*/
148667 + /* WRED parameters. */
148668 + struct qm_cgr_wr_parm wr_parm_g;
148669 + struct qm_cgr_wr_parm wr_parm_y;
148670 + struct qm_cgr_wr_parm wr_parm_r;
148671 +};
148672 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
148673 + * the CCGR are to be updated. */
148674 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
148675 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
148676 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
148677 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
148678 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
148679 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
148680 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
148681 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
148682 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
148683 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
148684 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
148685 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
148686 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
148687 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
148688 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
148689 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
148690 +
148691 +/**
148692 + * qman_ceetm_ccg_set
148693 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
148694 + * @ccg: the given CCG object.
148695 + * @we_mask: the write enable mask.
148696 + * @params: the parameters setting for this ccg
148697 + *
148698 + * Return 0 for success, or -EIO if configure ccg command returns error for
148699 + * "set" function, or -EINVAL if query ccg command returns error for "get"
148700 + * function.
148701 + */
148702 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
148703 + u16 we_mask,
148704 + const struct qm_ceetm_ccg_params *params);
148705 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
148706 + struct qm_ceetm_ccg_params *params);
148707 +
148708 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
148709 + * mask.
148710 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
148711 + * in the cscn target mask.
148712 + * @ccg: the give CCG object.
148713 + * @swp_idx: the index of the software portal.
148714 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
148715 + * the target mask.
148716 + * @we_mask: the write enable mask.
148717 + * @params: the parameters setting for this ccg
148718 + *
148719 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148720 + */
148721 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
148722 + u16 swp_idx,
148723 + unsigned int cscn_enabled,
148724 + u16 we_mask,
148725 + const struct qm_ceetm_ccg_params *params);
148726 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
148727 + u16 swp_idx,
148728 + unsigned int *cscn_enabled);
148729 +
148730 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
148731 + * target mask.
148732 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
148733 + * is in the cscn target mask.
148734 + * @ccg: the give CCG object.
148735 + * @dcp_idx: the index of the direct connect portal.
148736 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
148737 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
148738 + * the target mask.
148739 + * @we_mask: the write enable mask.
148740 + * @params: the parameters setting for this ccg
148741 + *
148742 + * Return 0 for success, or -EINVAL if command in set/get function fails.
148743 + */
148744 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
148745 + u16 dcp_idx,
148746 + u8 vcgid,
148747 + unsigned int cscn_enabled,
148748 + u16 we_mask,
148749 + const struct qm_ceetm_ccg_params *params);
148750 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
148751 + u16 dcp_idx,
148752 + u8 *vcgid,
148753 + unsigned int *cscn_enabled);
148754 +
148755 +/**
148756 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
148757 + * CEETM CCG counters.
148758 + * @ccg: the given CCG object.
148759 + * @flags: indicates whether the statistics counter will be cleared after query.
148760 + * @frame_count: The number of the frames that have been counted since the
148761 + * counter was cleared last time.
148762 + * @byte_count: the number of bytes in all frames that have been counted.
148763 + *
148764 + * Return zero for success or -EINVAL if query statistics command returns error.
148765 + *
148766 + */
148767 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
148768 + u64 *frame_count, u64 *byte_count);
148769 +
148770 +/**
148771 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
148772 + * @lfqid: Logical Frame Queue ID
148773 + * @lfqmt_query: Results of the query command
148774 + *
148775 + * Returns zero for success or -EIO if the query command returns error.
148776 + *
148777 + */
148778 +int qman_ceetm_query_lfqmt(int lfqid,
148779 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
148780 +
148781 +/**
148782 + * qman_ceetm_query_cq - Queries a CEETM CQ
148783 + * @cqid: the channel ID (first byte) followed by the CQ idx
148784 + * @dcpid: CEETM portal ID
148785 + * @cq_query: storage for the queried CQ fields
148786 + *
148787 + * Returns zero for success or -EIO if the query command returns error.
148788 + *
148789 +*/
148790 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
148791 + struct qm_mcr_ceetm_cq_query *cq_query);
148792 +
148793 +/**
148794 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
148795 + * @cid: Target ID (CQID or CCGRID)
148796 + * @dcp_idx: CEETM portal ID
148797 + * @command_type: One of the following:
148798 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
148799 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
148800 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
148801 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
148802 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
148803 + * 5 = Write reject statistics. CID carries the CCGRID to be written
148804 + * @frame_count: Frame count value to be written if this is a write command
148805 + * @byte_count: Bytes count value to be written if this is a write command
148806 + *
148807 + * Returns zero for success or -EIO if the query command returns error.
148808 + */
148809 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
148810 + u16 command_type, u64 frame_count,
148811 + u64 byte_count);
148812 +
148813 +/**
148814 + * qman_set_wpm - Set waterfall power management
148815 + *
148816 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148817 + *
148818 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148819 + * accessible.
148820 + */
148821 +int qman_set_wpm(int wpm_enable);
148822 +
148823 +/**
148824 + * qman_get_wpm - Query the waterfall power management setting
148825 + *
148826 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
148827 + *
148828 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
148829 + * accessible.
148830 + */
148831 +int qman_get_wpm(int *wpm_enable);
148832 +
148833 +/* The below qman_p_***() variants might be called in a migration situation
148834 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
148835 + * execution was affine to prior to migration.
148836 + * @qman_portal specifies which portal the APIs will use.
148837 +*/
148838 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
148839 + *p);
148840 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
148841 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
148842 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
148843 +u32 qman_p_poll_slow(struct qman_portal *p);
148844 +void qman_p_poll(struct qman_portal *p);
148845 +void qman_p_stop_dequeues(struct qman_portal *p);
148846 +void qman_p_start_dequeues(struct qman_portal *p);
148847 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
148848 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
148849 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
148850 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
148851 + int park_request);
148852 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
148853 + u32 flags __maybe_unused, u32 vdqcr);
148854 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
148855 + const struct qm_fd *fd, u32 flags);
148856 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
148857 + const struct qm_fd *fd, u32 flags,
148858 + struct qman_fq *orp, u16 orp_seqnum);
148859 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
148860 + const struct qm_fd *fd, u32 flags,
148861 + qman_cb_precommit cb, void *cb_arg);
148862 +#ifdef __cplusplus
148863 +}
148864 +#endif
148865 +
148866 +#endif /* FSL_QMAN_H */
148867 --- /dev/null
148868 +++ b/include/linux/fsl_usdpaa.h
148869 @@ -0,0 +1,372 @@
148870 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
148871 + *
148872 + * This file is licensed under the terms of the GNU General Public License
148873 + * version 2. This program is licensed "as is" without any warranty of any
148874 + * kind, whether express or implied.
148875 + */
148876 +
148877 +#ifndef FSL_USDPAA_H
148878 +#define FSL_USDPAA_H
148879 +
148880 +#ifdef __cplusplus
148881 +extern "C" {
148882 +#endif
148883 +
148884 +#include <linux/uaccess.h>
148885 +#include <linux/ioctl.h>
148886 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
148887 +#include <linux/compat.h>
148888 +
148889 +#ifdef CONFIG_FSL_USDPAA
148890 +
148891 +/******************************/
148892 +/* Allocation of resource IDs */
148893 +/******************************/
148894 +
148895 +/* This enum is used to distinguish between the type of underlying object being
148896 + * manipulated. */
148897 +enum usdpaa_id_type {
148898 + usdpaa_id_fqid,
148899 + usdpaa_id_bpid,
148900 + usdpaa_id_qpool,
148901 + usdpaa_id_cgrid,
148902 + usdpaa_id_ceetm0_lfqid,
148903 + usdpaa_id_ceetm0_channelid,
148904 + usdpaa_id_ceetm1_lfqid,
148905 + usdpaa_id_ceetm1_channelid,
148906 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
148907 +};
148908 +#define USDPAA_IOCTL_MAGIC 'u'
148909 +struct usdpaa_ioctl_id_alloc {
148910 + uint32_t base; /* Return value, the start of the allocated range */
148911 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
148912 + uint32_t num; /* how many IDs to allocate (and return value) */
148913 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
148914 + int partial; /* whether to allow less than 'num' */
148915 +};
148916 +struct usdpaa_ioctl_id_release {
148917 + /* Input; */
148918 + enum usdpaa_id_type id_type;
148919 + uint32_t base;
148920 + uint32_t num;
148921 +};
148922 +struct usdpaa_ioctl_id_reserve {
148923 + enum usdpaa_id_type id_type;
148924 + uint32_t base;
148925 + uint32_t num;
148926 +};
148927 +
148928 +
148929 +/* ioctl() commands */
148930 +#define USDPAA_IOCTL_ID_ALLOC \
148931 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
148932 +#define USDPAA_IOCTL_ID_RELEASE \
148933 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
148934 +#define USDPAA_IOCTL_ID_RESERVE \
148935 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
148936 +
148937 +/**********************/
148938 +/* Mapping DMA memory */
148939 +/**********************/
148940 +
148941 +/* Maximum length for a map name, including NULL-terminator */
148942 +#define USDPAA_DMA_NAME_MAX 16
148943 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
148944 + * For a sharable and named map, specify _SHARED (whether creating one or
148945 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
148946 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
148947 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
148948 + * specified and the mapping already exists, the mapping will fail unless _LAZY
148949 + * is specified. When mapping to a pre-existing sharable map, the length must be
148950 + * an exact match. Lengths must be a power-of-4 multiple of page size.
148951 + *
148952 + * Note that this does not actually map the memory to user-space, that is done
148953 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
148954 + * ioctl() is what gives the process permission to do this, and a page-offset
148955 + * with which to do so.
148956 + */
148957 +#define USDPAA_DMA_FLAG_SHARE 0x01
148958 +#define USDPAA_DMA_FLAG_CREATE 0x02
148959 +#define USDPAA_DMA_FLAG_LAZY 0x04
148960 +#define USDPAA_DMA_FLAG_RDONLY 0x08
148961 +struct usdpaa_ioctl_dma_map {
148962 + /* Output parameters - virtual and physical addresses */
148963 + void *ptr;
148964 + uint64_t phys_addr;
148965 + /* Input parameter, the length of the region to be created (or if
148966 + * mapping an existing region, this must match it). Must be a power-of-4
148967 + * multiple of page size. */
148968 + uint64_t len;
148969 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148970 + uint32_t flags;
148971 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148972 + * of the existing mapping to use). */
148973 + char name[USDPAA_DMA_NAME_MAX];
148974 + /* If this ioctl() creates the mapping, this is an input parameter
148975 + * stating whether the region supports locking. If mapping an existing
148976 + * region, this is a return value indicating the same thing. */
148977 + int has_locking;
148978 + /* In the case of a successful map with _CREATE and _LAZY, this return
148979 + * value indicates whether we created the mapped region or whether it
148980 + * already existed. */
148981 + int did_create;
148982 +};
148983 +
148984 +#ifdef CONFIG_COMPAT
148985 +struct usdpaa_ioctl_dma_map_compat {
148986 + /* Output parameters - virtual and physical addresses */
148987 + compat_uptr_t ptr;
148988 + uint64_t phys_addr;
148989 + /* Input parameter, the length of the region to be created (or if
148990 + * mapping an existing region, this must match it). Must be a power-of-4
148991 + * multiple of page size. */
148992 + uint64_t len;
148993 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
148994 + uint32_t flags;
148995 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
148996 + * of the existing mapping to use). */
148997 + char name[USDPAA_DMA_NAME_MAX];
148998 + /* If this ioctl() creates the mapping, this is an input parameter
148999 + * stating whether the region supports locking. If mapping an existing
149000 + * region, this is a return value indicating the same thing. */
149001 + int has_locking;
149002 + /* In the case of a successful map with _CREATE and _LAZY, this return
149003 + * value indicates whether we created the mapped region or whether it
149004 + * already existed. */
149005 + int did_create;
149006 +};
149007 +
149008 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
149009 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
149010 +#endif
149011 +
149012 +
149013 +#define USDPAA_IOCTL_DMA_MAP \
149014 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
149015 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
149016 + * This ioctl will do both (though you can munmap() before calling the ioctl
149017 + * too). */
149018 +#define USDPAA_IOCTL_DMA_UNMAP \
149019 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
149020 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
149021 + * with a mmap()'d address, and the process will (interruptible) sleep if the
149022 + * lock is already held by another process. Process destruction will
149023 + * automatically clean up any held locks. */
149024 +#define USDPAA_IOCTL_DMA_LOCK \
149025 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
149026 +#define USDPAA_IOCTL_DMA_UNLOCK \
149027 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
149028 +
149029 +/***************************************/
149030 +/* Mapping and using QMan/BMan portals */
149031 +/***************************************/
149032 +enum usdpaa_portal_type {
149033 + usdpaa_portal_qman,
149034 + usdpaa_portal_bman,
149035 +};
149036 +
149037 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
149038 +
149039 +struct usdpaa_ioctl_portal_map {
149040 + /* Input parameter, is a qman or bman portal required. */
149041 +
149042 + enum usdpaa_portal_type type;
149043 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149044 + for don't care. The portal index will be populated by the
149045 + driver when the ioctl() successfully completes */
149046 + uint32_t index;
149047 +
149048 + /* Return value if the map succeeds, this gives the mapped
149049 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149050 + struct usdpaa_portal_map {
149051 + void *cinh;
149052 + void *cena;
149053 + } addr;
149054 + /* Qman-specific return values */
149055 + uint16_t channel;
149056 + uint32_t pools;
149057 +};
149058 +
149059 +#ifdef CONFIG_COMPAT
149060 +struct compat_usdpaa_ioctl_portal_map {
149061 + /* Input parameter, is a qman or bman portal required. */
149062 + enum usdpaa_portal_type type;
149063 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149064 + for don't care. The portal index will be populated by the
149065 + driver when the ioctl() successfully completes */
149066 + uint32_t index;
149067 + /* Return value if the map succeeds, this gives the mapped
149068 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
149069 + struct usdpaa_portal_map_compat {
149070 + compat_uptr_t cinh;
149071 + compat_uptr_t cena;
149072 + } addr;
149073 + /* Qman-specific return values */
149074 + uint16_t channel;
149075 + uint32_t pools;
149076 +};
149077 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
149078 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
149079 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
149080 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
149081 +#endif
149082 +
149083 +#define USDPAA_IOCTL_PORTAL_MAP \
149084 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
149085 +#define USDPAA_IOCTL_PORTAL_UNMAP \
149086 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
149087 +
149088 +struct usdpaa_ioctl_irq_map {
149089 + enum usdpaa_portal_type type; /* Type of portal to map */
149090 + int fd; /* File descriptor that contains the portal */
149091 + void *portal_cinh; /* Cache inhibited area to identify the portal */
149092 +};
149093 +
149094 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
149095 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
149096 +
149097 +#ifdef CONFIG_COMPAT
149098 +
149099 +struct compat_ioctl_irq_map {
149100 + enum usdpaa_portal_type type; /* Type of portal to map */
149101 + compat_int_t fd; /* File descriptor that contains the portal */
149102 + compat_uptr_t portal_cinh; /* Used identify the portal */};
149103 +
149104 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
149105 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
149106 +#endif
149107 +
149108 +/* ioctl to query the amount of DMA memory used in the system */
149109 +struct usdpaa_ioctl_dma_used {
149110 + uint64_t free_bytes;
149111 + uint64_t total_bytes;
149112 +};
149113 +#define USDPAA_IOCTL_DMA_USED \
149114 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
149115 +
149116 +/* ioctl to allocate a raw portal */
149117 +struct usdpaa_ioctl_raw_portal {
149118 + /* inputs */
149119 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149120 +
149121 + /* set to non zero to turn on stashing */
149122 + uint8_t enable_stash;
149123 + /* Stashing attributes for the portal */
149124 + uint32_t cpu;
149125 + uint32_t cache;
149126 + uint32_t window;
149127 +
149128 + /* Specifies the stash request queue this portal should use */
149129 + uint8_t sdest;
149130 +
149131 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149132 + * for don't care. The portal index will be populated by the
149133 + * driver when the ioctl() successfully completes */
149134 + uint32_t index;
149135 +
149136 + /* outputs */
149137 + uint64_t cinh;
149138 + uint64_t cena;
149139 +};
149140 +
149141 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
149142 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
149143 +
149144 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
149145 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
149146 +
149147 +#ifdef CONFIG_COMPAT
149148 +
149149 +struct compat_ioctl_raw_portal {
149150 + /* inputs */
149151 + enum usdpaa_portal_type type; /* Type of portal to allocate */
149152 +
149153 + /* set to non zero to turn on stashing */
149154 + uint8_t enable_stash;
149155 + /* Stashing attributes for the portal */
149156 + uint32_t cpu;
149157 + uint32_t cache;
149158 + uint32_t window;
149159 + /* Specifies the stash request queue this portal should use */
149160 + uint8_t sdest;
149161 +
149162 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
149163 + * for don't care. The portal index will be populated by the
149164 + * driver when the ioctl() successfully completes */
149165 + uint32_t index;
149166 +
149167 + /* outputs */
149168 + uint64_t cinh;
149169 + uint64_t cena;
149170 +};
149171 +
149172 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
149173 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
149174 +
149175 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
149176 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
149177 +
149178 +#endif
149179 +
149180 +#ifdef __KERNEL__
149181 +
149182 +/* Early-boot hook */
149183 +int __init fsl_usdpaa_init_early(void);
149184 +
149185 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
149186 + * faults within its ranges via this hook. */
149187 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
149188 +
149189 +#endif /* __KERNEL__ */
149190 +
149191 +#endif /* CONFIG_FSL_USDPAA */
149192 +
149193 +#ifdef __KERNEL__
149194 +/* This interface is needed in a few places and though it's not specific to
149195 + * USDPAA as such, creating a new header for it doesn't make any sense. The
149196 + * qbman kernel driver implements this interface and uses it as the backend for
149197 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
149198 + * interface for tracking per-process allocations handed out to user-space. */
149199 +struct dpa_alloc {
149200 + struct list_head free;
149201 + spinlock_t lock;
149202 + struct list_head used;
149203 +};
149204 +#define DECLARE_DPA_ALLOC(name) \
149205 + struct dpa_alloc name = { \
149206 + .free = { \
149207 + .prev = &name.free, \
149208 + .next = &name.free \
149209 + }, \
149210 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
149211 + .used = { \
149212 + .prev = &name.used, \
149213 + .next = &name.used \
149214 + } \
149215 + }
149216 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
149217 +{
149218 + INIT_LIST_HEAD(&alloc->free);
149219 + INIT_LIST_HEAD(&alloc->used);
149220 + spin_lock_init(&alloc->lock);
149221 +}
149222 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
149223 + int partial);
149224 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
149225 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
149226 +
149227 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
149228 + * desired range is not available, or 0 for success. */
149229 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
149230 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
149231 + * 'alloc' is empty. */
149232 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
149233 +/* Returns 1 if the specified id is alloced, 0 otherwise */
149234 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
149235 +#endif /* __KERNEL__ */
149236 +
149237 +#ifdef __cplusplus
149238 +}
149239 +#endif
149240 +
149241 +#endif /* FSL_USDPAA_H */
149242 --- /dev/null
149243 +++ b/include/uapi/linux/fmd/Kbuild
149244 @@ -0,0 +1,5 @@
149245 +header-y += integrations/
149246 +header-y += Peripherals/
149247 +
149248 +header-y += ioctls.h
149249 +header-y += net_ioctls.h
149250 --- /dev/null
149251 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
149252 @@ -0,0 +1,4 @@
149253 +header-y += fm_ioctls.h
149254 +header-y += fm_port_ioctls.h
149255 +header-y += fm_pcd_ioctls.h
149256 +header-y += fm_test_ioctls.h
149257 --- /dev/null
149258 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
149259 @@ -0,0 +1,628 @@
149260 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149261 + * All rights reserved.
149262 + *
149263 + * Redistribution and use in source and binary forms, with or without
149264 + * modification, are permitted provided that the following conditions are met:
149265 + * * Redistributions of source code must retain the above copyright
149266 + * notice, this list of conditions and the following disclaimer.
149267 + * * Redistributions in binary form must reproduce the above copyright
149268 + * notice, this list of conditions and the following disclaimer in the
149269 + * documentation and/or other materials provided with the distribution.
149270 + * * Neither the name of Freescale Semiconductor nor the
149271 + * names of its contributors may be used to endorse or promote products
149272 + * derived from this software without specific prior written permission.
149273 + *
149274 + *
149275 + * ALTERNATIVELY, this software may be distributed under the terms of the
149276 + * GNU General Public License ("GPL") as published by the Free Software
149277 + * Foundation, either version 2 of that License or (at your option) any
149278 + * later version.
149279 + *
149280 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149281 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149282 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149283 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149284 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149285 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149286 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149287 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149288 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149289 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149290 + */
149291 +
149292 +/**************************************************************************//**
149293 + @File fm_ioctls.h
149294 +
149295 + @Description FM Char device ioctls
149296 +*//***************************************************************************/
149297 +#ifndef __FM_IOCTLS_H
149298 +#define __FM_IOCTLS_H
149299 +
149300 +
149301 +/**************************************************************************//**
149302 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149303 +
149304 + @Description FM Linux ioctls definitions and enums
149305 +
149306 + @{
149307 +*//***************************************************************************/
149308 +
149309 +/**************************************************************************//**
149310 + @Collection FM IOCTL device ('/dev') definitions
149311 +*//***************************************************************************/
149312 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
149313 +
149314 +#define DEV_FM_MINOR_BASE 0
149315 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
149316 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
149317 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
149318 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
149319 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
149320 +
149321 +#define FM_IOC_NUM(n) (n)
149322 +#define FM_PCD_IOC_NUM(n) (n+20)
149323 +#define FM_PORT_IOC_NUM(n) (n+70)
149324 +/* @} */
149325 +
149326 +#define IOC_FM_MAX_NUM_OF_PORTS 64
149327 +
149328 +
149329 +/**************************************************************************//**
149330 + @Description Enum for defining port types
149331 + (must match enum e_FmPortType defined in fm_ext.h)
149332 +*//***************************************************************************/
149333 +typedef enum ioc_fm_port_type {
149334 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
149335 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
149336 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
149337 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
149338 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
149339 + e_IOC_FM_PORT_TYPE_DUMMY
149340 +} ioc_fm_port_type;
149341 +
149342 +
149343 +/**************************************************************************//**
149344 + @Group lnx_ioctl_FM_lib_grp FM library
149345 +
149346 + @Description FM API functions, definitions and enums
149347 + The FM module is the main driver module and is a mandatory module
149348 + for FM driver users. Before any further module initialization,
149349 + this module must be initialized.
149350 + The FM is a "single-tone" module. It is responsible of the common
149351 + HW modules: FPM, DMA, common QMI, common BMI initializations and
149352 + run-time control routines. This module must be initialized always
149353 + when working with any of the FM modules.
149354 + NOTE - We assumes that the FML will be initialize only by core No. 0!
149355 +
149356 + @{
149357 +*//***************************************************************************/
149358 +
149359 +/**************************************************************************//**
149360 + @Description FM Exceptions
149361 +*//***************************************************************************/
149362 +typedef enum ioc_fm_exceptions {
149363 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
149364 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
149365 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
149366 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
149367 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
149368 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
149369 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
149370 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
149371 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
149372 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
149373 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
149374 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
149375 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
149376 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
149377 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
149378 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
149379 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
149380 +} ioc_fm_exceptions;
149381 +
149382 +/**************************************************************************//**
149383 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
149384 +
149385 + @Description FM Runtime control unit API functions, definitions and enums.
149386 + The FM driver provides a set of control routines for each module.
149387 + These routines may only be called after the module was fully
149388 + initialized (both configuration and initialization routines were
149389 + called). They are typically used to get information from hardware
149390 + (status, counters/statistics, revision etc.), to modify a current
149391 + state or to force/enable a required action. Run-time control may
149392 + be called whenever necessary and as many times as needed.
149393 + @{
149394 +*//***************************************************************************/
149395 +
149396 +/**************************************************************************//**
149397 + @Collection General FM defines.
149398 + *//***************************************************************************/
149399 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
149400 + FM_MAX_NUM_OF_1G_RX_PORTS + \
149401 + FM_MAX_NUM_OF_10G_RX_PORTS + \
149402 + FM_MAX_NUM_OF_1G_TX_PORTS + \
149403 + FM_MAX_NUM_OF_10G_TX_PORTS)
149404 +/* @} */
149405 +
149406 +/**************************************************************************//**
149407 + @Description Structure for Port bandwidth requirement. Port is identified
149408 + by type and relative id.
149409 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
149410 +*//***************************************************************************/
149411 +typedef struct ioc_fm_port_bandwidth_t {
149412 + ioc_fm_port_type type; /**< FM port type */
149413 + uint8_t relative_port_id; /**< Type relative port id */
149414 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
149415 +} ioc_fm_port_bandwidth_t;
149416 +
149417 +/**************************************************************************//**
149418 + @Description A Structure containing an array of Port bandwidth requirements.
149419 + The user should state the ports requiring bandwidth in terms of
149420 + percentage - i.e. all port's bandwidths in the array must add
149421 + up to 100.
149422 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
149423 +*//***************************************************************************/
149424 +typedef struct ioc_fm_port_bandwidth_params {
149425 + uint8_t num_of_ports;
149426 + /**< num of ports listed in the array below */
149427 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
149428 + /**< for each port, it's bandwidth (all port's
149429 + bandwidths must add up to 100.*/
149430 +} ioc_fm_port_bandwidth_params;
149431 +
149432 +/**************************************************************************//**
149433 + @Description enum for defining FM counters
149434 +*//***************************************************************************/
149435 +typedef enum ioc_fm_counters {
149436 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
149437 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
149438 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
149439 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
149440 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
149441 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
149442 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
149443 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
149444 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
149445 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
149446 +} ioc_fm_counters;
149447 +
149448 +typedef struct ioc_fm_obj_t {
149449 + void *obj;
149450 +} ioc_fm_obj_t;
149451 +
149452 +/**************************************************************************//**
149453 + @Description A structure for returning revision information
149454 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
149455 +*//***************************************************************************/
149456 +typedef struct ioc_fm_revision_info_t {
149457 + uint8_t major; /**< Major revision */
149458 + uint8_t minor; /**< Minor revision */
149459 +} ioc_fm_revision_info_t;
149460 +
149461 +/**************************************************************************//**
149462 + @Description A structure for FM counters
149463 +*//***************************************************************************/
149464 +typedef struct ioc_fm_counters_params_t {
149465 + ioc_fm_counters cnt; /**< The requested counter */
149466 + uint32_t val; /**< The requested value to get/set from/into the counter */
149467 +} ioc_fm_counters_params_t;
149468 +
149469 +typedef union ioc_fm_api_version_t {
149470 + struct {
149471 + uint8_t major;
149472 + uint8_t minor;
149473 + uint8_t respin;
149474 + uint8_t reserved;
149475 + } version;
149476 + uint32_t ver;
149477 +} ioc_fm_api_version_t;
149478 +
149479 +#if (DPAA_VERSION >= 11)
149480 +/**************************************************************************//**
149481 + @Description A structure of information about each of the external
149482 + buffer pools used by a port or storage-profile.
149483 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
149484 +*//***************************************************************************/
149485 +typedef struct ioc_fm_ext_pool_params {
149486 + uint8_t id; /**< External buffer pool id */
149487 + uint16_t size; /**< External buffer pool buffer size */
149488 +} ioc_fm_ext_pool_params;
149489 +
149490 +/**************************************************************************//**
149491 + @Description A structure for informing the driver about the external
149492 + buffer pools allocated in the BM and used by a port or a
149493 + storage-profile.
149494 + (must be identical to t_FmExtPools defined in fm_ext.h)
149495 +*//***************************************************************************/
149496 +typedef struct ioc_fm_ext_pools {
149497 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
149498 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
149499 + /**< Parameters for each port */
149500 +} ioc_fm_ext_pools;
149501 +
149502 +typedef struct ioc_fm_vsp_params_t {
149503 + void *p_fm; /**< A handle to the FM object this VSP related to */
149504 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
149505 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
149506 + parameter associated with Rx / OP port */
149507 + uint16_t liodn_offset; /**< VSP's LIODN offset */
149508 + struct {
149509 + ioc_fm_port_type port_type; /**< Port type */
149510 + uint8_t port_id; /**< Port Id - relative to type */
149511 + } port_params;
149512 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
149513 + defined in relevant FM object */
149514 + void *id; /**< return value */
149515 +} ioc_fm_vsp_params_t;
149516 +#endif /* (DPAA_VERSION >= 11) */
149517 +
149518 +/**************************************************************************//**
149519 + @Description A structure for defining BM pool depletion criteria
149520 +*//***************************************************************************/
149521 +typedef struct ioc_fm_buf_pool_depletion_t {
149522 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
149523 + a number of pools (all together!) are depleted */
149524 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
149525 + pause frames transmission. */
149526 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
149527 + /**< For each pool, TRUE if it should be considered for
149528 + depletion (Note - this pool must be used by this port!). */
149529 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
149530 + a single-pool is depleted; */
149531 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
149532 + /**< For each pool, TRUE if it should be considered for
149533 + depletion (Note - this pool must be used by this port!) */
149534 +#if (DPAA_VERSION >= 11)
149535 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
149536 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
149537 + which is transmitted */
149538 +#endif /* (DPAA_VERSION >= 11) */
149539 +} ioc_fm_buf_pool_depletion_t;
149540 +
149541 +#if (DPAA_VERSION >= 11)
149542 +typedef struct ioc_fm_buf_pool_depletion_params_t {
149543 + void *p_fm_vsp;
149544 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
149545 +} ioc_fm_buf_pool_depletion_params_t;
149546 +#endif /* (DPAA_VERSION >= 11) */
149547 +
149548 +typedef struct ioc_fm_buffer_prefix_content_t {
149549 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
149550 + of the external buffer; Note that the private-area will
149551 + start from the base of the buffer address. */
149552 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
149553 + User may use FM_PORT_GetBufferPrsResult() in order to
149554 + get the parser-result from a buffer. */
149555 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
149556 + User may use FM_PORT_GetBufferTimeStamp() in order to
149557 + get the parser-result from a buffer. */
149558 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
149559 + User may use FM_PORT_GetBufferHashResult() in order to
149560 + get the parser-result from a buffer. */
149561 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
149562 + AD, hash-result, key, etc. */
149563 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
149564 + other value for selecting a data alignment (must be a power of 2);
149565 + if write optimization is used, must be >= 16. */
149566 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
149567 + Note that this field impacts the size of the buffer-prefix
149568 + (i.e. it pushes the data offset);
149569 + This field is irrelevant if DPAA_VERSION==10 */
149570 +} ioc_fm_buffer_prefix_content_t;
149571 +
149572 +typedef struct ioc_fm_buffer_prefix_content_params_t {
149573 + void *p_fm_vsp;
149574 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
149575 +} ioc_fm_buffer_prefix_content_params_t;
149576 +
149577 +#if (DPAA_VERSION >= 11)
149578 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
149579 + void *p_fm_vsp;
149580 + bool no_sg;
149581 +} ioc_fm_vsp_config_no_sg_params_t;
149582 +
149583 +typedef struct ioc_fm_vsp_prs_result_params_t {
149584 + void *p_fm_vsp;
149585 + void *p_data;
149586 +} ioc_fm_vsp_prs_result_params_t;
149587 +#endif
149588 +
149589 +typedef struct fm_ctrl_mon_t {
149590 + uint8_t percent_cnt[2];
149591 +} fm_ctrl_mon_t;
149592 +
149593 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
149594 + uint8_t fm_ctrl_index;
149595 + fm_ctrl_mon_t *p_mon;
149596 +} ioc_fm_ctrl_mon_counters_params_t;
149597 +
149598 +/**************************************************************************//**
149599 + @Function FM_IOC_SET_PORTS_BANDWIDTH
149600 +
149601 + @Description Sets relative weights between ports when accessing common resources.
149602 +
149603 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
149604 + their sum must equal 100.
149605 +
149606 + @Return E_OK on success; Error code otherwise.
149607 +
149608 + @Cautions Allowed only following FM_Init().
149609 +*//***************************************************************************/
149610 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
149611 +
149612 +/**************************************************************************//**
149613 + @Function FM_IOC_GET_REVISION
149614 +
149615 + @Description Returns the FM revision
149616 +
149617 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
149618 +
149619 + @Return None.
149620 +
149621 + @Cautions Allowed only following FM_Init().
149622 +*//***************************************************************************/
149623 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
149624 +
149625 +/**************************************************************************//**
149626 + @Function FM_IOC_GET_COUNTER
149627 +
149628 + @Description Reads one of the FM counters.
149629 +
149630 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
149631 +
149632 + @Return Counter's current value.
149633 +
149634 + @Cautions Allowed only following FM_Init().
149635 + Note that it is user's responsibilty to call this routine only
149636 + for enabled counters, and there will be no indication if a
149637 + disabled counter is accessed.
149638 +*//***************************************************************************/
149639 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
149640 +
149641 +/**************************************************************************//**
149642 + @Function FM_IOC_SET_COUNTER
149643 +
149644 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
149645 +
149646 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
149647 +
149648 + @Return E_OK on success; Error code otherwise.
149649 +
149650 + @Cautions Allowed only following FM_Init().
149651 +*//***************************************************************************/
149652 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
149653 +
149654 +/**************************************************************************//**
149655 + @Function FM_IOC_FORCE_INTR
149656 +
149657 + @Description Causes an interrupt event on the requested source.
149658 +
149659 + @Param[in] ioc_fm_exceptions An exception to be forced.
149660 +
149661 + @Return E_OK on success; Error code if the exception is not enabled,
149662 + or is not able to create interrupt.
149663 +
149664 + @Cautions Allowed only following FM_Init().
149665 +*//***************************************************************************/
149666 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
149667 +
149668 +/**************************************************************************//**
149669 + @Function FM_IOC_GET_API_VERSION
149670 +
149671 + @Description Reads the FMD IOCTL API version.
149672 +
149673 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
149674 +
149675 + @Return Version's value.
149676 +*//***************************************************************************/
149677 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
149678 +
149679 +#if (DPAA_VERSION >= 11)
149680 +/**************************************************************************//**
149681 + @Function FM_VSP_Config
149682 +
149683 + @Description Creates descriptor for the FM VSP module.
149684 +
149685 + The routine returns a handle (descriptor) to the FM VSP object.
149686 + This descriptor must be passed as first parameter to all other
149687 + FM VSP function calls.
149688 +
149689 + No actual initialization or configuration of FM hardware is
149690 + done by this routine.
149691 +
149692 +@Param[in] p_FmVspParams Pointer to data structure of parameters
149693 +
149694 + @Retval Handle to FM VSP object, or NULL for Failure.
149695 +*//***************************************************************************/
149696 +#if defined(CONFIG_COMPAT)
149697 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
149698 +#endif
149699 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
149700 +
149701 +/**************************************************************************//**
149702 + @Function FM_VSP_Init
149703 +
149704 + @Description Initializes the FM VSP module
149705 +
149706 + @Param[in] h_FmVsp - FM VSP module descriptor
149707 +
149708 + @Return E_OK on success; Error code otherwise.
149709 +*//***************************************************************************/
149710 +#if defined(CONFIG_COMPAT)
149711 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
149712 +#endif
149713 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
149714 +
149715 +/**************************************************************************//**
149716 + @Function FM_VSP_Free
149717 +
149718 + @Description Frees all resources that were assigned to FM VSP module.
149719 +
149720 + Calling this routine invalidates the descriptor.
149721 +
149722 + @Param[in] h_FmVsp - FM VSP module descriptor
149723 +
149724 + @Return E_OK on success; Error code otherwise.
149725 +*//***************************************************************************/
149726 +#if defined(CONFIG_COMPAT)
149727 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
149728 +#endif
149729 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
149730 +
149731 +/**************************************************************************//**
149732 + @Function FM_VSP_ConfigPoolDepletion
149733 +
149734 + @Description Calling this routine enables pause frame generation depending on the
149735 + depletion status of BM pools. It also defines the conditions to activate
149736 + this functionality. By default, this functionality is disabled.
149737 +
149738 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
149739 +
149740 + @Return E_OK on success; Error code otherwise.
149741 +
149742 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149743 +*//***************************************************************************/
149744 +#if defined(CONFIG_COMPAT)
149745 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_compat_fm_buf_pool_depletion_params_t)
149746 +#endif
149747 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
149748 +
149749 +/**************************************************************************//**
149750 + @Function FM_VSP_ConfigBufferPrefixContent
149751 +
149752 + @Description Defines the structure, size and content of the application buffer.
149753 +
149754 + The prefix will
149755 + In VSPs defined for Tx ports, if 'passPrsResult', the application
149756 + should set a value to their offsets in the prefix of
149757 + the FM will save the first 'privDataSize', than,
149758 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
149759 + and timeStamp, and the packet itself (in this order), to the
149760 + application buffer, and to offset.
149761 +
149762 + Calling this routine changes the buffer margins definitions
149763 + in the internal driver data base from its default
149764 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
149765 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
149766 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
149767 +
149768 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
149769 +
149770 + @Return E_OK on success; Error code otherwise.
149771 +
149772 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149773 +*//***************************************************************************/
149774 +#if defined(CONFIG_COMPAT)
149775 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_compat_fm_buffer_prefix_content_params_t)
149776 +#endif
149777 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
149778 +
149779 +/**************************************************************************//**
149780 + @Function FM_VSP_ConfigNoScatherGather
149781 +
149782 + @Description Calling this routine changes the possibility to receive S/G frame
149783 + in the internal driver data base
149784 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
149785 +
149786 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
149787 +
149788 + @Return E_OK on success; Error code otherwise.
149789 +
149790 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
149791 +*//***************************************************************************/
149792 +#if defined(CONFIG_COMPAT)
149793 +#define FM_IOC_VSP_CONFIG_NO_SG_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_compat_fm_vsp_config_no_sg_params_t)
149794 +#endif
149795 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
149796 +
149797 +/**************************************************************************//**
149798 + @Function FM_VSP_GetBufferPrsResult
149799 +
149800 + @Description Returns the pointer to the parse result in the data buffer.
149801 + In Rx ports this is relevant after reception, if parse
149802 + result is configured to be part of the data passed to the
149803 + application. For non Rx ports it may be used to get the pointer
149804 + of the area in the buffer where parse result should be
149805 + initialized - if so configured.
149806 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
149807 + configuration.
149808 +
149809 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
149810 +
149811 + @Return Parse result pointer on success, NULL if parse result was not
149812 + configured for this port.
149813 +
149814 + @Cautions Allowed only following FM_VSP_Init().
149815 +*//***************************************************************************/
149816 +#if defined(CONFIG_COMPAT)
149817 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_compat_fm_vsp_prs_result_params_t)
149818 +#endif
149819 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
149820 +#endif /* (DPAA_VERSION >= 11) */
149821 +
149822 +/**************************************************************************//**
149823 + @Function FM_CtrlMonStart
149824 +
149825 + @Description Start monitoring utilization of all available FM controllers.
149826 +
149827 + In order to obtain FM controllers utilization the following sequence
149828 + should be used:
149829 + -# FM_CtrlMonStart()
149830 + -# FM_CtrlMonStop()
149831 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149832 +
149833 + @Return E_OK on success; Error code otherwise.
149834 +
149835 + @Cautions Allowed only following FM_Init().
149836 +*//***************************************************************************/
149837 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
149838 +
149839 +
149840 +/**************************************************************************//**
149841 + @Function FM_CtrlMonStop
149842 +
149843 + @Description Stop monitoring utilization of all available FM controllers.
149844 +
149845 + In order to obtain FM controllers utilization the following sequence
149846 + should be used:
149847 + -# FM_CtrlMonStart()
149848 + -# FM_CtrlMonStop()
149849 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149850 +
149851 + @Return E_OK on success; Error code otherwise.
149852 +
149853 + @Cautions Allowed only following FM_Init().
149854 +*//***************************************************************************/
149855 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
149856 +
149857 +/**************************************************************************//**
149858 + @Function FM_CtrlMonGetCounters
149859 +
149860 + @Description Obtain FM controller utilization parameters.
149861 +
149862 + In order to obtain FM controllers utilization the following sequence
149863 + should be used:
149864 + -# FM_CtrlMonStart()
149865 + -# FM_CtrlMonStop()
149866 + -# FM_CtrlMonGetCounters() - issued for each FM controller
149867 +
149868 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
149869 +
149870 + @Return E_OK on success; Error code otherwise.
149871 +
149872 + @Cautions Allowed only following FM_Init().
149873 +*//***************************************************************************/
149874 +#if defined(CONFIG_COMPAT)
149875 +#define FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_compat_fm_ctrl_mon_counters_params_t)
149876 +#endif
149877 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
149878 +
149879 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
149880 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
149881 +/** @} */ /* end of lnx_ioctl_FM_grp */
149882 +
149883 +#define FMD_API_VERSION_MAJOR 21
149884 +#define FMD_API_VERSION_MINOR 1
149885 +#define FMD_API_VERSION_RESPIN 0
149886 +
149887 +#endif /* __FM_IOCTLS_H */
149888 --- /dev/null
149889 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
149890 @@ -0,0 +1,3084 @@
149891 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
149892 + * All rights reserved.
149893 + *
149894 + * Redistribution and use in source and binary forms, with or without
149895 + * modification, are permitted provided that the following conditions are met:
149896 + * * Redistributions of source code must retain the above copyright
149897 + * notice, this list of conditions and the following disclaimer.
149898 + * * Redistributions in binary form must reproduce the above copyright
149899 + * notice, this list of conditions and the following disclaimer in the
149900 + * documentation and/or other materials provided with the distribution.
149901 + * * Neither the name of Freescale Semiconductor nor the
149902 + * names of its contributors may be used to endorse or promote products
149903 + * derived from this software without specific prior written permission.
149904 + *
149905 + *
149906 + * ALTERNATIVELY, this software may be distributed under the terms of the
149907 + * GNU General Public License ("GPL") as published by the Free Software
149908 + * Foundation, either version 2 of that License or (at your option) any
149909 + * later version.
149910 + *
149911 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
149912 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
149913 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
149914 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
149915 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
149916 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
149917 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
149918 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
149919 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
149920 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
149921 + */
149922 +
149923 +
149924 +/******************************************************************************
149925 + @File fm_pcd_ioctls.h
149926 +
149927 + @Description FM PCD ...
149928 +*//***************************************************************************/
149929 +#ifndef __FM_PCD_IOCTLS_H
149930 +#define __FM_PCD_IOCTLS_H
149931 +
149932 +#include "net_ioctls.h"
149933 +#include "fm_ioctls.h"
149934 +
149935 +
149936 +/**************************************************************************//**
149937 +
149938 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
149939 +
149940 + @Description Frame Manager Linux ioctls definitions and enums
149941 +
149942 + @{
149943 +*//***************************************************************************/
149944 +
149945 +/**************************************************************************//**
149946 + @Group lnx_ioctl_FM_PCD_grp FM PCD
149947 +
149948 + @Description Frame Manager PCD API functions, definitions and enums
149949 +
149950 + The FM PCD module is responsible for the initialization of all
149951 + global classifying FM modules. This includes the parser general and
149952 + common registers, the key generator global and common registers,
149953 + and the policer global and common registers.
149954 + In addition, the FM PCD SW module will initialize all required
149955 + key generator schemes, coarse classification flows, and policer
149956 + profiles. When an FM module is configured to work with one of these
149957 + entities, it will register to it using the FM PORT API. The PCD
149958 + module will manage the PCD resources - i.e. resource management of
149959 + KeyGen schemes, etc.
149960 +
149961 + @{
149962 +*//***************************************************************************/
149963 +
149964 +/**************************************************************************//**
149965 + @Collection General PCD defines
149966 +*//***************************************************************************/
149967 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
149968 +
149969 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
149970 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
149971 + /**< Number of distinction units is limited by
149972 + register size (32 bits) minus reserved bits
149973 + for private headers. */
149974 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
149975 + in a distinction unit */
149976 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
149977 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
149978 + For HW implementation reasons, in most
149979 + cases less than this will be allowed; The
149980 + driver will return an initialization error
149981 + if resource is unavailable. */
149982 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
149983 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
149984 +
149985 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
149986 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
149987 +
149988 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
149989 + insert manipulation */
149990 +
149991 +#if DPAA_VERSION >= 11
149992 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
149993 +#endif /* DPAA_VERSION >= 11 */
149994 +/* @} */
149995 +
149996 +#ifdef FM_CAPWAP_SUPPORT
149997 +#error "FM_CAPWAP_SUPPORT not implemented!"
149998 +#endif
149999 +
150000 +
150001 +/**************************************************************************//**
150002 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
150003 +
150004 + @Description Frame Manager PCD Initialization Unit API
150005 +
150006 + @{
150007 +*//***************************************************************************/
150008 +
150009 +/**************************************************************************//**
150010 + @Description PCD counters
150011 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
150012 +*//***************************************************************************/
150013 +typedef enum ioc_fm_pcd_counters {
150014 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
150015 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
150016 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
150017 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
150018 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
150019 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
150020 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
150021 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
150022 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
150023 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
150024 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
150025 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
150026 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
150027 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
150028 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L2 parse result is returned with errors. */
150029 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L3 parse result is returned with errors. */
150030 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times L4 parse result is returned with errors. */
150031 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR, /**< Parser counter - counts the number of times SHIM parse result is returned with errors. */
150032 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
150033 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES, /**< Parser counter - counts the number of cycles stalled waiting for parser internal memory reads while executing soft parser instruction. */
150034 + e_IOC_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES, /**< Parser counter - counts the number of cycles spent executing hard parser (including stall cycles). */
150035 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
150036 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
150037 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
150038 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
150039 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
150040 +} ioc_fm_pcd_counters;
150041 +
150042 +/**************************************************************************//**
150043 + @Description PCD interrupts
150044 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
150045 +*//***************************************************************************/
150046 +typedef enum ioc_fm_pcd_exceptions {
150047 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
150048 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
150049 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
150050 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
150051 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
150052 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
150053 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
150054 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
150055 +} ioc_fm_pcd_exceptions;
150056 +
150057 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
150058 +
150059 +
150060 +/**************************************************************************//**
150061 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
150062 +
150063 + @Description Frame Manager PCD Runtime Unit
150064 +
150065 + The runtime control allows creation of PCD infrastructure modules
150066 + such as Network Environment Characteristics, Classification Plan
150067 + Groups and Coarse Classification Trees.
150068 + It also allows on-the-fly initialization, modification and removal
150069 + of PCD modules such as KeyGen schemes, coarse classification nodes
150070 + and Policer profiles.
150071 +
150072 + In order to explain the programming model of the PCD driver interface
150073 + a few terms should be explained, and will be used below.
150074 + - Distinction Header - One of the 16 protocols supported by the FM parser,
150075 + or one of the SHIM headers (1 or 2). May be a header with a special
150076 + option (see below).
150077 + - Interchangeable Headers Group - This is a group of Headers recognized
150078 + by either one of them. For example, if in a specific context the user
150079 + chooses to treat IPv4 and IPV6 in the same way, they may create an
150080 + interchangeable Headers Unit consisting of these 2 headers.
150081 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
150082 + Group.
150083 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
150084 + IPv6, includes multicast, broadcast and other protocol specific options.
150085 + In terms of hardware it relates to the options available in the classification
150086 + plan.
150087 + - Network Environment Characteristics - a set of Distinction Units that define
150088 + the total recognizable header selection for a certain environment. This is
150089 + NOT the list of all headers that will ever appear in a flow, but rather
150090 + everything that needs distinction in a flow, where distinction is made by KeyGen
150091 + schemes and coarse classification action descriptors.
150092 +
150093 + The PCD runtime modules initialization is done in stages. The first stage after
150094 + initializing the PCD module itself is to establish a Network Flows Environment
150095 + Definition. The application may choose to establish one or more such environments.
150096 + Later, when needed, the application will have to state, for some of its modules,
150097 + to which single environment it belongs.
150098 +
150099 + @{
150100 +*//***************************************************************************/
150101 +
150102 +
150103 +/**************************************************************************//**
150104 + @Description structure for FM counters
150105 +*//***************************************************************************/
150106 +typedef struct ioc_fm_pcd_counters_params_t {
150107 + ioc_fm_pcd_counters cnt; /**< The requested counter */
150108 + uint32_t val; /**< The requested value to get/set from/into the counter */
150109 +} ioc_fm_pcd_counters_params_t;
150110 +
150111 +/**************************************************************************//**
150112 + @Description structure for FM exception definitios
150113 +*//***************************************************************************/
150114 +typedef struct ioc_fm_pcd_exception_params_t {
150115 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
150116 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
150117 +} ioc_fm_pcd_exception_params_t;
150118 +
150119 +/**************************************************************************//**
150120 + @Description A structure for SW parser labels
150121 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
150122 + *//***************************************************************************/
150123 +typedef struct ioc_fm_pcd_prs_label_params_t {
150124 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
150125 + resolution), relative to Parser RAM. */
150126 + ioc_net_header_type hdr; /**< The existence of this header will invoke
150127 + the SW parser code. */
150128 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
150129 + attachments for the same header, use this
150130 + index to distinguish between them. */
150131 +} ioc_fm_pcd_prs_label_params_t;
150132 +
150133 +/**************************************************************************//**
150134 + @Description A structure for SW parser
150135 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
150136 + *//***************************************************************************/
150137 +typedef struct ioc_fm_pcd_prs_sw_params_t {
150138 + bool override; /**< FALSE to invoke a check that nothing else
150139 + was loaded to this address, including
150140 + internal patches.
150141 + TRUE to override any existing code.*/
150142 + uint32_t size; /**< SW parser code size */
150143 + uint16_t base; /**< SW parser base (in instruction counts!
150144 + must be larger than 0x20)*/
150145 + uint8_t *p_code; /**< SW parser code */
150146 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
150147 + /**< SW parser data (parameters) */
150148 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
150149 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
150150 + /**< SW parser labels table,
150151 + containing num_of_labels entries */
150152 +} ioc_fm_pcd_prs_sw_params_t;
150153 +
150154 +/**************************************************************************//**
150155 + @Description A structure to set the a KeyGen default value
150156 + *//***************************************************************************/
150157 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
150158 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
150159 + uint32_t value; /**< The requested default value */
150160 +} ioc_fm_pcd_kg_dflt_value_params_t;
150161 +
150162 +
150163 +/**************************************************************************//**
150164 + @Function FM_PCD_Enable
150165 +
150166 + @Description This routine should be called after PCD is initialized for enabling all
150167 + PCD engines according to their existing configuration.
150168 +
150169 + @Return 0 on success; Error code otherwise.
150170 +
150171 + @Cautions Allowed only when PCD is disabled.
150172 +*//***************************************************************************/
150173 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
150174 +
150175 +/**************************************************************************//**
150176 + @Function FM_PCD_Disable
150177 +
150178 + @Description This routine may be called when PCD is enabled in order to
150179 + disable all PCD engines. It may be called
150180 + only when none of the ports in the system are using the PCD.
150181 +
150182 + @Return 0 on success; Error code otherwise.
150183 +
150184 + @Cautions Allowed only when PCD is enabled.
150185 +*//***************************************************************************/
150186 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
150187 +
150188 + /**************************************************************************//**
150189 + @Function FM_PCD_PrsLoadSw
150190 +
150191 + @Description This routine may be called only when all ports in the
150192 + system are actively using the classification plan scheme.
150193 + In such cases it is recommended in order to save resources.
150194 + The driver automatically saves 8 classification plans for
150195 + ports that do NOT use the classification plan mechanism, to
150196 + avoid this (in order to save those entries) this routine may
150197 + be called.
150198 +
150199 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
150200 +
150201 + @Return 0 on success; Error code otherwise.
150202 +
150203 + @Cautions Allowed only when PCD is disabled.
150204 +*//***************************************************************************/
150205 +#if defined(CONFIG_COMPAT)
150206 +#define FM_PCD_IOC_PRS_LOAD_SW_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_compat_fm_pcd_prs_sw_params_t)
150207 +#endif
150208 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
150209 +
150210 +/**************************************************************************//**
150211 + @Function FM_PCD_KgSetDfltValue
150212 +
150213 + @Description Calling this routine sets a global default value to be used
150214 + by the KeyGen when parser does not recognize a required
150215 + field/header.
150216 + By default default values are 0.
150217 +
150218 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
150219 +
150220 + @Return 0 on success; Error code otherwise.
150221 +
150222 + @Cautions Allowed only when PCD is disabled.
150223 +*//***************************************************************************/
150224 +#define FM_PCD_IOC_KG_SET_DFLT_VALUE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(6), ioc_fm_pcd_kg_dflt_value_params_t)
150225 +
150226 +/**************************************************************************//**
150227 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
150228 +
150229 + @Description Calling this routine allows the keygen to access data past
150230 + the parser finishing point.
150231 +
150232 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
150233 +
150234 + @Return 0 on success; Error code otherwise.
150235 +
150236 + @Cautions Allowed only when PCD is disabled.
150237 +*//***************************************************************************/
150238 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
150239 +
150240 +/**************************************************************************//**
150241 + @Function FM_PCD_SetException
150242 +
150243 + @Description Calling this routine enables/disables PCD interrupts.
150244 +
150245 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
150246 +
150247 + @Return 0 on success; Error code otherwise.
150248 +*//***************************************************************************/
150249 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
150250 +
150251 +/**************************************************************************//**
150252 + @Function FM_PCD_GetCounter
150253 +
150254 + @Description Reads one of the FM PCD counters.
150255 +
150256 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
150257 +
150258 + @Return 0 on success; Error code otherwise.
150259 +
150260 + @Cautions Note that it is user's responsibilty to call this routine only
150261 + for enabled counters, and there will be no indication if a
150262 + disabled counter is accessed.
150263 +*//***************************************************************************/
150264 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
150265 +
150266 +/**************************************************************************//**
150267 +
150268 + @Function FM_PCD_KgSchemeGetCounter
150269 +
150270 + @Description Reads scheme packet counter.
150271 +
150272 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
150273 +
150274 + @Return Counter's current value.
150275 +
150276 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
150277 +*//***************************************************************************/
150278 +#if defined(CONFIG_COMPAT)
150279 +#define FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_compat_fm_pcd_kg_scheme_spc_t)
150280 +#endif
150281 +#define FM_PCD_IOC_KG_SCHEME_GET_CNTR _IOR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(4), ioc_fm_pcd_kg_scheme_spc_t)
150282 +
150283 +#if 0
150284 +TODO: unused IOCTL
150285 +/**************************************************************************//**
150286 + @Function FM_PCD_ModifyCounter
150287 +
150288 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
150289 +
150290 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
150291 +
150292 + @Return 0 on success; Error code otherwise.
150293 +*//***************************************************************************/
150294 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
150295 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
150296 +#endif
150297 +
150298 +/**************************************************************************//**
150299 + @Function FM_PCD_ForceIntr
150300 +
150301 + @Description Causes an interrupt event on the requested source.
150302 +
150303 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
150304 +
150305 + @Return 0 on success; error code if the exception is not enabled,
150306 + or is not able to create interrupt.
150307 +*//***************************************************************************/
150308 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
150309 +
150310 +/**************************************************************************//**
150311 + @Collection Definitions of coarse classification parameters as required by KeyGen
150312 + (when coarse classification is the next engine after this scheme).
150313 +*//***************************************************************************/
150314 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
150315 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
150316 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
150317 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
150318 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
150319 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
150320 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
150321 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
150322 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
150323 +/* @} */
150324 +
150325 +/**************************************************************************//**
150326 + @Collection A set of definitions to allow protocol
150327 + special option description.
150328 +*//***************************************************************************/
150329 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
150330 +
150331 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
150332 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
150333 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
150334 +
150335 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
150336 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
150337 +
150338 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
150339 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
150340 +
150341 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
150342 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
150343 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
150344 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
150345 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
150346 +
150347 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
150348 + IPV4 Reassembly manipulation requires network
150349 + environment with IPV4 header and IPV4_FRAG_1 option */
150350 +
150351 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
150352 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
150353 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
150354 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
150355 +
150356 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
150357 + IPV6 Reassembly manipulation requires network
150358 + environment with IPV6 header and IPV6_FRAG_1 option */
150359 +#if (DPAA_VERSION >= 11)
150360 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
150361 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
150362 + CAPWAP Reassembly manipulation requires network
150363 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
150364 + in case where fragment found, the fragment-extension offset
150365 + may be found at 'shim2' (in parser-result). */
150366 +#endif /* (DPAA_VERSION >= 11) */
150367 +
150368 +/* @} */
150369 +
150370 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
150371 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
150372 +/**************************************************************************//**
150373 + @Collection A set of definitions to support Header Manipulation selection.
150374 +*//***************************************************************************/
150375 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
150376 +
150377 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
150378 +
150379 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
150380 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150381 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
150382 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150383 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
150384 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
150385 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150386 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
150387 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
150388 +
150389 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
150390 +
150391 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
150392 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150393 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
150394 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
150395 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150396 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
150397 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
150398 +
150399 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
150400 +
150401 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
150402 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150403 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
150404 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
150405 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
150406 +
150407 +/* @} */
150408 +
150409 +/**************************************************************************//**
150410 + @Description A type used for returning the order of the key extraction.
150411 + each value in this array represents the index of the extraction
150412 + command as defined by the user in the initialization extraction array.
150413 + The valid size of this array is the user define number of extractions
150414 + required (also marked by the second '0' in this array).
150415 +*//***************************************************************************/
150416 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150417 +
150418 +/**************************************************************************//**
150419 + @Description All PCD engines
150420 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
150421 +*//***************************************************************************/
150422 +typedef enum ioc_fm_pcd_engine {
150423 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
150424 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
150425 + e_IOC_FM_PCD_KG, /**< KeyGen */
150426 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
150427 + e_IOC_FM_PCD_PLCR, /**< Policer */
150428 + e_IOC_FM_PCD_PRS, /**< Parser */
150429 +#if DPAA_VERSION >= 11
150430 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
150431 +#endif /* DPAA_VERSION >= 11 */
150432 + e_IOC_FM_PCD_HASH /**< Hash Table */
150433 +} ioc_fm_pcd_engine;
150434 +
150435 +/**************************************************************************//**
150436 + @Description An enum for selecting extraction by header types
150437 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
150438 +*//***************************************************************************/
150439 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
150440 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
150441 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
150442 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
150443 +} ioc_fm_pcd_extract_by_hdr_type;
150444 +
150445 +/**************************************************************************//**
150446 + @Description An enum for selecting extraction source (when it is not the header)
150447 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
150448 +*//***************************************************************************/
150449 +typedef enum ioc_fm_pcd_extract_from {
150450 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
150451 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
150452 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
150453 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
150454 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
150455 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
150456 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
150457 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
150458 +} ioc_fm_pcd_extract_from;
150459 +
150460 +/**************************************************************************//**
150461 + @Description An enum for selecting extraction type
150462 +*//***************************************************************************/
150463 +typedef enum ioc_fm_pcd_extract_type {
150464 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
150465 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
150466 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
150467 +} ioc_fm_pcd_extract_type;
150468 +
150469 +/**************************************************************************//**
150470 + @Description An enum for selecting a default
150471 +*//***************************************************************************/
150472 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
150473 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
150474 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
150475 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
150476 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
150477 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
150478 +} ioc_fm_pcd_kg_extract_dflt_select;
150479 +
150480 +/**************************************************************************//**
150481 + @Description Enumeration type defining all default groups - each group shares
150482 + a default value, one of four user-initialized values.
150483 +*//***************************************************************************/
150484 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
150485 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
150486 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
150487 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
150488 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
150489 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
150490 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
150491 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
150492 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
150493 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
150494 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
150495 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
150496 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
150497 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
150498 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
150499 + any data extraction that is not the full
150500 + field described above */
150501 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
150502 + any data extraction without validation */
150503 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
150504 + extraction from parser result or
150505 + direct use of default value */
150506 +} ioc_fm_pcd_kg_known_fields_dflt_types;
150507 +
150508 +/**************************************************************************//**
150509 + @Description Enumeration type for defining header index for scenarios with
150510 + multiple (tunneled) headers
150511 +*//***************************************************************************/
150512 +typedef enum ioc_fm_pcd_hdr_index {
150513 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
150514 + to specify regular IP (not tunneled). */
150515 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
150516 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
150517 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
150518 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
150519 +} ioc_fm_pcd_hdr_index;
150520 +
150521 +/**************************************************************************//**
150522 + @Description Enumeration type for selecting the policer profile functional type
150523 +*//***************************************************************************/
150524 +typedef enum ioc_fm_pcd_profile_type_selection {
150525 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
150526 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
150527 +} ioc_fm_pcd_profile_type_selection;
150528 +
150529 +/**************************************************************************//**
150530 + @Description Enumeration type for selecting the policer profile algorithm
150531 +*//***************************************************************************/
150532 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
150533 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
150534 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
150535 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
150536 +} ioc_fm_pcd_plcr_algorithm_selection;
150537 +
150538 +/**************************************************************************//**
150539 + @Description Enumeration type for selecting a policer profile color mode
150540 +*//***************************************************************************/
150541 +typedef enum ioc_fm_pcd_plcr_color_mode {
150542 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
150543 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
150544 +} ioc_fm_pcd_plcr_color_mode;
150545 +
150546 +/**************************************************************************//**
150547 + @Description Enumeration type for selecting a policer profile color
150548 +*//***************************************************************************/
150549 +typedef enum ioc_fm_pcd_plcr_color {
150550 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
150551 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
150552 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
150553 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
150554 +} ioc_fm_pcd_plcr_color;
150555 +
150556 +/**************************************************************************//**
150557 + @Description Enumeration type for selecting the policer profile packet frame length selector
150558 +*//***************************************************************************/
150559 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
150560 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
150561 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
150562 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
150563 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
150564 +} ioc_fm_pcd_plcr_frame_length_select;
150565 +
150566 +/**************************************************************************//**
150567 + @Description Enumeration type for selecting roll-back frame
150568 +*//***************************************************************************/
150569 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
150570 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
150571 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
150572 +} ioc_fm_pcd_plcr_roll_back_frame_select;
150573 +
150574 +/**************************************************************************//**
150575 + @Description Enumeration type for selecting the policer profile packet or byte mode
150576 +*//***************************************************************************/
150577 +typedef enum ioc_fm_pcd_plcr_rate_mode {
150578 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
150579 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
150580 +} ioc_fm_pcd_plcr_rate_mode;
150581 +
150582 +/**************************************************************************//**
150583 + @Description Enumeration type for defining action of frame
150584 +*//***************************************************************************/
150585 +typedef enum ioc_fm_pcd_done_action {
150586 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
150587 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
150588 +} ioc_fm_pcd_done_action;
150589 +
150590 +/**************************************************************************//**
150591 + @Description Enumeration type for selecting the policer counter
150592 +*//***************************************************************************/
150593 +typedef enum ioc_fm_pcd_plcr_profile_counters {
150594 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
150595 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
150596 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
150597 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
150598 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
150599 +} ioc_fm_pcd_plcr_profile_counters;
150600 +
150601 +/**************************************************************************//**
150602 + @Description Enumeration type for selecting the PCD action after extraction
150603 +*//***************************************************************************/
150604 +typedef enum ioc_fm_pcd_action {
150605 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
150606 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
150607 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
150608 +} ioc_fm_pcd_action;
150609 +
150610 +/**************************************************************************//**
150611 + @Description Enumeration type for selecting type of insert manipulation
150612 +*//***************************************************************************/
150613 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
150614 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
150615 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
150616 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150617 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
150618 +#endif /* FM_CAPWAP_SUPPORT */
150619 +} ioc_fm_pcd_manip_hdr_insrt_type;
150620 +
150621 +/**************************************************************************//**
150622 + @Description Enumeration type for selecting type of remove manipulation
150623 +*//***************************************************************************/
150624 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
150625 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
150626 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
150627 +} ioc_fm_pcd_manip_hdr_rmv_type;
150628 +
150629 +/**************************************************************************//**
150630 + @Description An enum for selecting specific L2 fields removal
150631 +*//***************************************************************************/
150632 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
150633 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
150634 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
150635 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
150636 + the header which follows the MPLS header */
150637 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
150638 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
150639 +
150640 +/**************************************************************************//**
150641 + @Description Enumeration type for selecting specific fields updates
150642 +*//***************************************************************************/
150643 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
150644 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
150645 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
150646 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
150647 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
150648 +} ioc_fm_pcd_manip_hdr_field_update_type;
150649 +
150650 +/**************************************************************************//**
150651 + @Description Enumeration type for selecting VLAN updates
150652 +*//***************************************************************************/
150653 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
150654 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
150655 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
150656 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
150657 +
150658 +/**************************************************************************//**
150659 + @Description Enumeration type for selecting specific L2 fields removal
150660 +*//***************************************************************************/
150661 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
150662 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
150663 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
150664 +
150665 +#if (DPAA_VERSION >= 11)
150666 +/**************************************************************************//**
150667 + @Description Enumeration type for selecting QoS mapping mode
150668 +
150669 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
150670 + User should instruct the port to read the parser-result
150671 +*//***************************************************************************/
150672 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
150673 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
150674 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
150675 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
150676 +
150677 +/**************************************************************************//**
150678 + @Description Enumeration type for selecting QoS source
150679 +
150680 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
150681 + User should left room for the parser-result on input/output buffer
150682 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
150683 +*//***************************************************************************/
150684 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
150685 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
150686 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
150687 +} ioc_fm_pcd_manip_hdr_qos_src;
150688 +#endif /* (DPAA_VERSION >= 11) */
150689 +
150690 +/**************************************************************************//**
150691 + @Description Enumeration type for selecting type of header insertion
150692 +*//***************************************************************************/
150693 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
150694 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
150695 +#if (DPAA_VERSION >= 11)
150696 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
150697 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
150698 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
150699 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
150700 +#endif /* (DPAA_VERSION >= 11) */
150701 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
150702 +
150703 +/**************************************************************************//**
150704 + @Description Enumeration type for selecting specific custom command
150705 +*//***************************************************************************/
150706 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
150707 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
150708 +} ioc_fm_pcd_manip_hdr_custom_type;
150709 +
150710 +/**************************************************************************//**
150711 + @Description Enumeration type for selecting specific custom command
150712 +*//***************************************************************************/
150713 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
150714 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
150715 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
150716 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
150717 +
150718 +/**************************************************************************//**
150719 + @Description Enumeration type for selecting type of header removal
150720 +*//***************************************************************************/
150721 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
150722 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
150723 +#if (DPAA_VERSION >= 11)
150724 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
150725 +#endif /* (DPAA_VERSION >= 11) */
150726 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
150727 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
150728 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
150729 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
150730 +
150731 +/**************************************************************************//**
150732 + @Description Enumeration type for selecting type of timeout mode
150733 +*//***************************************************************************/
150734 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
150735 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
150736 + from the first fragment to the last */
150737 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
150738 +} ioc_fm_pcd_manip_reassem_time_out_mode;
150739 +
150740 +/**************************************************************************//**
150741 + @Description Enumeration type for selecting type of WaysNumber mode
150742 +*//***************************************************************************/
150743 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
150744 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
150745 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
150746 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
150747 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
150748 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
150749 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
150750 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
150751 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
150752 +} ioc_fm_pcd_manip_reassem_ways_number;
150753 +
150754 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
150755 +/**************************************************************************//**
150756 + @Description Enumeration type for selecting type of statistics mode
150757 +*//***************************************************************************/
150758 +typedef enum ioc_fm_pcd_stats {
150759 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
150760 +} ioc_fm_pcd_stats;
150761 +#endif
150762 +
150763 +/**************************************************************************//**
150764 + @Description Enumeration type for selecting manipulation type
150765 +*//***************************************************************************/
150766 +typedef enum ioc_fm_pcd_manip_type {
150767 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
150768 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
150769 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
150770 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
150771 +} ioc_fm_pcd_manip_type;
150772 +
150773 +/**************************************************************************//**
150774 + @Description Enumeration type for selecting type of statistics mode
150775 +*//***************************************************************************/
150776 +typedef enum ioc_fm_pcd_cc_stats_mode {
150777 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
150778 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
150779 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
150780 +#if (DPAA_VERSION >= 11)
150781 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
150782 +#endif /* (DPAA_VERSION >= 11) */
150783 +} ioc_fm_pcd_cc_stats_mode;
150784 +
150785 +/**************************************************************************//**
150786 + @Description Enumeration type for determining the action in case an IP packet
150787 + is larger than MTU but its DF (Don't Fragment) bit is set.
150788 +*//***************************************************************************/
150789 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
150790 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
150791 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
150792 + /**< Obsolete, cannot enqueue to error queue;
150793 + In practice, selects to discard packets;
150794 + Will be removed in the future */
150795 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
150796 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
150797 +} ioc_fm_pcd_manip_dont_frag_action;
150798 +
150799 +/**************************************************************************//**
150800 + @Description Enumeration type for selecting type of special offload manipulation
150801 +*//***************************************************************************/
150802 +typedef enum ioc_fm_pcd_manip_special_offload_type {
150803 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
150804 +#if (DPAA_VERSION >= 11)
150805 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
150806 +#endif /* (DPAA_VERSION >= 11) */
150807 +} ioc_fm_pcd_manip_special_offload_type;
150808 +
150809 +/**************************************************************************//**
150810 + @Description A union of protocol dependent special options
150811 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
150812 +*//***************************************************************************/
150813 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
150814 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
150815 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
150816 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
150817 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
150818 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
150819 +#if (DPAA_VERSION >= 11)
150820 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
150821 +#endif /* (DPAA_VERSION >= 11) */
150822 +} ioc_fm_pcd_hdr_protocol_opt_u;
150823 +
150824 +/**************************************************************************//**
150825 + @Description A union holding all known protocol fields
150826 +*//***************************************************************************/
150827 +typedef union ioc_fm_pcd_fields_u {
150828 + ioc_header_field_eth_t eth; /**< Ethernet */
150829 + ioc_header_field_vlan_t vlan; /**< VLAN */
150830 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
150831 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
150832 + ioc_header_field_mpls_t mpls; /**< MPLS */
150833 + ioc_header_field_ip_t ip; /**< IP */
150834 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
150835 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
150836 + ioc_header_field_udp_t udp; /**< UDP */
150837 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
150838 + ioc_header_field_tcp_t tcp; /**< TCP */
150839 + ioc_header_field_sctp_t sctp; /**< SCTP */
150840 + ioc_header_field_dccp_t dccp; /**< DCCP */
150841 + ioc_header_field_gre_t gre; /**< GRE */
150842 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
150843 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
150844 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
150845 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
150846 +} ioc_fm_pcd_fields_u;
150847 +
150848 +/**************************************************************************//**
150849 + @Description Parameters for defining header extraction for key generation
150850 +*//***************************************************************************/
150851 +typedef struct ioc_fm_pcd_from_hdr_t {
150852 + uint8_t size; /**< Size in byte */
150853 + uint8_t offset; /**< Byte offset */
150854 +} ioc_fm_pcd_from_hdr_t;
150855 +
150856 +/**************************************************************************//**
150857 + @Description Parameters for defining field extraction for key generation
150858 +*//***************************************************************************/
150859 +typedef struct ioc_fm_pcd_from_field_t {
150860 + ioc_fm_pcd_fields_u field; /**< Field selection */
150861 + uint8_t size; /**< Size in byte */
150862 + uint8_t offset; /**< Byte offset */
150863 +} ioc_fm_pcd_from_field_t;
150864 +
150865 +/**************************************************************************//**
150866 + @Description Parameters for defining a single network environment unit
150867 + A distinction unit should be defined if it will later be used
150868 + by one or more PCD engines to distinguish between flows.
150869 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
150870 +*//***************************************************************************/
150871 +typedef struct ioc_fm_pcd_distinction_unit_t {
150872 + struct {
150873 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
150874 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
150875 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
150876 +} ioc_fm_pcd_distinction_unit_t;
150877 +
150878 +/**************************************************************************//**
150879 + @Description Parameters for defining all different distinction units supported
150880 + by a specific PCD Network Environment Characteristics module.
150881 +
150882 + Each unit represent a protocol or a group of protocols that may
150883 + be used later by the different PCD engines to distinguish between flows.
150884 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
150885 +*//***************************************************************************/
150886 +typedef struct ioc_fm_pcd_net_env_params_t {
150887 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
150888 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
150889 + /**< An array of num_of_distinction_units of the
150890 + different units to be identified */
150891 + void *id; /**< Output parameter; Returns the net-env Id to be used */
150892 +} ioc_fm_pcd_net_env_params_t;
150893 +
150894 +/**************************************************************************//**
150895 + @Description Parameters for defining a single extraction action when
150896 + creating a key
150897 +*//***************************************************************************/
150898 +typedef struct ioc_fm_pcd_extract_entry_t {
150899 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150900 + union {
150901 + struct {
150902 + ioc_net_header_type hdr; /**< Header selection */
150903 + bool ignore_protocol_validation;
150904 + /**< Ignore protocol validation */
150905 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150906 + IP. Otherwise should be cleared.*/
150907 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
150908 + union {
150909 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
150910 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
150911 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
150912 + } extract_by_hdr_type;
150913 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150914 + struct {
150915 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
150916 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
150917 + uint16_t ic_indx_mask; /**< Relevant only for CC when
150918 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
150919 + Note that the number of bits that are set within
150920 + this mask must be log2 of the CC-node 'num_of_keys'.
150921 + Note that the mask cannot be set on the lower bits. */
150922 + uint8_t offset; /**< Byte offset */
150923 + uint8_t size; /**< Size in bytes */
150924 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150925 + } extract_params;
150926 +} ioc_fm_pcd_extract_entry_t;
150927 +
150928 +/**************************************************************************//**
150929 + @Description A structure for defining masks for each extracted
150930 + field in the key.
150931 +*//***************************************************************************/
150932 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
150933 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
150934 + uint8_t offset; /**< Byte offset */
150935 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
150936 +} ioc_fm_pcd_kg_extract_mask_t;
150937 +
150938 +/**************************************************************************//**
150939 + @Description A structure for defining default selection per groups
150940 + of fields
150941 +*//***************************************************************************/
150942 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
150943 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
150944 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
150945 +} ioc_fm_pcd_kg_extract_dflt_t;
150946 +
150947 +
150948 +/**************************************************************************//**
150949 + @Description A structure for defining all parameters needed for
150950 + generation a key and using a hash function
150951 +*//***************************************************************************/
150952 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
150953 + uint32_t private_dflt0; /**< Scheme default register 0 */
150954 + uint32_t private_dflt1; /**< Scheme default register 1 */
150955 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
150956 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
150957 + /**< An array of extraction definitions. */
150958 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
150959 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
150960 + /**< For each extraction used in this scheme, specify the required
150961 + default register to be used when header is not found.
150962 + types not specified in this array will get undefined value. */
150963 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
150964 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
150965 + uint8_t hash_shift; /**< Hash result right shift.
150966 + Selects the 24 bits out of the 64 hash result.
150967 + 0 means using the 24 LSB's, otherwise use the
150968 + 24 LSB's after shifting right.*/
150969 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
150970 + of queues for the key and hash functionality */
150971 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
150972 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
150973 + destination fields on all layers; If TRUE, driver will check that for
150974 + all layers, if SRC extraction is selected, DST extraction must also be
150975 + selected, and vice versa. */
150976 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
150977 +
150978 +/**************************************************************************//**
150979 + @Description A structure of parameters for defining a single
150980 + Qid mask (extracted OR).
150981 +*//***************************************************************************/
150982 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
150983 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
150984 + union {
150985 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
150986 + ioc_net_header_type hdr;
150987 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
150988 + IP. Otherwise should be cleared.*/
150989 + bool ignore_protocol_validation;
150990 +
150991 + } extract_by_hdr;
150992 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
150993 + } extract_params;
150994 + uint8_t extraction_offset; /**< Offset for extraction */
150995 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
150996 + field not found */
150997 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
150998 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
150999 + the extracted byte; Assume byte is placed as the 8 MSB's in
151000 + a 32 bit word where the lower bits
151001 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
151002 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
151003 + extracted byte will effect the 8 LSB's of the FQID,
151004 + if bitOffsetInFqid=31 than the byte's MSB will effect
151005 + the FQID's LSB; 0 means - no effect on FQID;
151006 + Note that one, and only one of
151007 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151008 + extracted byte must effect either FQID or Policer profile).*/
151009 + uint8_t bit_offset_in_plcr_profile;
151010 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
151011 + effect using the extracted byte; Assume byte is placed
151012 + as the 8 MSB's in a 16 bit word where the lower bits
151013 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
151014 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
151015 + than the extracted byte will effect the whole policer profile id,
151016 + if bitOffsetInFqid=15 than the byte's MSB will effect
151017 + the Policer Profile id's LSB;
151018 + 0 means - no effect on policer profile; Note that one, and only one of
151019 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
151020 + extracted byte must effect either FQID or Policer profile).*/
151021 +} ioc_fm_pcd_kg_extracted_or_params_t;
151022 +
151023 +/**************************************************************************//**
151024 + @Description A structure for configuring scheme counter
151025 +*//***************************************************************************/
151026 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
151027 + bool update; /**< FALSE to keep the current counter state
151028 + and continue from that point, TRUE to update/reset
151029 + the counter when the scheme is written. */
151030 + uint32_t value; /**< If update=TRUE, this value will be written into the
151031 + counter; clear this field to reset the counter. */
151032 +} ioc_fm_pcd_kg_scheme_counter_t;
151033 +
151034 +
151035 +/**************************************************************************//**
151036 + @Description A structure for retrieving FMKG_SE_SPC
151037 +*//***************************************************************************/
151038 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
151039 + uint32_t val; /**< return value */
151040 + void *id; /**< scheme handle */
151041 +} ioc_fm_pcd_kg_scheme_spc_t;
151042 +
151043 +/**************************************************************************//**
151044 + @Description A structure for defining policer profile parameters as required by keygen
151045 + (when policer is the next engine after this scheme).
151046 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
151047 +*//***************************************************************************/
151048 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
151049 + bool shared_profile; /**< TRUE if this profile is shared between ports
151050 + (i.e. managed by master partition) May not be TRUE
151051 + if profile is after Coarse Classification*/
151052 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
151053 + id, if FALSE fqid_offset_relative_profile_id_base is used
151054 + together with fqid_offset_shift and num_of_profiles
151055 + parameters, to define a range of profiles from
151056 + which the KeyGen result will determine the
151057 + destination policer profile. */
151058 + union {
151059 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
151060 + This parameter should indicate the policer profile offset within the port's
151061 + policer profiles or SHARED window. */
151062 + struct {
151063 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
151064 + uint8_t fqid_offset_relative_profile_id_base;
151065 + /**< OR of KG results without the qid base
151066 + This parameter should indicate the policer profile
151067 + offset within the port's policer profiles window
151068 + or SHARED window depends on shared_profile */
151069 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
151070 + } indirect_profile; /**< Indirect profile parameters */
151071 + } profile_select; /**< Direct/indirect profile selection and parameters */
151072 +} ioc_fm_pcd_kg_plcr_profile_t;
151073 +
151074 +#if DPAA_VERSION >= 11
151075 +/**************************************************************************//**
151076 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
151077 +*//***************************************************************************/
151078 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
151079 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
151080 + profile id;
151081 + If FALSE, fqidOffsetRelativeProfileIdBase is used
151082 + together with fqidOffsetShift and numOfProfiles
151083 + parameters to define a range of profiles from which
151084 + the KeyGen result will determine the destination
151085 + storage profile. */
151086 + union {
151087 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
151088 + should indicate the storage profile offset within the
151089 + port's storage profiles window. */
151090 + struct {
151091 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
151092 + uint8_t fqid_offset_relative_profile_id_base;
151093 + /**< OR of KeyGen results without the FQID base;
151094 + should indicate the policer profile offset within the
151095 + port's storage profiles window. */
151096 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
151097 + } indirect_profile; /**< Indirect profile parameters. */
151098 + } profile_select; /**< Direct/indirect profile selection and parameters. */
151099 +} ioc_fm_pcd_kg_storage_profile_t;
151100 +#endif /* DPAA_VERSION >= 11 */
151101 +
151102 +/**************************************************************************//**
151103 + @Description Parameters for defining CC as the next engine after KeyGen
151104 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
151105 +*//***************************************************************************/
151106 +typedef struct ioc_fm_pcd_kg_cc_t {
151107 + void *tree_id; /**< CC Tree id */
151108 + uint8_t grp_id; /**< CC group id within the CC tree */
151109 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
151110 + policing is required. */
151111 + bool bypass_plcr_profile_generation;
151112 + /**< TRUE to bypass KeyGen policer profile generation;
151113 + selected profile is the one set at port initialization. */
151114 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
151115 + bypass_plcr_profile_generation = FALSE */
151116 +} ioc_fm_pcd_kg_cc_t;
151117 +
151118 +/**************************************************************************//**
151119 + @Description Parameters for defining initializing a KeyGen scheme
151120 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
151121 +*//***************************************************************************/
151122 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
151123 + bool modify; /**< TRUE to change an existing scheme */
151124 + union {
151125 + uint8_t relative_scheme_id;
151126 + /**< if modify=FALSE: partition-relative scheme id */
151127 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
151128 + } scm_id;
151129 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
151130 + for match vector; KeyGen will ignore it when matching */
151131 + struct { /**< HL relevant only if always_direct=FALSE */
151132 + void *net_env_id; /**< The id of the Network Environment as returned
151133 + by FM_PCD_NetEnvCharacteristicsSet() */
151134 + uint8_t num_of_distinction_units;
151135 + /**< Number of NetEnv units listed in unit_ids array */
151136 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
151137 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
151138 + } net_env_params;
151139 + bool use_hash; /**< use the KG Hash functionality */
151140 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
151141 + /**< used only if useHash = TRUE */
151142 + bool bypass_fqid_generation;
151143 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
151144 + In such a case FQID after KG will be the default FQID
151145 + defined for the relevant port, or the FQID defined by CC
151146 + in cases where CC was the previous engine. */
151147 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
151148 + If hash is used and an even distribution is expected
151149 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
151150 + hash_distribution_num_of_fqids. */
151151 + uint8_t num_of_used_extracted_ors;
151152 + /**< Number of FQID masks listed in extracted_ors array*/
151153 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
151154 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
151155 + registers are shared between qid_masks
151156 + functionality and some of the extraction
151157 + actions; Normally only some will be used
151158 + for qid_mask. Driver will return error if
151159 + resource is full at initialization time. */
151160 +#if DPAA_VERSION >= 11
151161 + bool override_storage_profile;
151162 + /**< TRUE if KeyGen override previously decided storage profile */
151163 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
151164 +#endif /* DPAA_VERSION >= 11 */
151165 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
151166 + union { /**< depends on nextEngine */
151167 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
151168 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
151169 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
151170 + } kg_next_engine_params;
151171 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
151172 + the scheme counter */
151173 + void *id; /**< Returns the scheme Id to be used */
151174 +} ioc_fm_pcd_kg_scheme_params_t;
151175 +
151176 +/**************************************************************************//**
151177 + @Collection
151178 +*//***************************************************************************/
151179 +#if DPAA_VERSION >= 11
151180 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
151181 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
151182 +#endif /* DPAA_VERSION >= 11 */
151183 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
151184 +/* @} */
151185 +
151186 +/**************************************************************************//**
151187 + @Description Parameters for defining CC as the next engine after a CC node.
151188 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
151189 +*//***************************************************************************/
151190 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
151191 + void *cc_node_id; /**< Id of the next CC node */
151192 +} ioc_fm_pcd_cc_next_cc_params_t;
151193 +
151194 +#if DPAA_VERSION >= 11
151195 +/**************************************************************************//**
151196 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
151197 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
151198 +*//***************************************************************************/
151199 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
151200 + void* frm_replic_id; /**< The id of the next frame replicator group */
151201 +} ioc_fm_pcd_cc_next_fr_params_t;
151202 +#endif /* DPAA_VERSION >= 11 */
151203 +
151204 +/**************************************************************************//**
151205 + @Description A structure for defining PLCR params when PLCR is the
151206 + next engine after a CC node
151207 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
151208 +*//***************************************************************************/
151209 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
151210 + bool override_params; /**< TRUE if CC override previously decided parameters*/
151211 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
151212 + TRUE if this profile is shared between ports */
151213 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
151214 + (otherwise profile id is taken from keygen);
151215 + This parameter should indicate the policer
151216 + profile offset within the port's
151217 + policer profiles or from SHARED window.*/
151218 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
151219 + FQID for enquing the frame;
151220 + In earlier chips if policer next engine is KEYGEN,
151221 + this parameter can be 0, because the KEYGEN always decides
151222 + the enqueue FQID.*/
151223 +#if DPAA_VERSION >= 11
151224 + uint8_t new_relative_storage_profile_id;
151225 + /**< Indicates the relative storage profile offset within
151226 + the port's storage profiles window;
151227 + Relevant only if the port was configured with VSP. */
151228 +#endif /* DPAA_VERSION >= 11 */
151229 +} ioc_fm_pcd_cc_next_plcr_params_t;
151230 +
151231 +/**************************************************************************//**
151232 + @Description A structure for defining enqueue params when BMI is the
151233 + next engine after a CC node
151234 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
151235 +*//***************************************************************************/
151236 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
151237 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151238 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151239 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
151240 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151241 + (otherwise FQID is taken from KeyGen),
151242 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
151243 +#if DPAA_VERSION >= 11
151244 + uint8_t new_relative_storage_profile_id;
151245 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151246 + storage profile offset within the port's storage profiles
151247 + window; Relevant only if the port was configured with VSP. */
151248 +#endif /* DPAA_VERSION >= 11 */
151249 +
151250 +} ioc_fm_pcd_cc_next_enqueue_params_t;
151251 +
151252 +/**************************************************************************//**
151253 + @Description A structure for defining KG params when KG is the next engine after a CC node
151254 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
151255 +*//***************************************************************************/
151256 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
151257 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
151258 + Note - this parameters are irrelevant for earlier chips */
151259 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
151260 + (otherwise FQID is taken from KeyGen),
151261 + Note - this parameters are irrelevant for earlier chips */
151262 +#if DPAA_VERSION >= 11
151263 + uint8_t new_relative_storage_profile_id;
151264 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
151265 + storage profile offset within the port's storage profiles
151266 + window; Relevant only if the port was configured with VSP. */
151267 +#endif /* DPAA_VERSION >= 11 */
151268 + void *p_direct_scheme; /**< Direct scheme id to go to. */
151269 +} ioc_fm_pcd_cc_next_kg_params_t;
151270 +
151271 +/**************************************************************************//**
151272 + @Description Parameters for defining the next engine after a CC node.
151273 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
151274 +*//***************************************************************************/
151275 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
151276 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
151277 + according to nextEngine definition */
151278 + union {
151279 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
151280 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
151281 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
151282 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
151283 +#if DPAA_VERSION >= 11
151284 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
151285 +#endif /* DPAA_VERSION >= 11 */
151286 + } params; /**< Union used for all the next-engine parameters options */
151287 + void *manip_id; /**< Handle to Manipulation object.
151288 + Relevant if next engine is of type result
151289 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
151290 + bool statistics_en; /**< If TRUE, statistics counters are incremented
151291 + for each frame passing through this
151292 + Coarse Classification entry. */
151293 +} ioc_fm_pcd_cc_next_engine_params_t;
151294 +
151295 +/**************************************************************************//**
151296 + @Description Parameters for defining a single CC key
151297 +*//***************************************************************************/
151298 +typedef struct ioc_fm_pcd_cc_key_params_t {
151299 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
151300 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
151301 + in keySize. p_key and p_mask (if defined) has to be
151302 + of the same size defined in the key_size */
151303 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151304 + /**< parameters for the next for the defined Key in p_key */
151305 +
151306 +} ioc_fm_pcd_cc_key_params_t;
151307 +
151308 +/**************************************************************************//**
151309 + @Description Parameters for defining CC keys parameters
151310 + The driver supports two methods for CC node allocation: dynamic and static.
151311 + Static mode was created in order to prevent runtime alloc/free
151312 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
151313 + the driver automatically allocates the memory according to
151314 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
151315 + size that may be used for this CC-Node taking into consideration
151316 + 'mask_support' and 'statistics_mode' parameters.
151317 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
151318 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
151319 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
151320 + all required structures are allocated according to 'num_of_keys'
151321 + parameter. During runtime modification, these structures are
151322 + re-allocated according to the updated number of keys.
151323 +
151324 + Please note that 'action' and 'ic_indx_mask' mentioned in the
151325 + specific parameter explanations are passed in the extraction
151326 + parameters of the node (fields of extractccparams.extractnonhdr).
151327 +*//***************************************************************************/
151328 +typedef struct ioc_keys_params_t {
151329 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
151330 + A value of zero may be used for dynamic memory allocation. */
151331 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
151332 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
151333 + Should be TRUE to reserve table memory for key masks, even if
151334 + initial keys do not contain masks, or if the node was initialized
151335 + as 'empty' (without keys); this will allow user to add keys with
151336 + masks at runtime. */
151337 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
151338 + To enable statistics gathering, statistics should be enabled per
151339 + every key, using 'statistics_en' in next engine parameters structure
151340 + of that key;
151341 + If 'max_num_of_keys' is set, all required structures will be
151342 + preallocated for all keys. */
151343 +#if (DPAA_VERSION >= 11)
151344 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
151345 + /**< Relevant only for 'RMON' statistics mode
151346 + (this feature is supported only on B4860 device);
151347 + Holds a list of programmable thresholds. For each received frame,
151348 + its length in bytes is examined against these range thresholds and
151349 + the appropriate counter is incremented by 1. For example, to belong
151350 + to range i, the following should hold:
151351 + range i-1 threshold < frame length <= range i threshold
151352 + Each range threshold must be larger then its preceding range
151353 + threshold. Last range threshold must be 0xFFFF. */
151354 +#endif /* (DPAA_VERSION >= 11) */
151355 + uint16_t num_of_keys; /**< Number of initial keys;
151356 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
151357 + this field should be power-of-2 of the number of bits that are
151358 + set in 'ic_indx_mask'. */
151359 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
151360 + to be the standard size of the selected key; For other extraction
151361 + types, 'key_size' has to be as size of extraction; When 'action' =
151362 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
151363 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
151364 + /**< An array with 'num_of_keys' entries, each entry specifies the
151365 + corresponding key parameters;
151366 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
151367 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
151368 + for the 'miss' entry. */
151369 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151370 + /**< Parameters for defining the next engine when a key is not matched;
151371 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
151372 +} ioc_keys_params_t;
151373 +
151374 +/**************************************************************************//**
151375 + @Description Parameters for defining a CC node
151376 +*//***************************************************************************/
151377 +typedef struct ioc_fm_pcd_cc_node_params_t {
151378 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
151379 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
151380 + void *id; /**< Output parameter; returns the CC node Id to be used */
151381 +} ioc_fm_pcd_cc_node_params_t;
151382 +
151383 +/**************************************************************************//**
151384 + @Description Parameters for defining a hash table
151385 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
151386 +*//***************************************************************************/
151387 +typedef struct ioc_fm_pcd_hash_table_params_t {
151388 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
151389 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
151390 + requested statistics mode will be allocated according to max_num_of_keys. */
151391 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
151392 + that leads to this hash-table. */
151393 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
151394 + The number-of-sets for this hash will be calculated
151395 + as (2^(number of bits set in 'hash_res_mask'));
151396 + The 4 lower bits must be cleared. */
151397 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
151398 + 2-bytes to be used as hash index. */
151399 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
151400 +
151401 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
151402 + /**< Parameters for defining the next engine when a key is not matched */
151403 + void *id;
151404 +} ioc_fm_pcd_hash_table_params_t;
151405 +
151406 +/**************************************************************************//**
151407 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
151408 +*//***************************************************************************/
151409 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
151410 + void *p_hash_tbl;
151411 + uint8_t key_size;
151412 + ioc_fm_pcd_cc_key_params_t key_params;
151413 +} ioc_fm_pcd_hash_table_add_key_params_t;
151414 +
151415 +/**************************************************************************//**
151416 + @Description Parameters for defining a CC tree group.
151417 +
151418 + This structure defines a CC group in terms of NetEnv units
151419 + and the action to be taken in each case. The unit_ids list must
151420 + be given in order from low to high indices.
151421 +
151422 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
151423 + structures where each defines the next action to be taken for
151424 + each units combination. for example:
151425 + num_of_distinction_units = 2
151426 + unit_ids = {1,3}
151427 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151428 + unit 1 - not found; unit 3 - not found;
151429 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151430 + unit 1 - not found; unit 3 - found;
151431 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151432 + unit 1 - found; unit 3 - not found;
151433 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
151434 + unit 1 - found; unit 3 - found;
151435 +*//***************************************************************************/
151436 +typedef struct ioc_fm_pcd_cc_grp_params_t {
151437 + uint8_t num_of_distinction_units; /**< Up to 4 */
151438 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
151439 + /**< Indexes of the units as defined in
151440 + FM_PCD_NetEnvCharacteristicsSet() */
151441 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
151442 + /**< Maximum entries per group is 16 */
151443 +} ioc_fm_pcd_cc_grp_params_t;
151444 +
151445 +/**************************************************************************//**
151446 + @Description Parameters for defining the CC tree groups
151447 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
151448 +*//***************************************************************************/
151449 +typedef struct ioc_fm_pcd_cc_tree_params_t {
151450 + void *net_env_id; /**< Id of the Network Environment as returned
151451 + by FM_PCD_NetEnvCharacteristicsSet() */
151452 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
151453 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
151454 + /**< Parameters for each group. */
151455 + void *id; /**< Output parameter; Returns the tree Id to be used */
151456 +} ioc_fm_pcd_cc_tree_params_t;
151457 +
151458 +/**************************************************************************//**
151459 + @Description Parameters for defining policer byte rate
151460 +*//***************************************************************************/
151461 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
151462 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
151463 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
151464 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
151465 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
151466 +
151467 +/**************************************************************************//**
151468 + @Description Parameters for defining the policer profile (based on
151469 + RFC-2698 or RFC-4115 attributes).
151470 +*//***************************************************************************/
151471 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
151472 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
151473 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
151474 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
151475 + uint32_t committed_burst_size; /**< KBits or Packets */
151476 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
151477 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
151478 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
151479 +
151480 +/**************************************************************************//**
151481 + @Description Parameters for defining the next engine after policer
151482 +*//***************************************************************************/
151483 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
151484 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
151485 + void *p_profile; /**< Policer profile handle - used when next engine
151486 + is PLCR, must be a SHARED profile */
151487 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
151488 +} ioc_fm_pcd_plcr_next_engine_params_u;
151489 +
151490 +typedef struct ioc_fm_pcd_port_params_t {
151491 + ioc_fm_port_type port_type; /**< Type of port for this profile */
151492 + uint8_t port_id; /**< FM-Port id of port for this profile */
151493 +} ioc_fm_pcd_port_params_t;
151494 +
151495 +/**************************************************************************//**
151496 + @Description Parameters for defining the policer profile entry
151497 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
151498 +*//***************************************************************************/
151499 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
151500 + bool modify; /**< TRUE to change an existing profile */
151501 + union {
151502 + struct {
151503 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
151504 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
151505 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
151506 + } new_params; /**< Use it when modify = FALSE */
151507 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
151508 + } profile_select;
151509 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
151510 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
151511 +
151512 + union {
151513 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
151514 + any incoming packet with the default value. */
151515 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
151516 + pre-color value of 2'b11. */
151517 + } color;
151518 +
151519 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
151520 +
151521 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
151522 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
151523 +
151524 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
151525 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
151526 +
151527 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
151528 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
151529 +
151530 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
151531 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
151532 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
151533 +
151534 + void *id; /**< output parameter; Returns the profile Id to be used */
151535 +} ioc_fm_pcd_plcr_profile_params_t;
151536 +
151537 +/**************************************************************************//**
151538 + @Description A structure for modifying CC tree next engine
151539 +*//***************************************************************************/
151540 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
151541 + void *id; /**< CC tree Id to be used */
151542 + uint8_t grp_indx; /**< A Group index in the tree */
151543 + uint8_t indx; /**< Entry index in the group defined by grp_index */
151544 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151545 + /**< Parameters for the next for the defined Key in the p_Key */
151546 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
151547 +
151548 +/**************************************************************************//**
151549 + @Description A structure for modifying CC node next engine
151550 +*//***************************************************************************/
151551 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
151552 + void *id; /**< CC node Id to be used */
151553 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151554 + NOTE: This parameter is IGNORED for miss-key! */
151555 + uint8_t key_size; /**< Key size of added key */
151556 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
151557 + /**< parameters for the next for the defined Key in the p_Key */
151558 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
151559 +
151560 +/**************************************************************************//**
151561 + @Description A structure for remove CC node key
151562 +*//***************************************************************************/
151563 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
151564 + void *id; /**< CC node Id to be used */
151565 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151566 + NOTE: This parameter is IGNORED for miss-key! */
151567 +} ioc_fm_pcd_cc_node_remove_key_params_t;
151568 +
151569 +/**************************************************************************//**
151570 + @Description A structure for modifying CC node key and next engine
151571 +*//***************************************************************************/
151572 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
151573 + void *id; /**< CC node Id to be used */
151574 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151575 + NOTE: This parameter is IGNORED for miss-key! */
151576 + uint8_t key_size; /**< Key size of added key */
151577 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
151578 + the array of the type ioc_fm_pcd_cc_key_params_t */
151579 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
151580 +
151581 +/**************************************************************************//**
151582 + @Description A structure for modifying CC node key
151583 +*//***************************************************************************/
151584 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
151585 + void *id; /**< CC node Id to be used */
151586 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
151587 + NOTE: This parameter is IGNORED for miss-key! */
151588 + uint8_t key_size; /**< Key size of added key */
151589 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
151590 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
151591 + in keySize. p_Key and p_Mask (if defined) have to be
151592 + of the same size as defined in the key_size */
151593 +} ioc_fm_pcd_cc_node_modify_key_params_t;
151594 +
151595 +/**************************************************************************//**
151596 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
151597 +*//***************************************************************************/
151598 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
151599 + void *p_hash_tbl; /**< The id of the hash table */
151600 + uint8_t key_size; /**< The size of the key to remove */
151601 + uint8_t *p_key; /**< Pointer to the key to remove */
151602 +} ioc_fm_pcd_hash_table_remove_key_params_t;
151603 +
151604 +/**************************************************************************//**
151605 + @Description Parameters for selecting a location for requested manipulation
151606 +*//***************************************************************************/
151607 +typedef struct ioc_fm_manip_hdr_info_t {
151608 + ioc_net_header_type hdr; /**< Header selection */
151609 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
151610 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
151611 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
151612 +} ioc_fm_manip_hdr_info_t;
151613 +
151614 +/**************************************************************************//**
151615 + @Description Parameters for defining header removal by header type
151616 +*//***************************************************************************/
151617 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
151618 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
151619 + union {
151620 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
151621 + struct {
151622 + bool include;/**< If FALSE, remove until the specified header (not including the header);
151623 + If TRUE, remove also the specified header. */
151624 + ioc_fm_manip_hdr_info_t hdr_info;
151625 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151626 +#endif /* FM_CAPWAP_SUPPORT */
151627 +#if (DPAA_VERSION >= 11)
151628 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
151629 +#endif /* (DPAA_VERSION >= 11) */
151630 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
151631 + Defines which L2 headers to remove. */
151632 + } u;
151633 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
151634 +
151635 +/**************************************************************************//**
151636 + @Description Parameters for configuring IP fragmentation manipulation
151637 +*//***************************************************************************/
151638 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
151639 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151640 + IP fragmentation will be executed.*/
151641 +#if DPAA_VERSION == 10
151642 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
151643 +#endif /* DPAA_VERSION == 10 */
151644 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151645 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151646 + received frame's buffer. */
151647 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151648 + This parameter is relevant when 'sg_bpid_en=TRUE';
151649 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151650 + of this pool need to be allocated in the same memory area as the received buffers.
151651 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151652 + mutual to all these sources. */
151653 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
151654 + than MTU and its DF bit is set, then this field will
151655 + determine the action to be taken.*/
151656 +} ioc_fm_pcd_manip_frag_ip_params_t;
151657 +
151658 +/**************************************************************************//**
151659 + @Description Parameters for configuring IP reassembly manipulation.
151660 +
151661 + This is a common structure for both IPv4 and IPv6 reassembly
151662 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
151663 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
151664 +*//***************************************************************************/
151665 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
151666 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
151667 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
151668 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
151669 + NOTE: The following comment is relevant only for FMAN v2 devices:
151670 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
151671 + the user schemes id to ensure that the reassembly's schemes will be first match.
151672 + The remaining schemes, if defined, should have higher relative scheme ID. */
151673 +#if DPAA_VERSION >= 11
151674 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
151675 + profile than the opening fragment (Non-Consistent-SP state)
151676 + then one of two possible scenarios occurs:
151677 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
151678 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
151679 +#else
151680 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
151681 +#endif /* DPAA_VERSION >= 11 */
151682 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151683 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151684 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
151685 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
151686 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
151687 + /**< Number of frames per hash entry needed for reassembly process:
151688 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
151689 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
151690 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
151691 + Must be power of 2;
151692 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
151693 + maxNumFramesInProcess has to be in the range of 4 - 512;
151694 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151695 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151696 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151697 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
151698 + uint32_t timeout_threshold_for_reassm_process;
151699 + /**< Represents the time interval in microseconds which defines
151700 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151701 +} ioc_fm_pcd_manip_reassem_ip_params_t;
151702 +
151703 +/**************************************************************************//**
151704 + @Description Parameters for defining IPSEC manipulation
151705 +*//***************************************************************************/
151706 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
151707 + bool decryption; /**< TRUE if being used in decryption direction;
151708 + FALSE if being used in encryption direction. */
151709 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
151710 + (direction depends on the 'decryption' field). */
151711 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
151712 + (direction depends on the 'decryption' field). */
151713 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
151714 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
151715 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
151716 + It is specifies the length of the outer IP header that was configured in the
151717 + corresponding SA. */
151718 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
151719 + The value must be a multiplication of 16 */
151720 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
151721 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
151722 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
151723 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
151724 +
151725 +#if (DPAA_VERSION >= 11)
151726 +/**************************************************************************//**
151727 + @Description Parameters for configuring CAPWAP fragmentation manipulation
151728 +
151729 + Restrictions:
151730 + - Maximum number of fragments per frame is 16.
151731 + - Transmit confirmation is not supported.
151732 + - Fragmentation nodes must be set as the last PCD action (i.e. the
151733 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
151734 + - Only BMan buffers shall be used for frames to be fragmented.
151735 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
151736 + does not support VSP. Therefore, on the same port where we have IPF we
151737 + cannot support VSP.
151738 +*//***************************************************************************/
151739 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
151740 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
151741 + CAPWAP fragmentation will be executed.*/
151742 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
151743 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
151744 + received frame's buffer. */
151745 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
151746 + This parameters is relevant when 'sgBpidEn=TRUE';
151747 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
151748 + of this pool need to be allocated in the same memory area as the received buffers.
151749 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
151750 + mutual to all these sources. */
151751 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
151752 + When this mode is enabled then only the first fragment include the CAPWAP header options
151753 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
151754 + options field (CAPWAP header is updated accordingly).*/
151755 +} ioc_fm_pcd_manip_frag_capwap_params_t;
151756 +
151757 +/**************************************************************************//**
151758 + @Description Parameters for configuring CAPWAP reassembly manipulation.
151759 +
151760 + Restrictions:
151761 + - Application must define one scheme to catch the reassembled frames.
151762 + - Maximum number of fragments per frame is 16.
151763 +
151764 +*//***************************************************************************/
151765 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
151766 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
151767 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
151768 + Rest schemes, if defined, should have higher relative scheme ID. */
151769 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
151770 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
151771 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
151772 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
151773 + considered as a valid length;
151774 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
151775 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
151776 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
151777 + /**< Number of frames per hash entry needed for reassembly process */
151778 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
151779 + Must be power of 2;
151780 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
151781 + maxNumFramesInProcess has to be in the range of 4 - 512;
151782 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
151783 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
151784 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
151785 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
151786 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
151787 + uint32_t timeout_threshold_for_reassm_process;
151788 + /**< Represents the time interval in microseconds which defines
151789 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
151790 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
151791 +
151792 +/**************************************************************************//**
151793 + @Description structure for defining CAPWAP manipulation
151794 +*//***************************************************************************/
151795 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
151796 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
151797 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
151798 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
151799 +
151800 +#endif /* (DPAA_VERSION >= 11) */
151801 +
151802 +/**************************************************************************//**
151803 + @Description Parameters for defining special offload manipulation
151804 +*//***************************************************************************/
151805 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
151806 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
151807 + union
151808 + {
151809 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
151810 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
151811 +
151812 +#if (DPAA_VERSION >= 11)
151813 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
151814 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
151815 +#endif /* (DPAA_VERSION >= 11) */
151816 + } u;
151817 +} ioc_fm_pcd_manip_special_offload_params_t;
151818 +
151819 +/**************************************************************************//**
151820 + @Description Parameters for defining generic removal manipulation
151821 +*//***************************************************************************/
151822 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
151823 + uint8_t offset; /**< Offset from beginning of header to the start
151824 + location of the removal */
151825 + uint8_t size; /**< Size of removed section */
151826 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
151827 +
151828 +/**************************************************************************//**
151829 + @Description Parameters for defining insertion manipulation
151830 +*//***************************************************************************/
151831 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
151832 + uint8_t size; /**< size of inserted section */
151833 + uint8_t *p_data; /**< data to be inserted */
151834 +} ioc_fm_pcd_manip_hdr_insrt_t;
151835 +
151836 +/**************************************************************************//**
151837 + @Description Parameters for defining generic insertion manipulation
151838 +*//***************************************************************************/
151839 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
151840 + uint8_t offset; /**< Offset from beginning of header to the start
151841 + location of the insertion */
151842 + uint8_t size; /**< Size of inserted section */
151843 + bool replace; /**< TRUE to override (replace) existing data at
151844 + 'offset', FALSE to insert */
151845 + uint8_t *p_data; /**< Pointer to data to be inserted */
151846 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
151847 +
151848 +/**************************************************************************//**
151849 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
151850 +*//***************************************************************************/
151851 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
151852 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
151853 + /**< A table of VPri values for each DSCP value;
151854 + The index is the D_SCP value (0-0x3F) and the
151855 + value is the corresponding VPRI (0-15). */
151856 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
151857 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
151858 + this field is the Q Tag default value if the
151859 + IP header is not found. */
151860 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
151861 +
151862 +/**************************************************************************//**
151863 + @Description Parameters for defining header manipulation VLAN fields updates
151864 +*//***************************************************************************/
151865 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
151866 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
151867 + union {
151868 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
151869 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
151870 + is the new VLAN pri. */
151871 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
151872 + /**< Parameters structure, Relevant only if update_type =
151873 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
151874 + } u;
151875 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
151876 +
151877 +/**************************************************************************//**
151878 + @Description Parameters for defining header manipulation IPV4 fields updates
151879 +*//***************************************************************************/
151880 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
151881 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151882 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
151883 + IOC_HDR_MANIP_IPV4_TOS */
151884 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
151885 + contains IOC_HDR_MANIP_IPV4_ID */
151886 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
151887 + contains IOC_HDR_MANIP_IPV4_SRC */
151888 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
151889 + contains IOC_HDR_MANIP_IPV4_DST */
151890 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
151891 +
151892 +/**************************************************************************//**
151893 + @Description Parameters for defining header manipulation IPV6 fields updates
151894 +*//***************************************************************************/
151895 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
151896 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151897 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
151898 + IOC_HDR_MANIP_IPV6_TC */
151899 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151900 + /**< 16 byte new IP SRC; Relevant only if valid_updates
151901 + contains IOC_HDR_MANIP_IPV6_SRC */
151902 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
151903 + /**< 16 byte new IP DST; Relevant only if valid_updates
151904 + contains IOC_HDR_MANIP_IPV6_DST */
151905 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
151906 +
151907 +/**************************************************************************//**
151908 + @Description Parameters for defining header manipulation TCP/UDP fields updates
151909 +*//***************************************************************************/
151910 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
151911 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
151912 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
151913 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
151914 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
151915 + contains IOC_HDR_MANIP_TCP_UDP_DST */
151916 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
151917 +
151918 +/**************************************************************************//**
151919 + @Description Parameters for defining header manipulation fields updates
151920 +*//***************************************************************************/
151921 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
151922 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
151923 + union {
151924 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
151925 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
151926 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
151927 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
151928 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
151929 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
151930 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
151931 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
151932 + } u;
151933 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
151934 +
151935 +/**************************************************************************//**
151936 + @Description Parameters for defining custom header manipulation for IP replacement
151937 +*//***************************************************************************/
151938 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
151939 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
151940 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
151941 + bool update_ipv4_id; /**< Relevant when replace_type =
151942 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
151943 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
151944 + update_ipv4_id = TRUE */
151945 + uint8_t hdr_size; /**< The size of the new IP header */
151946 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
151947 + /**< The new IP header */
151948 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
151949 +
151950 +/**************************************************************************//**
151951 + @Description Parameters for defining custom header manipulation
151952 +*//***************************************************************************/
151953 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
151954 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
151955 + union {
151956 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
151957 + /**< Parameters IP header replacement */
151958 + } u;
151959 +} ioc_fm_pcd_manip_hdr_custom_params_t;
151960 +
151961 +/**************************************************************************//**
151962 + @Description Parameters for defining specific L2 insertion manipulation
151963 +*//***************************************************************************/
151964 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
151965 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
151966 + bool update; /**< TRUE to update MPLS header */
151967 + uint8_t size; /**< size of inserted section */
151968 + uint8_t *p_data; /**< data to be inserted */
151969 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
151970 +
151971 +#if (DPAA_VERSION >= 11)
151972 +/**************************************************************************//**
151973 + @Description Parameters for defining IP insertion manipulation
151974 +*//***************************************************************************/
151975 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
151976 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
151977 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
151978 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
151979 + the inserted header */
151980 + uint16_t id; /**< 16 bit New IP ID */
151981 + bool dont_frag_overwrite;
151982 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
151983 + * This byte is configured to be overwritten when RPD is set. */
151984 + uint8_t last_dst_offset;
151985 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
151986 + * in order to calculate UDP checksum pseudo header;
151987 + * Otherwise set it to '0'. */
151988 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
151989 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
151990 +#endif /* (DPAA_VERSION >= 11) */
151991 +
151992 +/**************************************************************************//**
151993 + @Description Parameters for defining header insertion manipulation by header type
151994 +*//***************************************************************************/
151995 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
151996 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
151997 + union {
151998 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
151999 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
152000 + Selects which L2 headers to remove */
152001 +#if (DPAA_VERSION >= 11)
152002 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
152003 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
152004 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
152005 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
152006 +#endif /* (DPAA_VERSION >= 11) */
152007 + } u;
152008 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
152009 +
152010 +/**************************************************************************//**
152011 + @Description Parameters for defining header insertion manipulation
152012 +*//***************************************************************************/
152013 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
152014 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
152015 + union {
152016 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
152017 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
152018 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
152019 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
152020 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152021 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
152022 + /**< Parameters for defining header insertion manipulation by template,
152023 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
152024 +#endif /* FM_CAPWAP_SUPPORT */
152025 + } u;
152026 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
152027 +
152028 +/**************************************************************************//**
152029 + @Description Parameters for defining header removal manipulation
152030 +*//***************************************************************************/
152031 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
152032 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
152033 + union {
152034 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
152035 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
152036 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
152037 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
152038 + } u;
152039 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
152040 +
152041 +/**************************************************************************//**
152042 + @Description Parameters for defining header manipulation node
152043 +*//***************************************************************************/
152044 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
152045 + bool rmv; /**< TRUE, to define removal manipulation */
152046 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
152047 +
152048 + bool insrt; /**< TRUE, to define insertion manipulation */
152049 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
152050 +
152051 + bool field_update; /**< TRUE, to define field update manipulation */
152052 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
152053 +
152054 + bool custom; /**< TRUE, to define custom manipulation */
152055 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
152056 +
152057 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
152058 + completing the manipulation on the frame */
152059 +} ioc_fm_pcd_manip_hdr_params_t;
152060 +
152061 +
152062 +/**************************************************************************//**
152063 + @Description structure for defining fragmentation manipulation
152064 +*//***************************************************************************/
152065 +typedef struct ioc_fm_pcd_manip_frag_params_t {
152066 + ioc_net_header_type hdr; /**< Header selection */
152067 + union {
152068 +#if (DPAA_VERSION >= 11)
152069 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
152070 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152071 +#endif /* (DPAA_VERSION >= 11) */
152072 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
152073 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152074 + } u;
152075 +} ioc_fm_pcd_manip_frag_params_t;
152076 +
152077 +/**************************************************************************//**
152078 + @Description structure for defining reassemble manipulation
152079 +*//***************************************************************************/
152080 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
152081 + ioc_net_header_type hdr; /**< Header selection */
152082 + union {
152083 +#if (DPAA_VERSION >= 11)
152084 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
152085 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
152086 +#endif /* (DPAA_VERSION >= 11) */
152087 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
152088 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
152089 + } u;
152090 +} ioc_fm_pcd_manip_reassem_params_t;
152091 +
152092 +/**************************************************************************//**
152093 + @Description Parameters for defining a manipulation node
152094 +*//***************************************************************************/
152095 +typedef struct ioc_fm_pcd_manip_params_t {
152096 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
152097 + union {
152098 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
152099 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
152100 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
152101 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
152102 + } u;
152103 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
152104 + Allows concatenation of manipulation actions
152105 + This parameter is optional and may be NULL. */
152106 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152107 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
152108 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
152109 + relevant if frag_or_reasm = TRUE */
152110 +#endif /* FM_CAPWAP_SUPPORT */
152111 + void *id;
152112 +} ioc_fm_pcd_manip_params_t;
152113 +
152114 +/**************************************************************************//**
152115 + @Description Structure for retrieving IP reassembly statistics
152116 +*//***************************************************************************/
152117 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
152118 + /* common counters for both IPv4 and IPv6 */
152119 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
152120 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152121 + a Reassembly Frame Descriptor */
152122 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152123 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152124 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152125 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152126 +#if (DPAA_VERSION >= 11)
152127 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
152128 + successfully reassembled frames */
152129 +#endif /* (DPAA_VERSION >= 11) */
152130 +struct {
152131 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152132 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152133 + have been processed for all frames */
152134 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152135 + (valid and error fragments) for all frames */
152136 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152137 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152138 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
152139 + to access an IP-Reassembly Automatic Learning Hash set */
152140 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152141 + exceeds 16 */
152142 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
152143 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
152144 +
152145 +/**************************************************************************//**
152146 + @Description Structure for retrieving IP fragmentation statistics
152147 +*//***************************************************************************/
152148 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
152149 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152150 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152151 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152152 +} ioc_fm_pcd_manip_frag_ip_stats_t;
152153 +
152154 +#if (DPAA_VERSION >= 11)
152155 +/**************************************************************************//**
152156 + @Description Structure for retrieving CAPWAP reassembly statistics
152157 +*//***************************************************************************/
152158 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
152159 + uint32_t timeout; /**< Counts the number of timeout occurrences */
152160 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
152161 + a Reassembly Frame Descriptor */
152162 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
152163 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
152164 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
152165 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
152166 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
152167 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
152168 + have been processed for all frames */
152169 + uint32_t processed_fragments; /**< Counts the number of processed fragments
152170 + (valid and error fragments) for all frames */
152171 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
152172 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
152173 + to access an Reassembly Automatic Learning Hash set */
152174 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
152175 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
152176 + exceeds 16 */
152177 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
152178 + length exceeds MaxReassembledFrameLength value */
152179 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
152180 +
152181 +/**************************************************************************//**
152182 + @Description Structure for retrieving CAPWAP fragmentation statistics
152183 +*//***************************************************************************/
152184 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
152185 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
152186 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
152187 + uint32_t generated_fragments; /**< Number of fragments that were generated */
152188 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
152189 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
152190 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
152191 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
152192 +#endif /* (DPAA_VERSION >= 11) */
152193 +
152194 +/**************************************************************************//**
152195 + @Description Structure for retrieving reassembly statistics
152196 +*//***************************************************************************/
152197 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
152198 + union {
152199 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
152200 +#if (DPAA_VERSION >= 11)
152201 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
152202 +#endif /* (DPAA_VERSION >= 11) */
152203 + } u;
152204 +} ioc_fm_pcd_manip_reassem_stats_t;
152205 +
152206 +/**************************************************************************//**
152207 + @Description structure for retrieving fragmentation statistics
152208 +*//***************************************************************************/
152209 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
152210 + union {
152211 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
152212 +#if (DPAA_VERSION >= 11)
152213 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
152214 +#endif /* (DPAA_VERSION >= 11) */
152215 + } u;
152216 +} ioc_fm_pcd_manip_frag_stats_t;
152217 +
152218 +/**************************************************************************//**
152219 + @Description structure for defining manipulation statistics
152220 +*//***************************************************************************/
152221 +typedef struct ioc_fm_pcd_manip_stats_t {
152222 + union {
152223 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
152224 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
152225 + } u;
152226 +} ioc_fm_pcd_manip_stats_t;
152227 +
152228 +/**************************************************************************//**
152229 + @Description Parameters for acquiring manipulation statistics
152230 +*//***************************************************************************/
152231 +typedef struct ioc_fm_pcd_manip_get_stats_t {
152232 + void *id;
152233 + ioc_fm_pcd_manip_stats_t stats;
152234 +} ioc_fm_pcd_manip_get_stats_t;
152235 +
152236 +#if DPAA_VERSION >= 11
152237 +/**************************************************************************//**
152238 + @Description Parameters for defining frame replicator group and its members
152239 +*//***************************************************************************/
152240 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
152241 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
152242 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
152243 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
152244 + /**< Array of members' parameters */
152245 + void *id;
152246 +} ioc_fm_pcd_frm_replic_group_params_t;
152247 +
152248 +typedef struct ioc_fm_pcd_frm_replic_member_t {
152249 + void *h_replic_group;
152250 + uint16_t member_index;
152251 +} ioc_fm_pcd_frm_replic_member_t;
152252 +
152253 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
152254 + ioc_fm_pcd_frm_replic_member_t member;
152255 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
152256 +} ioc_fm_pcd_frm_replic_member_params_t;
152257 +#endif /* DPAA_VERSION >= 11 */
152258 +
152259 +
152260 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
152261 + uint32_t byte_count; /**< This counter reflects byte count of frames that
152262 + were matched by this key. */
152263 + uint32_t frame_count; /**< This counter reflects count of frames that
152264 + were matched by this key. */
152265 +#if (DPAA_VERSION >= 11)
152266 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
152267 + /**< These counters reflect how many frames matched
152268 + this key in 'RMON' statistics mode:
152269 + Each counter holds the number of frames of a
152270 + specific frames length range, according to the
152271 + ranges provided at initialization. */
152272 +#endif /* (DPAA_VERSION >= 11) */
152273 +} ioc_fm_pcd_cc_key_statistics_t;
152274 +
152275 +
152276 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
152277 + void *id;
152278 + uint16_t key_index;
152279 + ioc_fm_pcd_cc_key_statistics_t statistics;
152280 +} ioc_fm_pcd_cc_tbl_get_stats_t;
152281 +
152282 +/**************************************************************************//**
152283 + @Function FM_PCD_MatchTableGetKeyStatistics
152284 +
152285 + @Description This routine may be used to get statistics counters of specific key
152286 + in a CC Node.
152287 +
152288 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152289 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152290 + these counters reflect how many frames passed that were matched
152291 + this key; The total frames count will be returned in the counter
152292 + of the first range (as only one frame length range was defined).
152293 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
152294 + frame count will be separated to frame length counters, based on
152295 + provided frame length ranges.
152296 +
152297 + @Param[in] h_CcNode A handle to the node
152298 + @Param[in] keyIndex Key index for adding
152299 + @Param[out] p_KeyStatistics Key statistics counters
152300 +
152301 + @Return The specific key statistics.
152302 +
152303 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152304 +*//***************************************************************************/
152305 +
152306 +#if defined(CONFIG_COMPAT)
152307 +#define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_compat_fm_pcd_cc_tbl_get_stats_t)
152308 +#endif
152309 +#define FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(12), ioc_fm_pcd_cc_tbl_get_stats_t)
152310 +
152311 +/**************************************************************************//**
152312 + @Function FM_PCD_MatchTableGetMissStatistics
152313 +
152314 + @Description This routine may be used to get statistics counters of miss entry
152315 + in a CC Node.
152316 +
152317 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152318 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152319 + these counters reflect how many frames were not matched to any
152320 + existing key and therefore passed through the miss entry; The
152321 + total frames count will be returned in the counter of the
152322 + first range (as only one frame length range was defined).
152323 +
152324 + @Param[in] h_CcNode A handle to the node
152325 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152326 +
152327 + @Return E_OK on success; Error code otherwise.
152328 +
152329 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152330 +*//***************************************************************************/
152331 +
152332 +#if defined(CONFIG_COMPAT)
152333 +#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_compat_fm_pcd_cc_tbl_get_stats_t)
152334 +#endif
152335 +#define FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(13), ioc_fm_pcd_cc_tbl_get_stats_t)
152336 +
152337 +/**************************************************************************//**
152338 + @Function FM_PCD_HashTableGetMissStatistics
152339 +
152340 + @Description This routine may be used to get statistics counters of 'miss'
152341 + entry of the a hash table.
152342 +
152343 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
152344 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
152345 + these counters reflect how many frames were not matched to any
152346 + existing key and therefore passed through the miss entry;
152347 +
152348 + @Param[in] h_HashTbl A handle to a hash table
152349 + @Param[out] p_MissStatistics Statistics counters for 'miss'
152350 +
152351 + @Return E_OK on success; Error code otherwise.
152352 +
152353 + @Cautions Allowed only following FM_PCD_HashTableSet().
152354 +*//***************************************************************************/
152355 +
152356 +#if defined(CONFIG_COMPAT)
152357 +#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_compat_fm_pcd_cc_tbl_get_stats_t)
152358 +#endif
152359 +#define FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(14), ioc_fm_pcd_cc_tbl_get_stats_t)
152360 +
152361 +
152362 +/**************************************************************************//**
152363 + @Function FM_PCD_NetEnvCharacteristicsSet
152364 +
152365 + @Description Define a set of Network Environment Characteristics.
152366 +
152367 + When setting an environment it is important to understand its
152368 + application. It is not meant to describe the flows that will run
152369 + on the ports using this environment, but what the user means TO DO
152370 + with the PCD mechanisms in order to parse-classify-distribute those
152371 + frames.
152372 + By specifying a distinction unit, the user means it would use that option
152373 + for distinction between frames at either a KeyGen scheme or a coarse
152374 + classification action descriptor. Using interchangeable headers to define a
152375 + unit means that the user is indifferent to which of the interchangeable
152376 + headers is present in the frame, and wants the distinction to be based
152377 + on the presence of either one of them.
152378 +
152379 + Depending on context, there are limitations to the use of environments. A
152380 + port using the PCD functionality is bound to an environment. Some or even
152381 + all ports may share an environment but also an environment per port is
152382 + possible. When initializing a scheme, a classification plan group (see below),
152383 + or a coarse classification tree, one of the initialized environments must be
152384 + stated and related to. When a port is bound to a scheme, a classification
152385 + plan group, or a coarse classification tree, it MUST be bound to the same
152386 + environment.
152387 +
152388 + The different PCD modules, may relate (for flows definition) ONLY on
152389 + distinction units as defined by their environment. When initializing a
152390 + scheme for example, it may not choose to select IPV4 as a match for
152391 + recognizing flows unless it was defined in the relating environment. In
152392 + fact, to guide the user through the configuration of the PCD, each module's
152393 + characterization in terms of flows is not done using protocol names, but using
152394 + environment indexes.
152395 +
152396 + In terms of HW implementation, the list of distinction units sets the LCV vectors
152397 + and later used for match vector, classification plan vectors and coarse classification
152398 + indexing.
152399 +
152400 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
152401 +
152402 + @Return 0 on success; Error code otherwise.
152403 +*//***************************************************************************/
152404 +#if defined(CONFIG_COMPAT)
152405 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_compat_fm_pcd_net_env_params_t)
152406 +#endif
152407 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(20), ioc_fm_pcd_net_env_params_t)
152408 +
152409 +/**************************************************************************//**
152410 + @Function FM_PCD_NetEnvCharacteristicsDelete
152411 +
152412 + @Description Deletes a set of Network Environment Charecteristics.
152413 +
152414 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
152415 +
152416 + @Return 0 on success; Error code otherwise.
152417 +*//***************************************************************************/
152418 +#if defined(CONFIG_COMPAT)
152419 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
152420 +#endif
152421 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
152422 +
152423 +/**************************************************************************//**
152424 + @Function FM_PCD_KgSchemeSet
152425 +
152426 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
152427 + This routine should be called for adding or modifying a scheme.
152428 + When a scheme needs modifying, the API requires that it will be
152429 + rewritten. In such a case 'modify' should be TRUE. If the
152430 + routine is called for a valid scheme and 'modify' is FALSE,
152431 + it will return error.
152432 +
152433 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
152434 +
152435 + @Return 0 on success; Error code otherwise.
152436 +*//***************************************************************************/
152437 +#if defined(CONFIG_COMPAT)
152438 +#define FM_PCD_IOC_KG_SCHEME_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_compat_fm_pcd_kg_scheme_params_t)
152439 +#endif
152440 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
152441 +
152442 +/**************************************************************************//**
152443 + @Function FM_PCD_KgSchemeDelete
152444 +
152445 + @Description Deleting an initialized scheme.
152446 +
152447 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
152448 +
152449 + @Return 0 on success; Error code otherwise.
152450 +*//***************************************************************************/
152451 +#if defined(CONFIG_COMPAT)
152452 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
152453 +#endif
152454 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
152455 +
152456 +/**************************************************************************//**
152457 + @Function FM_PCD_CcRootBuild
152458 +
152459 + @Description This routine must be called to define a complete coarse
152460 + classification tree. This is the way to define coarse
152461 + classification to a certain flow - the KeyGen schemes
152462 + may point only to trees defined in this way.
152463 +
152464 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
152465 +
152466 + @Return 0 on success; Error code otherwise.
152467 +*//***************************************************************************/
152468 +#if defined(CONFIG_COMPAT)
152469 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
152470 +#endif
152471 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
152472 +
152473 +/**************************************************************************//**
152474 + @Function FM_PCD_CcRootDelete
152475 +
152476 + @Description Deleting a built tree.
152477 +
152478 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
152479 +*//***************************************************************************/
152480 +#if defined(CONFIG_COMPAT)
152481 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
152482 +#endif
152483 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
152484 +
152485 +/**************************************************************************//**
152486 + @Function FM_PCD_MatchTableSet
152487 +
152488 + @Description This routine should be called for each CC (coarse classification)
152489 + node. The whole CC tree should be built bottom up so that each
152490 + node points to already defined nodes. p_NodeId returns the node
152491 + Id to be used by other nodes.
152492 +
152493 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
152494 +
152495 + @Return 0 on success; Error code otherwise.
152496 +*//***************************************************************************/
152497 +#if defined(CONFIG_COMPAT)
152498 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
152499 +#endif
152500 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
152501 +
152502 +/**************************************************************************//**
152503 + @Function FM_PCD_MatchTableDelete
152504 +
152505 + @Description Deleting a built node.
152506 +
152507 + @Param[in] ioc_fm_obj_t - The id of a CC node.
152508 +
152509 + @Return 0 on success; Error code otherwise.
152510 +*//***************************************************************************/
152511 +#if defined(CONFIG_COMPAT)
152512 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
152513 +#endif
152514 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
152515 +
152516 +/**************************************************************************//**
152517 + @Function FM_PCD_CcRootModifyNextEngine
152518 +
152519 + @Description Modify the Next Engine Parameters in the entry of the tree.
152520 +
152521 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152522 +
152523 + @Return 0 on success; Error code otherwise.
152524 +
152525 + @Cautions Allowed only following FM_PCD_CcRootBuild().
152526 +*//***************************************************************************/
152527 +#if defined(CONFIG_COMPAT)
152528 +#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)
152529 +#endif
152530 +#define FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(30), ioc_fm_pcd_cc_tree_modify_next_engine_params_t)
152531 +
152532 +/**************************************************************************//**
152533 + @Function FM_PCD_MatchTableModifyNextEngine
152534 +
152535 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
152536 +
152537 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
152538 +
152539 + @Return 0 on success; Error code otherwise.
152540 +
152541 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152542 +*//***************************************************************************/
152543 +#if defined(CONFIG_COMPAT)
152544 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)
152545 +#endif
152546 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(31), ioc_fm_pcd_cc_node_modify_next_engine_params_t)
152547 +
152548 +/**************************************************************************//**
152549 + @Function FM_PCD_MatchTableModifyMissNextEngine
152550 +
152551 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
152552 +
152553 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
152554 +
152555 + @Return 0 on success; Error code otherwise.
152556 +
152557 + @Cautions Allowed only following FM_PCD_MatchTableSet().
152558 +*//***************************************************************************/
152559 +#if defined(CONFIG_COMPAT)
152560 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)
152561 +#endif
152562 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(32), ioc_fm_pcd_cc_node_modify_next_engine_params_t)
152563 +
152564 +/**************************************************************************//**
152565 + @Function FM_PCD_MatchTableRemoveKey
152566 +
152567 + @Description Remove the key (including next engine parameters of this key)
152568 + defined by the index of the relevant node.
152569 +
152570 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
152571 +
152572 + @Return 0 on success; Error code otherwise.
152573 +
152574 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152575 + node and for all of the nodes that lead to it.
152576 +*//***************************************************************************/
152577 +#if defined(CONFIG_COMPAT)
152578 +#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_compat_fm_pcd_cc_node_remove_key_params_t)
152579 +#endif
152580 +#define FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(33), ioc_fm_pcd_cc_node_remove_key_params_t)
152581 +
152582 +/**************************************************************************//**
152583 + @Function FM_PCD_MatchTableAddKey
152584 +
152585 + @Description Add the key (including next engine parameters of this key in the
152586 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
152587 + may be used when the user doesn't care about the position of the
152588 + key in the table - in that case, the key will be automatically
152589 + added by the driver in the last available entry.
152590 +
152591 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152592 +
152593 + @Return 0 on success; Error code otherwise.
152594 +
152595 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152596 + node and for all of the nodes that lead to it.
152597 +*//***************************************************************************/
152598 +#if defined(CONFIG_COMPAT)
152599 +#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)
152600 +#endif
152601 +#define FM_PCD_IOC_MATCH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(34), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)
152602 +
152603 +/**************************************************************************//**
152604 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
152605 +
152606 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
152607 +
152608 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
152609 +
152610 + @Return 0 on success; Error code otherwise.
152611 +
152612 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
152613 + the node that points to this node
152614 +*//***************************************************************************/
152615 +#if defined(CONFIG_COMPAT)
152616 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)
152617 +#endif
152618 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(35), ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)
152619 +
152620 +/**************************************************************************//**
152621 + @Function FM_PCD_MatchTableModifyKey
152622 +
152623 + @Description Modify the key at the index defined by key_index.
152624 +
152625 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
152626 +
152627 + @Return 0 on success; Error code otherwise.
152628 +
152629 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
152630 + node and for all of the nodes that lead to it.
152631 +*//***************************************************************************/
152632 +#if defined(CONFIG_COMPAT)
152633 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_compat_fm_pcd_cc_node_modify_key_params_t)
152634 +#endif
152635 +#define FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(36), ioc_fm_pcd_cc_node_modify_key_params_t)
152636 +
152637 +/**************************************************************************//**
152638 + @Function FM_PCD_HashTableSet
152639 +
152640 + @Description This routine initializes a hash table structure.
152641 + KeyGen hash result determines the hash bucket.
152642 + Next, KeyGen key is compared against all keys of this
152643 + bucket (exact match).
152644 + Number of sets (number of buckets) of the hash equals to the
152645 + number of 1-s in 'hash_res_mask' in the provided parameters.
152646 + Number of hash table ways is then calculated by dividing
152647 + 'max_num_of_keys' equally between the hash sets. This is the maximal
152648 + number of keys that a hash bucket may hold.
152649 + The hash table is initialized empty and keys may be
152650 + added to it following the initialization. Keys masks are not
152651 + supported in current hash table implementation.
152652 + The initialized hash table can be integrated as a node in a
152653 + CC tree.
152654 +
152655 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
152656 +
152657 + @Return 0 on success; Error code otherwise.
152658 +*//***************************************************************************/
152659 +#if defined(CONFIG_COMPAT)
152660 +#define FM_PCD_IOC_HASH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_pcd_hash_table_params_t)
152661 +#endif
152662 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
152663 +
152664 +
152665 +/**************************************************************************//**
152666 + @Function FM_PCD_HashTableDelete
152667 +
152668 + @Description This routine deletes the provided hash table and released all
152669 + its allocated resources.
152670 +
152671 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
152672 +
152673 + @Return 0 on success; Error code otherwise.
152674 +
152675 + @Cautions Allowed only following FM_PCD_HashTableSet().
152676 +*//***************************************************************************/
152677 +#if defined(CONFIG_COMPAT)
152678 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
152679 +#endif
152680 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
152681 +
152682 +/**************************************************************************//**
152683 + @Function FM_PCD_HashTableAddKey
152684 +
152685 + @Description This routine adds the provided key (including next engine
152686 + parameters of this key) to the hash table.
152687 + The key is added as the last key of the bucket that it is
152688 + mapped to.
152689 +
152690 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
152691 +
152692 + @Return 0 on success; error code otherwise.
152693 +
152694 + @Cautions Allowed only following FM_PCD_HashTableSet().
152695 +*//***************************************************************************/
152696 +#if defined(CONFIG_COMPAT)
152697 +#define FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_compat_fm_pcd_hash_table_add_key_params_t)
152698 +#endif
152699 +#define FM_PCD_IOC_HASH_TABLE_ADD_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(39), ioc_fm_pcd_hash_table_add_key_params_t)
152700 +
152701 +/**************************************************************************//**
152702 + @Function FM_PCD_HashTableRemoveKey
152703 +
152704 + @Description This routine removes the requested key (including next engine
152705 + parameters of this key) from the hash table.
152706 +
152707 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
152708 +
152709 + @Return 0 on success; Error code otherwise.
152710 +
152711 + @Cautions Allowed only following FM_PCD_HashTableSet().
152712 +*//***************************************************************************/
152713 +#if defined(CONFIG_COMPAT)
152714 +#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_compat_fm_pcd_hash_table_remove_key_params_t)
152715 +#endif
152716 +#define FM_PCD_IOC_HASH_TABLE_REMOVE_KEY _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(40), ioc_fm_pcd_hash_table_remove_key_params_t)
152717 +
152718 +/**************************************************************************//**
152719 + @Function FM_PCD_PlcrProfileSet
152720 +
152721 + @Description Sets a profile entry in the policer profile table.
152722 + The routine overrides any existing value.
152723 +
152724 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
152725 + policer profile entry.
152726 +
152727 + @Return 0 on success; Error code otherwise.
152728 +*//***************************************************************************/
152729 +#if defined(CONFIG_COMPAT)
152730 +#define FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_pcd_plcr_profile_params_t)
152731 +#endif
152732 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
152733 +
152734 +/**************************************************************************//**
152735 + @Function FM_PCD_PlcrProfileDelete
152736 +
152737 + @Description Delete a profile entry in the policer profile table.
152738 + The routine set entry to invalid.
152739 +
152740 + @Param[in] ioc_fm_obj_t The id of a policer profile.
152741 +
152742 + @Return 0 on success; Error code otherwise.
152743 +*//***************************************************************************/
152744 +#if defined(CONFIG_COMPAT)
152745 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
152746 +#endif
152747 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
152748 +
152749 +/**************************************************************************//**
152750 + @Function FM_PCD_ManipNodeSet
152751 +
152752 + @Description This routine should be called for defining a manipulation
152753 + node. A manipulation node must be defined before the CC node
152754 + that precedes it.
152755 +
152756 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152757 +
152758 + @Return A handle to the initialized object on success; NULL code otherwise.
152759 +*//***************************************************************************/
152760 +#if defined(CONFIG_COMPAT)
152761 +#define FM_PCD_IOC_MANIP_NODE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_compat_fm_pcd_manip_params_t)
152762 +#endif
152763 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
152764 +
152765 +/**************************************************************************//**
152766 + @Function FM_PCD_ManipNodeReplace
152767 +
152768 + @Description Change existing manipulation node to be according to new requirement.
152769 + (Here, it's implemented as a variant of the same IOCTL as for
152770 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
152771 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
152772 + the manip node's handle)
152773 +
152774 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
152775 +
152776 + @Return 0 on success; error code otherwise.
152777 +
152778 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152779 +*//***************************************************************************/
152780 +#if defined(CONFIG_COMPAT)
152781 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152782 +#endif
152783 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
152784 +
152785 +/**************************************************************************//**
152786 + @Function FM_PCD_ManipNodeDelete
152787 +
152788 + @Description Delete an existing manipulation node.
152789 +
152790 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
152791 +
152792 + @Return 0 on success; error code otherwise.
152793 +
152794 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152795 +*//***************************************************************************/
152796 +#if defined(CONFIG_COMPAT)
152797 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
152798 +#endif
152799 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
152800 +
152801 +/**************************************************************************//**
152802 + @Function FM_PCD_ManipGetStatistics
152803 +
152804 + @Description Retrieve the manipulation statistics.
152805 +
152806 + @Param[in] h_ManipNode A handle to a manipulation node.
152807 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
152808 +
152809 + @Return E_OK on success; Error code otherwise.
152810 +
152811 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
152812 +*//***************************************************************************/
152813 +#if defined(CONFIG_COMPAT)
152814 +#define FM_PCD_IOC_MANIP_GET_STATS_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_compat_fm_pcd_manip_get_stats_t)
152815 +#endif
152816 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
152817 +
152818 +/**************************************************************************//**
152819 +@Function FM_PCD_SetAdvancedOffloadSupport
152820 +
152821 +@Description This routine must be called in order to support the following features:
152822 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
152823 +
152824 +@Param[in] h_FmPcd FM PCD module descriptor.
152825 +
152826 +@Return 0 on success; error code otherwise.
152827 +
152828 +@Cautions Allowed only when PCD is disabled.
152829 +*//***************************************************************************/
152830 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
152831 +
152832 +#if (DPAA_VERSION >= 11)
152833 +/**************************************************************************//**
152834 + @Function FM_PCD_FrmReplicSetGroup
152835 +
152836 + @Description Initialize a Frame Replicator group.
152837 +
152838 + @Param[in] h_FmPcd FM PCD module descriptor.
152839 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
152840 + the frame replicator group.
152841 +
152842 + @Return A handle to the initialized object on success; NULL code otherwise.
152843 +
152844 + @Cautions Allowed only following FM_PCD_Init().
152845 +*//***************************************************************************/
152846 +#if defined(CONFIG_COMPAT)
152847 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_compat_fm_pcd_frm_replic_group_params_t)
152848 +#endif
152849 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(46), ioc_fm_pcd_frm_replic_group_params_t)
152850 +
152851 +/**************************************************************************//**
152852 + @Function FM_PCD_FrmReplicDeleteGroup
152853 +
152854 + @Description Delete a Frame Replicator group.
152855 +
152856 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152857 +
152858 + @Return E_OK on success; Error code otherwise.
152859 +
152860 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
152861 +*//***************************************************************************/
152862 +#if defined(CONFIG_COMPAT)
152863 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
152864 +#endif
152865 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
152866 +
152867 +/**************************************************************************//**
152868 + @Function FM_PCD_FrmReplicAddMember
152869 +
152870 + @Description Add the member in the index defined by the memberIndex.
152871 +
152872 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152873 + @Param[in] memberIndex member index for adding.
152874 + @Param[in] p_MemberParams A pointer to the new member parameters.
152875 +
152876 + @Return E_OK on success; Error code otherwise.
152877 +
152878 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152879 +*//***************************************************************************/
152880 +#if defined(CONFIG_COMPAT)
152881 +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_compat_fm_pcd_frm_replic_member_params_t)
152882 +#endif
152883 +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(48), ioc_fm_pcd_frm_replic_member_params_t)
152884 +
152885 +/**************************************************************************//**
152886 + @Function FM_PCD_FrmReplicRemoveMember
152887 +
152888 + @Description Remove the member defined by the index from the relevant group.
152889 +
152890 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
152891 + @Param[in] memberIndex member index for removing.
152892 +
152893 + @Return E_OK on success; Error code otherwise.
152894 +
152895 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
152896 +*//***************************************************************************/
152897 +#if defined(CONFIG_COMPAT)
152898 +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_compat_fm_pcd_frm_replic_member_t)
152899 +#endif
152900 +#define FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(49), ioc_fm_pcd_frm_replic_member_t)
152901 +
152902 +#endif
152903 +
152904 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152905 +/**************************************************************************//**
152906 + @Function FM_PCD_StatisticsSetNode
152907 +
152908 + @Description This routine should be called for defining a statistics node.
152909 +
152910 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
152911 +
152912 + @Return 0 on success; Error code otherwise.
152913 +*//***************************************************************************/
152914 +#if defined(CONFIG_COMPAT)
152915 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152916 +#endif
152917 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
152918 +
152919 +#endif /* FM_CAPWAP_SUPPORT */
152920 +
152921 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
152922 +#if defined(CONFIG_COMPAT)
152923 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
152924 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
152925 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
152926 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
152927 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
152928 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
152929 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
152930 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
152931 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
152932 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
152933 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
152934 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
152935 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
152936 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
152937 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
152938 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
152939 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
152940 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
152941 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
152942 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
152943 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
152944 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
152945 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
152946 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
152947 +#endif
152948 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
152949 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
152950 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
152951 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
152952 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
152953 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
152954 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
152955 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
152956 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
152957 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
152958 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
152959 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
152960 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
152961 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
152962 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
152963 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
152964 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
152965 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
152966 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
152967 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
152968 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
152969 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
152970 +
152971 +#endif /* __FM_PCD_IOCTLS_H */
152972 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
152973 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
152974 +/** @} */ /* end of lnx_ioctl_FM_grp group */
152975 --- /dev/null
152976 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
152977 @@ -0,0 +1,973 @@
152978 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
152979 + * All rights reserved.
152980 + *
152981 + * Redistribution and use in source and binary forms, with or without
152982 + * modification, are permitted provided that the following conditions are met:
152983 + * * Redistributions of source code must retain the above copyright
152984 + * notice, this list of conditions and the following disclaimer.
152985 + * * Redistributions in binary form must reproduce the above copyright
152986 + * notice, this list of conditions and the following disclaimer in the
152987 + * documentation and/or other materials provided with the distribution.
152988 + * * Neither the name of Freescale Semiconductor nor the
152989 + * names of its contributors may be used to endorse or promote products
152990 + * derived from this software without specific prior written permission.
152991 + *
152992 + *
152993 + * ALTERNATIVELY, this software may be distributed under the terms of the
152994 + * GNU General Public License ("GPL") as published by the Free Software
152995 + * Foundation, either version 2 of that License or (at your option) any
152996 + * later version.
152997 + *
152998 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
152999 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153000 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153001 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153002 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153003 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153004 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153005 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153006 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153007 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153008 + */
153009 +
153010 +/******************************************************************************
153011 + @File fm_port_ioctls.h
153012 +
153013 + @Description FM Port routines
153014 +*//***************************************************************************/
153015 +#ifndef __FM_PORT_IOCTLS_H
153016 +#define __FM_PORT_IOCTLS_H
153017 +
153018 +#include "enet_ext.h"
153019 +#include "net_ioctls.h"
153020 +#include "fm_ioctls.h"
153021 +#include "fm_pcd_ioctls.h"
153022 +
153023 +
153024 +/**************************************************************************//**
153025 +
153026 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
153027 +
153028 + @Description FM Linux ioctls definitions and enums
153029 +
153030 + @{
153031 +*//***************************************************************************/
153032 +
153033 +/**************************************************************************//**
153034 + @Group lnx_ioctl_FM_PORT_grp FM Port
153035 +
153036 + @Description FM Port API
153037 +
153038 + The FM uses a general module called "port" to represent a Tx port
153039 + (MAC), an Rx port (MAC), offline parsing flow or host command
153040 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
153041 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
153042 + Host command/Offline parsing ports. The SW driver manages these
153043 + ports as sub-modules of the FM, i.e. after an FM is initialized,
153044 + its ports may be initialized and operated upon.
153045 +
153046 + The port is initialized aware of its type, but other functions on
153047 + a port may be indifferent to its type. When necessary, the driver
153048 + verifies coherency and returns error if applicable.
153049 +
153050 + On initialization, user specifies the port type and it's index
153051 + (relative to the port's type). Host command and Offline parsing
153052 + ports share the same id range, I.e user may not initialized host
153053 + command port 0 and offline parsing port 0.
153054 +
153055 + @{
153056 +*//***************************************************************************/
153057 +
153058 +/**************************************************************************//**
153059 + @Description An enum for defining port PCD modes.
153060 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
153061 +
153062 + This enum defines the superset of PCD engines support - i.e. not
153063 + all engines have to be used, but all have to be enabled. The real
153064 + flow of a specific frame depends on the PCD configuration and the
153065 + frame headers and payload.
153066 + Note: the first engine and the first engine after the parser (if
153067 + exists) should be in order, the order is important as it will
153068 + define the flow of the port. However, as for the rest engines
153069 + (the ones that follows), the order is not important anymore as
153070 + it is defined by the PCD graph itself.
153071 +*//***************************************************************************/
153072 +typedef enum ioc_fm_port_pcd_support {
153073 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
153074 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
153075 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
153076 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
153077 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
153078 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
153079 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
153080 + /**< Use all PCD engines */
153081 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
153082 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
153083 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
153084 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
153085 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153086 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
153087 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
153088 +#endif /* FM_CAPWAP_SUPPORT */
153089 +} ioc_fm_port_pcd_support;
153090 +
153091 +
153092 +/**************************************************************************//**
153093 + @Collection FM Frame error
153094 +*//***************************************************************************/
153095 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
153096 +
153097 +/* @} */
153098 +
153099 +
153100 +/**************************************************************************//**
153101 + @Description An enum for defining Dual Tx rate limiting scale.
153102 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
153103 +*//***************************************************************************/
153104 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
153105 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
153106 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
153107 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
153108 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
153109 +} ioc_fm_port_dual_rate_limiter_scale_down;
153110 +
153111 +/**************************************************************************//**
153112 + @Description A structure for defining Tx rate limiting
153113 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
153114 +*//***************************************************************************/
153115 +typedef struct ioc_fm_port_rate_limit_t {
153116 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
153117 + for offline parsing ports. (note that
153118 + for early chips burst size is
153119 + rounded up to a multiply of 1000 frames).*/
153120 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
153121 + offline parsing ports. Rate limit refers to
153122 + data rate (rather than line rate). */
153123 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
153124 + for some earlier chip revisions */
153125 +} ioc_fm_port_rate_limit_t;
153126 +
153127 +
153128 +
153129 +/**************************************************************************//**
153130 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
153131 +
153132 + @Description FM Port Runtime control unit API functions, definitions and enums.
153133 +
153134 + @{
153135 +*//***************************************************************************/
153136 +
153137 +/**************************************************************************//**
153138 + @Description An enum for defining FM Port counters.
153139 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
153140 +*//***************************************************************************/
153141 +typedef enum ioc_fm_port_counters {
153142 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
153143 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
153144 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
153145 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
153146 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
153147 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
153148 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
153149 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
153150 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
153151 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
153152 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
153153 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
153154 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
153155 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
153156 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
153157 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
153158 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
153159 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
153160 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
153161 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
153162 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
153163 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
153164 +} ioc_fm_port_counters;
153165 +
153166 +typedef struct ioc_fm_port_bmi_stats_t {
153167 + uint32_t cnt_cycle;
153168 + uint32_t cnt_task_util;
153169 + uint32_t cnt_queue_util;
153170 + uint32_t cnt_dma_util;
153171 + uint32_t cnt_fifo_util;
153172 + uint32_t cnt_rx_pause_activation;
153173 + uint32_t cnt_frame;
153174 + uint32_t cnt_discard_frame;
153175 + uint32_t cnt_dealloc_buf;
153176 + uint32_t cnt_rx_bad_frame;
153177 + uint32_t cnt_rx_large_frame;
153178 + uint32_t cnt_rx_filter_frame;
153179 + uint32_t cnt_rx_list_dma_err;
153180 + uint32_t cnt_rx_out_of_buffers_discard;
153181 + uint32_t cnt_wred_discard;
153182 + uint32_t cnt_length_err;
153183 + uint32_t cnt_unsupported_format;
153184 +} ioc_fm_port_bmi_stats_t;
153185 +
153186 +/**************************************************************************//**
153187 + @Description Structure for Port id parameters.
153188 + (Description may be inaccurate;
153189 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
153190 +
153191 + Fields commented 'IN' are passed by the port module to be used
153192 + by the FM module.
153193 + Fields commented 'OUT' will be filled by FM before returning to port.
153194 +*//***************************************************************************/
153195 +typedef struct ioc_fm_port_congestion_groups_t {
153196 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
153197 + to define the size of the following array */
153198 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
153199 + /**< An array of CG indexes;
153200 + Note that the size of the array should be
153201 + 'num_of_congestion_grps_to_consider'. */
153202 +#if DPAA_VERSION >= 11
153203 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
153204 + /**< A matrix that represents the map between the CG ids
153205 + defined in 'congestion_grps_to_consider' to the priorities
153206 + mapping array. */
153207 +#endif /* DPAA_VERSION >= 11 */
153208 +} ioc_fm_port_congestion_groups_t;
153209 +
153210 +
153211 +
153212 +/**************************************************************************//**
153213 + @Function FM_PORT_Disable
153214 +
153215 + @Description Gracefully disable an FM port. The port will not start new tasks after all
153216 + tasks associated with the port are terminated.
153217 +
153218 + @Return 0 on success; error code otherwise.
153219 +
153220 + @Cautions This is a blocking routine, it returns after port is
153221 + gracefully stopped, i.e. the port will not except new frames,
153222 + but it will finish all frames or tasks which were already began
153223 +*//***************************************************************************/
153224 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
153225 +
153226 +/**************************************************************************//**
153227 + @Function FM_PORT_Enable
153228 +
153229 + @Description A runtime routine provided to allow disable/enable of port.
153230 +
153231 + @Return 0 on success; error code otherwise.
153232 +*//***************************************************************************/
153233 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
153234 +
153235 +/**************************************************************************//**
153236 + @Function FM_PORT_SetRateLimit
153237 +
153238 + @Description Calling this routine enables rate limit algorithm.
153239 + By default, this functionality is disabled.
153240 + Note that rate-limit mechanism uses the FM time stamp.
153241 + The selected rate limit specified here would be
153242 + rounded DOWN to the nearest 16M.
153243 +
153244 + May be used for Tx and offline parsing ports only
153245 +
153246 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
153247 +
153248 + @Return 0 on success; error code otherwise.
153249 +*//***************************************************************************/
153250 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
153251 +
153252 +/**************************************************************************//**
153253 + @Function FM_PORT_DeleteRateLimit
153254 +
153255 + @Description Calling this routine disables the previously enabled rate limit.
153256 +
153257 + May be used for Tx and offline parsing ports only
153258 +
153259 + @Return 0 on success; error code otherwise.
153260 +*//***************************************************************************/
153261 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
153262 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
153263 +
153264 +
153265 +/**************************************************************************//**
153266 + @Function FM_PORT_AddCongestionGrps
153267 +
153268 + @Description This routine effects the corresponding Tx port.
153269 + It should be called in order to enable pause
153270 + frame transmission in case of congestion in one or more
153271 + of the congestion groups relevant to this port.
153272 + Each call to this routine may add one or more congestion
153273 + groups to be considered relevant to this port.
153274 +
153275 + May be used for Rx, or RX+OP ports only (depending on chip)
153276 +
153277 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153278 + congestion group ids to consider.
153279 +
153280 + @Return 0 on success; error code otherwise.
153281 +*//***************************************************************************/
153282 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
153283 +
153284 +/**************************************************************************//**
153285 + @Function FM_PORT_RemoveCongestionGrps
153286 +
153287 + @Description This routine effects the corresponding Tx port. It should be
153288 + called when congestion groups were
153289 + defined for this port and are no longer relevant, or pause
153290 + frames transmitting is not required on their behalf.
153291 + Each call to this routine may remove one or more congestion
153292 + groups to be considered relevant to this port.
153293 +
153294 + May be used for Rx, or RX+OP ports only (depending on chip)
153295 +
153296 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
153297 + congestion group ids to consider.
153298 +
153299 + @Return 0 on success; error code otherwise.
153300 +*//***************************************************************************/
153301 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
153302 +
153303 +/**************************************************************************//**
153304 + @Function FM_PORT_SetErrorsRoute
153305 +
153306 + @Description Errors selected for this routine will cause a frame with that error
153307 + to be enqueued to error queue.
153308 + Errors not selected for this routine will cause a frame with that error
153309 + to be enqueued to the one of the other port queues.
153310 + By default all errors are defined to be enqueued to error queue.
153311 + Errors that were configured to be discarded (at initialization)
153312 + may not be selected here.
153313 +
153314 + May be used for Rx and offline parsing ports only
153315 +
153316 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
153317 +
153318 + @Return 0 on success; error code otherwise.
153319 +
153320 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153321 + (szbs001: How is it possible to have one function that needs to be
153322 + called BEFORE FM_PORT_Init() implemented as an ioctl,
153323 + which will ALWAYS be called AFTER the FM_PORT_Init()
153324 + for that port!?!?!?!???!?!??!?!?)
153325 +*//***************************************************************************/
153326 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
153327 +
153328 +
153329 +/**************************************************************************//**
153330 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
153331 +
153332 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
153333 +
153334 + @{
153335 +*//***************************************************************************/
153336 +
153337 +/**************************************************************************//**
153338 + @Description A structure defining the KG scheme after the parser.
153339 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
153340 +
153341 + This is relevant only to change scheme selection mode - from
153342 + direct to indirect and vice versa, or when the scheme is selected directly,
153343 + to select the scheme id.
153344 +
153345 +*//***************************************************************************/
153346 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
153347 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
153348 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
153349 + 'scheme_id' selects the scheme after parser. */
153350 +} ioc_fm_pcd_kg_scheme_select_t;
153351 +
153352 +/**************************************************************************//**
153353 + @Description Scheme IDs structure
153354 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
153355 +*//***************************************************************************/
153356 +typedef struct ioc_fm_pcd_port_schemes_params_t {
153357 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153358 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
153359 + port to be bound to */
153360 +} ioc_fm_pcd_port_schemes_params_t;
153361 +
153362 +/**************************************************************************//**
153363 + @Description A union for defining port protocol parameters for parser
153364 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
153365 +*//***************************************************************************/
153366 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
153367 + /* MPLS */
153368 + struct {
153369 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
153370 + interpreted as described in HW spec table. When the bit
153371 + is cleared, the parser will advance to MPLS next parse */
153372 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
153373 + } mpls_prs_options;
153374 +
153375 + /* VLAN */
153376 + struct {
153377 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
153378 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153379 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
153380 + on VLAN TAG on top of 0x8100 and 0x88A8 */
153381 + } vlan_prs_options;
153382 +
153383 + /* PPP */
153384 + struct{
153385 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
153386 + } pppoe_prs_options;
153387 +
153388 + /* IPV6 */
153389 + struct {
153390 + bool routing_hdr_disable; /**< Disable routing header */
153391 + } ipv6_prs_options;
153392 +
153393 + /* UDP */
153394 + struct {
153395 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153396 + } udp_prs_options;
153397 +
153398 + /* TCP */
153399 + struct {
153400 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
153401 + } tcp_prs_options;
153402 +} ioc_fm_pcd_hdr_prs_opts_u;
153403 +
153404 +/**************************************************************************//**
153405 + @Description A structure for defining each header for the parser
153406 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
153407 +*//***************************************************************************/
153408 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
153409 + ioc_net_header_type hdr; /**< Selected header */
153410 + bool err_disable; /**< TRUE to disable error indication */
153411 + bool soft_prs_enable; /**< Enable jump to SW parser when this
153412 + header is recognized by the HW parser. */
153413 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
153414 + attachments exists for the same header,
153415 + (in the main sw parser code) use this
153416 + index to distinguish between them. */
153417 + bool use_prs_opts; /**< TRUE to use parser options. */
153418 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
153419 + defining the parser options selected.*/
153420 +} ioc_fm_pcd_prs_additional_hdr_params_t;
153421 +
153422 +/**************************************************************************//**
153423 + @Description A structure for defining port PCD parameters
153424 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
153425 +*//***************************************************************************/
153426 +typedef struct ioc_fm_port_pcd_prs_params_t {
153427 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
153428 + port information into the parser result. This information
153429 + may be extracted by KeyGen and be used for frames
153430 + distribution when a per-port distinction is required,
153431 + it may also be used as a port logical id for analyzing
153432 + incoming frames. */
153433 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
153434 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
153435 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
153436 + uint8_t num_of_hdrs_with_additional_params;
153437 + /**< Normally 0, some headers may get special parameters */
153438 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
153439 + /**< 'num_of_hdrs_with_additional_params' structures
153440 + additional parameters for each header that requires them */
153441 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
153442 + indicate a VLAN tag (in addition to the TPID values
153443 + 0x8100 and 0x88A8). */
153444 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153445 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
153446 + indicate a VLAN tag (in addition to the TPID values
153447 + 0x8100 and 0x88A8). */
153448 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
153449 +} ioc_fm_port_pcd_prs_params_t;
153450 +
153451 +/**************************************************************************//**
153452 + @Description A structure for defining coarse alassification parameters
153453 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
153454 +*//***************************************************************************/
153455 +typedef struct ioc_fm_port_pcd_cc_params_t {
153456 + void *cc_tree_id; /**< CC tree id */
153457 +} ioc_fm_port_pcd_cc_params_t;
153458 +
153459 +/**************************************************************************//**
153460 + @Description A structure for defining keygen parameters
153461 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
153462 +*//***************************************************************************/
153463 +typedef struct ioc_fm_port_pcd_kg_params_t {
153464 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
153465 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
153466 + /**< Array of 'num_of_schemes' schemes for the
153467 + port to be bound to */
153468 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
153469 + regardless of parser result */
153470 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
153471 + relevant only if direct=TRUE. */
153472 +} ioc_fm_port_pcd_kg_params_t;
153473 +
153474 +/**************************************************************************//**
153475 + @Description A structure for defining policer parameters
153476 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
153477 +*//***************************************************************************/
153478 +typedef struct ioc_fm_port_pcd_plcr_params_t {
153479 + void *plcr_profile_id; /**< Selected profile handle;
153480 + relevant in one of the following cases:
153481 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
153482 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
153483 + or if any flow uses a KG scheme where policer
153484 + profile is not generated (bypass_plcr_profile_generation selected) */
153485 +} ioc_fm_port_pcd_plcr_params_t;
153486 +
153487 +/**************************************************************************//**
153488 + @Description A structure for defining port PCD parameters
153489 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
153490 +*//***************************************************************************/
153491 +typedef struct ioc_fm_port_pcd_params_t {
153492 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
153493 + Describes the active PCD engines for this port. */
153494 + void *net_env_id; /**< HL Unused in PLCR only mode */
153495 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
153496 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
153497 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
153498 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
153499 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
153500 +#if (DPAA_VERSION >= 11)
153501 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
153502 +#endif /* (DPAA_VERSION >= 11) */
153503 +} ioc_fm_port_pcd_params_t;
153504 +
153505 +/**************************************************************************//**
153506 + @Description A structure for defining the Parser starting point
153507 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
153508 +*//***************************************************************************/
153509 +typedef struct ioc_fm_pcd_prs_start_t {
153510 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
153511 + start parsing */
153512 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
153513 + 'parsing_offset' */
153514 +} ioc_fm_pcd_prs_start_t;
153515 +
153516 +
153517 +/**************************************************************************//**
153518 + @Description FQID parameters structure
153519 +*//***************************************************************************/
153520 +typedef struct ioc_fm_port_pcd_fqids_params_t {
153521 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
153522 + uint8_t alignment; /**< Alignment required for this port */
153523 + uint32_t base_fqid; /**< output parameter - the base fqid */
153524 +} ioc_fm_port_pcd_fqids_params_t;
153525 +
153526 +
153527 +/**************************************************************************//**
153528 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
153529 +
153530 + @Description Allocates FQID's
153531 +
153532 + May be used for Rx and offline parsing ports only
153533 +
153534 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
153535 +
153536 + @Return 0 on success; error code otherwise.
153537 +*//***************************************************************************/
153538 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
153539 +
153540 +/**************************************************************************//**
153541 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
153542 +
153543 + @Description Frees previously-allocated FQIDs
153544 +
153545 + May be used for Rx and offline parsing ports only
153546 +
153547 + @Param[in] uint32_t Base FQID of previously allocated range.
153548 +
153549 + @Return 0 on success; error code otherwise.
153550 +*//***************************************************************************/
153551 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
153552 +
153553 +
153554 +/**************************************************************************//**
153555 + @Function FM_PORT_SetPCD
153556 +
153557 + @Description Calling this routine defines the port's PCD configuration.
153558 + It changes it from its default configuration which is PCD
153559 + disabled (BMI to BMI) and configures it according to the passed
153560 + parameters.
153561 +
153562 + May be used for Rx and offline parsing ports only
153563 +
153564 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
153565 + configuration.
153566 +
153567 + @Return 0 on success; error code otherwise.
153568 +*//***************************************************************************/
153569 +#if defined(CONFIG_COMPAT)
153570 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
153571 +#endif
153572 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
153573 +
153574 +/**************************************************************************//**
153575 + @Function FM_PORT_DeletePCD
153576 +
153577 + @Description Calling this routine releases the port's PCD configuration.
153578 + The port returns to its default configuration which is PCD
153579 + disabled (BMI to BMI) and all PCD configuration is removed.
153580 +
153581 + May be used for Rx and offline parsing ports which are
153582 + in PCD mode only
153583 +
153584 + @Return 0 on success; error code otherwise.
153585 +*//***************************************************************************/
153586 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
153587 +
153588 +/**************************************************************************//**
153589 + @Function FM_PORT_AttachPCD
153590 +
153591 + @Description This routine may be called after FM_PORT_DetachPCD was called,
153592 + to return to the originally configured PCD support flow.
153593 + The couple of routines are used to allow PCD configuration changes
153594 + that demand that PCD will not be used while changes take place.
153595 +
153596 + May be used for Rx and offline parsing ports which are
153597 + in PCD mode only
153598 +
153599 + @Return 0 on success; error code otherwise.
153600 +*//***************************************************************************/
153601 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
153602 +
153603 +/**************************************************************************//**
153604 + @Function FM_PORT_DetachPCD
153605 +
153606 + @Description Calling this routine detaches the port from its PCD functionality.
153607 + The port returns to its default flow which is BMI to BMI.
153608 +
153609 + May be used for Rx and offline parsing ports which are
153610 + in PCD mode only
153611 +
153612 + @Return 0 on success; error code otherwise.
153613 +*//***************************************************************************/
153614 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
153615 +
153616 +/**************************************************************************//**
153617 + @Function FM_PORT_PcdPlcrAllocProfiles
153618 +
153619 + @Description This routine may be called only for ports that use the Policer in
153620 + order to allocate private policer profiles.
153621 +
153622 + @Param[in] uint16_t The number of required policer profiles
153623 +
153624 + @Return 0 on success; error code otherwise.
153625 +
153626 + @Cautions Allowed before FM_PORT_SetPCD() only.
153627 +*//***************************************************************************/
153628 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
153629 +
153630 +/**************************************************************************//**
153631 + @Function FM_PORT_PcdPlcrFreeProfiles
153632 +
153633 + @Description This routine should be called for freeing private policer profiles.
153634 +
153635 + @Return 0 on success; error code otherwise.
153636 +
153637 + @Cautions Allowed before FM_PORT_SetPCD() only.
153638 +*//***************************************************************************/
153639 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
153640 +
153641 +/**************************************************************************//**
153642 + @Function FM_PORT_PcdKgModifyInitialScheme
153643 +
153644 + @Description This routine may be called only for ports that use the keygen in
153645 + order to change the initial scheme frame should be routed to.
153646 + The change may be of a scheme id (in case of direct mode),
153647 + from direct to indirect, or from indirect to direct - specifying the scheme id.
153648 +
153649 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
153650 + a scheme is direct/indirect, and if direct - scheme id.
153651 +
153652 + @Return 0 on success; error code otherwise.
153653 +*//***************************************************************************/
153654 +#if defined(CONFIG_COMPAT)
153655 +#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_compat_fm_pcd_kg_scheme_select_t)
153656 +#endif
153657 +#define FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(26), ioc_fm_pcd_kg_scheme_select_t)
153658 +
153659 +/**************************************************************************//**
153660 + @Function FM_PORT_PcdPlcrModifyInitialProfile
153661 +
153662 + @Description This routine may be called for ports with flows
153663 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
153664 + to change the initial Policer profile frame should be routed to.
153665 + The change may be of a profile and/or absolute/direct mode selection.
153666 +
153667 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
153668 +
153669 + @Return 0 on success; error code otherwise.
153670 +*//***************************************************************************/
153671 +#if defined(CONFIG_COMPAT)
153672 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_compat_fm_obj_t)
153673 +#endif
153674 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
153675 +
153676 +/**************************************************************************//**
153677 + @Function FM_PORT_PcdCcModifyTree
153678 +
153679 + @Description This routine may be called to change this port connection to
153680 + a pre-initializes coarse classification Tree.
153681 +
153682 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
153683 +
153684 + @Return 0 on success; error code otherwise.
153685 +
153686 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
153687 +*//***************************************************************************/
153688 +#if defined(CONFIG_COMPAT)
153689 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
153690 +#endif
153691 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
153692 +
153693 +/**************************************************************************//**
153694 + @Function FM_PORT_PcdKgBindSchemes
153695 +
153696 + @Description These routines may be called for modifying the binding of ports
153697 + to schemes. The scheme itself is not added,
153698 + just this specific port starts using it.
153699 +
153700 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153701 +
153702 + @Return 0 on success; error code otherwise.
153703 +
153704 + @Cautions Allowed only following FM_PORT_SetPCD().
153705 +*//***************************************************************************/
153706 +#if defined(CONFIG_COMPAT)
153707 +#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_compat_fm_pcd_port_schemes_params_t)
153708 +#endif
153709 +#define FM_PORT_IOC_PCD_KG_BIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(30), ioc_fm_pcd_port_schemes_params_t)
153710 +
153711 +/**************************************************************************//**
153712 + @Function FM_PORT_PcdKgUnbindSchemes
153713 +
153714 + @Description These routines may be called for modifying the binding of ports
153715 + to schemes. The scheme itself is not removed or invalidated,
153716 + just this specific port stops using it.
153717 +
153718 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
153719 +
153720 + @Return 0 on success; error code otherwise.
153721 +
153722 + @Cautions Allowed only following FM_PORT_SetPCD().
153723 +*//***************************************************************************/
153724 +#if defined(CONFIG_COMPAT)
153725 +#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_compat_fm_pcd_port_schemes_params_t)
153726 +#endif
153727 +#define FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(31), ioc_fm_pcd_port_schemes_params_t)
153728 +
153729 +typedef struct ioc_fm_port_mac_addr_params_t {
153730 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
153731 +} ioc_fm_port_mac_addr_params_t;
153732 +
153733 +/**************************************************************************//**
153734 + @Function FM_MAC_AddHashMacAddr
153735 +
153736 + @Description Add an Address to the hash table. This is for filter purpose only.
153737 +
153738 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153739 +
153740 + @Return E_OK on success; Error code otherwise.
153741 +
153742 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
153743 + @Cautions Some address need to be filtered out in upper FM blocks.
153744 +*//***************************************************************************/
153745 +#define FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(36), ioc_fm_port_mac_addr_params_t)
153746 +
153747 +/**************************************************************************//**
153748 + @Function FM_MAC_RemoveHashMacAddr
153749 +
153750 + @Description Delete an Address to the hash table. This is for filter purpose only.
153751 +
153752 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
153753 +
153754 + @Return E_OK on success; Error code otherwise.
153755 +
153756 + @Cautions Allowed only following FM_MAC_Init().
153757 +*//***************************************************************************/
153758 +#define FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(37), ioc_fm_port_mac_addr_params_t)
153759 +
153760 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
153761 + uint8_t priority;
153762 + uint16_t pause_time;
153763 + uint16_t thresh_time;
153764 +} ioc_fm_port_tx_pause_frames_params_t;
153765 +
153766 +/**************************************************************************//**
153767 + @Function FM_MAC_SetTxPauseFrames
153768 +
153769 + @Description Enable/Disable transmission of Pause-Frames.
153770 + The routine changes the default configuration:
153771 + pause-time - [0xf000]
153772 + threshold-time - [0]
153773 +
153774 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
153775 +
153776 + @Return E_OK on success; Error code otherwise.
153777 +
153778 + @Cautions Allowed only following FM_MAC_Init().
153779 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
153780 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
153781 + in the 'priority' field.
153782 +*//***************************************************************************/
153783 +#define FM_PORT_IOC_SET_TX_PAUSE_FRAMES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(40), ioc_fm_port_tx_pause_frames_params_t)
153784 +
153785 +typedef struct ioc_fm_port_mac_statistics_t {
153786 + /* RMON */
153787 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
153788 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
153789 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
153790 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
153791 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
153792 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
153793 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
153794 + /* */
153795 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
153796 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
153797 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
153798 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
153799 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
153800 + This count does not include range length errors */
153801 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
153802 + a valid FCS and otherwise well formed */
153803 + /* Pause */
153804 + uint64_t te_stat_pause; /**< Pause MAC Control received */
153805 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
153806 + /* MIB II */
153807 + uint64_t if_in_octets; /**< Total number of byte received. */
153808 + uint64_t if_in_pkts; /**< Total number of packets received.*/
153809 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
153810 + NOTE: this counter is not supported on dTSEC MAC */
153811 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
153812 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
153813 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
153814 + uint64_t if_in_errors; /**< Number of frames received with error:
153815 + - FIFO Overflow Error
153816 + - CRC Error
153817 + - Frame Too Long Error
153818 + - Alignment Error
153819 + - The dedicated Error Code (0xfe, not a code error) was received */
153820 + uint64_t if_out_octets; /**< Total number of byte sent. */
153821 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
153822 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
153823 + NOTE: this counter is not supported on dTSEC MAC */
153824 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
153825 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
153826 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
153827 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
153828 + - FIFO Overflow Error
153829 + - FIFO Underflow Error
153830 + - Other */
153831 +} ioc_fm_port_mac_statistics_t;
153832 +
153833 +/**************************************************************************//**
153834 + @Function FM_MAC_GetStatistics
153835 +
153836 + @Description get all MAC statistics counters
153837 +
153838 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
153839 +
153840 + @Return E_OK on success; Error code otherwise.
153841 +
153842 + @Cautions Allowed only following FM_Init().
153843 +*//***************************************************************************/
153844 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
153845 +
153846 +/**************************************************************************//**
153847 + @Function FM_PORT_ConfigBufferPrefixContent
153848 +
153849 + @Description Defines the structure, size and content of the application buffer.
153850 + The prefix will
153851 + In Tx ports, if 'passPrsResult', the application
153852 + should set a value to their offsets in the prefix of
153853 + the FM will save the first 'privDataSize', than,
153854 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
153855 + and timeStamp, and the packet itself (in this order), to the
153856 + application buffer, and to offset.
153857 + Calling this routine changes the buffer margins definitions
153858 + in the internal driver data base from its default
153859 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
153860 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
153861 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
153862 +
153863 + May be used for all ports
153864 +
153865 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
153866 +
153867 + @Return E_OK on success; Error code otherwise.
153868 +
153869 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
153870 +*//***************************************************************************/
153871 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
153872 +
153873 +#if (DPAA_VERSION >= 11)
153874 +typedef struct ioc_fm_port_vsp_alloc_params_t {
153875 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
153876 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
153877 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
153878 + if relevant function called for Rx port */
153879 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
153880 +}ioc_fm_port_vsp_alloc_params_t;
153881 +
153882 +/**************************************************************************//**
153883 + @Function FM_PORT_VSPAlloc
153884 +
153885 + @Description This routine allocated VSPs per port and forces the port to work
153886 + in VSP mode. Note that the port is initialized by default with the
153887 + physical-storage-profile only.
153888 +
153889 + @Param[in] h_FmPort A handle to a FM Port module.
153890 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
153891 +
153892 + @Return E_OK on success; Error code otherwise.
153893 +
153894 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
153895 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
153896 +*//***************************************************************************/
153897 +#if defined(CONFIG_COMPAT)
153898 +#define FM_PORT_IOC_VSP_ALLOC_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_compat_fm_port_vsp_alloc_params_t)
153899 +#endif
153900 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
153901 +#endif /* (DPAA_VERSION >= 11) */
153902 +
153903 +/**************************************************************************//**
153904 + @Function FM_PORT_GetBmiCounters
153905 +
153906 + @Description Read port's BMI stat counters and place them into
153907 + a designated structure of counters.
153908 +
153909 + @Param[in] h_FmPort A handle to a FM Port module.
153910 + @Param[out] p_BmiStats counters structure
153911 +
153912 + @Return E_OK on success; Error code otherwise.
153913 +
153914 + @Cautions Allowed only following FM_PORT_Init().
153915 +*//***************************************************************************/
153916 +
153917 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
153918 +
153919 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
153920 +
153921 + e_CommMode type;
153922 + uint64_t count_pkts_64; /**< 64 byte frame counter */
153923 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
153924 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
153925 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
153926 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
153927 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
153928 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
153929 +} ioc_fm_port_mac_frame_size_counters_t;
153930 +
153931 +/**************************************************************************//**
153932 + @Function FM_MAC_GetFrameSizeCounters
153933 +
153934 + @Description get MAC statistics counters for different frame size
153935 +
153936 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
153937 +
153938 + @Return E_OK on success; Error code otherwise.
153939 +
153940 + @Cautions Allowed only following FM_Init().
153941 +*//***************************************************************************/
153942 +#define FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(43), ioc_fm_port_mac_frame_size_counters_t)
153943 +
153944 +
153945 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
153946 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
153947 +
153948 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
153949 +/** @} */ /* end of lnx_ioctl_FM_grp group */
153950 +#endif /* __FM_PORT_IOCTLS_H */
153951 --- /dev/null
153952 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
153953 @@ -0,0 +1,208 @@
153954 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
153955 + * All rights reserved.
153956 + *
153957 + * Redistribution and use in source and binary forms, with or without
153958 + * modification, are permitted provided that the following conditions are met:
153959 + * * Redistributions of source code must retain the above copyright
153960 + * notice, this list of conditions and the following disclaimer.
153961 + * * Redistributions in binary form must reproduce the above copyright
153962 + * notice, this list of conditions and the following disclaimer in the
153963 + * documentation and/or other materials provided with the distribution.
153964 + * * Neither the name of Freescale Semiconductor nor the
153965 + * names of its contributors may be used to endorse or promote products
153966 + * derived from this software without specific prior written permission.
153967 + *
153968 + *
153969 + * ALTERNATIVELY, this software may be distributed under the terms of the
153970 + * GNU General Public License ("GPL") as published by the Free Software
153971 + * Foundation, either version 2 of that License or (at your option) any
153972 + * later version.
153973 + *
153974 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
153975 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
153976 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
153977 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
153978 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
153979 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
153980 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
153981 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
153982 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
153983 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
153984 + */
153985 +
153986 +/**************************************************************************//**
153987 + @File fm_test_ioctls.h
153988 +
153989 + @Description FM Char device ioctls
153990 +*//***************************************************************************/
153991 +#ifndef __FM_TEST_IOCTLS_H
153992 +#define __FM_TEST_IOCTLS_H
153993 +
153994 +#include "ioctls.h"
153995 +
153996 +
153997 +/**************************************************************************//**
153998 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
153999 +
154000 + @Description FM-Test Linux ioctls definitions and enums
154001 +
154002 + @{
154003 +*//***************************************************************************/
154004 +
154005 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
154006 +
154007 +/**************************************************************************//**
154008 + @Collection TEST Parameters
154009 +*//***************************************************************************/
154010 +/**************************************************************************//**
154011 + @Description: Name of the FM-Test chardev
154012 +*//***************************************************************************/
154013 +#define DEV_FM_TEST_NAME "fm-test-port"
154014 +
154015 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
154016 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
154017 +
154018 +#define FMT_PORT_IOC_NUM(n) n
154019 +/* @} */
154020 +
154021 +/**************************************************************************//**
154022 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
154023 +
154024 + @Description TODO
154025 +
154026 + @{
154027 +*//***************************************************************************/
154028 +
154029 +/**************************************************************************//**
154030 + @Description TODO
154031 +*//***************************************************************************/
154032 +typedef uint8_t ioc_fmt_xxx_t;
154033 +
154034 +#define FM_PRS_MAX 32
154035 +#define FM_TIME_STAMP_MAX 8
154036 +
154037 +/**************************************************************************//**
154038 + @Description FM Port buffer content description
154039 +*//***************************************************************************/
154040 +typedef struct ioc_fmt_buff_context_t {
154041 + void *p_user_priv;
154042 + uint8_t fm_prs_res[FM_PRS_MAX];
154043 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154044 +} ioc_fmt_buff_context_t;
154045 +
154046 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154047 +typedef struct ioc_fmt_compat_buff_context_t {
154048 + compat_uptr_t p_user_priv;
154049 + uint8_t fm_prs_res[FM_PRS_MAX];
154050 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
154051 +} ioc_fmt_compat_buff_context_t;
154052 +#endif
154053 +
154054 +/**************************************************************************//**
154055 + @Description Buffer descriptor
154056 +*//***************************************************************************/
154057 +typedef struct ioc_fmt_buff_desc_t {
154058 + uint32_t qid;
154059 + void *p_data;
154060 + uint32_t size;
154061 + uint32_t status;
154062 + ioc_fmt_buff_context_t buff_context;
154063 +} ioc_fmt_buff_desc_t;
154064 +
154065 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
154066 +typedef struct ioc_fmt_compat_buff_desc_t {
154067 + uint32_t qid;
154068 + compat_uptr_t p_data;
154069 + uint32_t size;
154070 + uint32_t status;
154071 + ioc_fmt_compat_buff_context_t buff_context;
154072 +} ioc_fmt_compat_buff_desc_t;
154073 +#endif
154074 +
154075 +/**************************************************************************//**
154076 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
154077 +
154078 + @Description TODO
154079 + @{
154080 +*//***************************************************************************/
154081 +
154082 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
154083 +
154084 +
154085 +/**************************************************************************//**
154086 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
154087 +
154088 + @Description TODO
154089 +
154090 + @{
154091 +*//***************************************************************************/
154092 +
154093 +/**************************************************************************//**
154094 + @Description FM-Test FM port type
154095 +*//***************************************************************************/
154096 +typedef enum ioc_fmt_port_type {
154097 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
154098 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
154099 +} ioc_fmt_port_type;
154100 +
154101 +/**************************************************************************//**
154102 + @Description TODO
154103 +*//***************************************************************************/
154104 +typedef struct ioc_fmt_port_param_t {
154105 + uint8_t fm_id;
154106 + ioc_fmt_port_type fm_port_type;
154107 + uint8_t fm_port_id;
154108 + uint32_t num_tx_queues;
154109 +} ioc_fmt_port_param_t;
154110 +
154111 +
154112 +/**************************************************************************//**
154113 + @Function FMT_PORT_IOC_INIT
154114 +
154115 + @Description TODO
154116 +
154117 + @Param[in] ioc_fmt_port_param_t TODO
154118 +
154119 + @Cautions Allowed only after the FM equivalent port is already initialized.
154120 +*//***************************************************************************/
154121 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
154122 +
154123 +/**************************************************************************//**
154124 + @Function FMT_PORT_IOC_SET_DIAG_MODE
154125 +
154126 + @Description TODO
154127 +
154128 + @Param[in] ioc_diag_mode TODO
154129 +
154130 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154131 +*//***************************************************************************/
154132 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
154133 +
154134 +/**************************************************************************//**
154135 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
154136 +
154137 + @Description Set IP header manipulations for this port.
154138 +
154139 + @Param[in] int 1 to enable; 0 to disable
154140 +
154141 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154142 +*//***************************************************************************/
154143 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
154144 +
154145 +/**************************************************************************//**
154146 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
154147 +
154148 + @Description Set DPA in echo mode - all frame are sent back.
154149 +
154150 + @Param[in] int 1 to enable; 0 to disable
154151 +
154152 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
154153 +*//***************************************************************************/
154154 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
154155 +
154156 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
154157 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
154158 +/** @} */ /* end of lnx_ioctl_FMT_grp */
154159 +
154160 +
154161 +#endif /* __FM_TEST_IOCTLS_H */
154162 --- /dev/null
154163 +++ b/include/uapi/linux/fmd/integrations/Kbuild
154164 @@ -0,0 +1 @@
154165 +header-y += integration_ioctls.h
154166 --- /dev/null
154167 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
154168 @@ -0,0 +1,56 @@
154169 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154170 + * All rights reserved.
154171 + *
154172 + * Redistribution and use in source and binary forms, with or without
154173 + * modification, are permitted provided that the following conditions are met:
154174 + * * Redistributions of source code must retain the above copyright
154175 + * notice, this list of conditions and the following disclaimer.
154176 + * * Redistributions in binary form must reproduce the above copyright
154177 + * notice, this list of conditions and the following disclaimer in the
154178 + * documentation and/or other materials provided with the distribution.
154179 + * * Neither the name of Freescale Semiconductor nor the
154180 + * names of its contributors may be used to endorse or promote products
154181 + * derived from this software without specific prior written permission.
154182 + *
154183 + *
154184 + * ALTERNATIVELY, this software may be distributed under the terms of the
154185 + * GNU General Public License ("GPL") as published by the Free Software
154186 + * Foundation, either version 2 of that License or (at your option) any
154187 + * later version.
154188 + *
154189 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154190 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154191 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154192 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154193 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154194 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154195 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154196 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154197 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154198 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154199 + */
154200 +
154201 +/**************************************************************************//**
154202 + @File integration_ioctls.h
154203 +
154204 + @Description External header file for Integration unit routines.
154205 +*//***************************************************************************/
154206 +
154207 +#ifndef __INTG_IOCTLS_H
154208 +#define __INTG_IOCTLS_H
154209 +
154210 +
154211 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
154212 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
154213 +
154214 +/*#define FM_IOCTL_DBG*/
154215 +
154216 +#if defined(FM_IOCTL_DBG)
154217 + #define _fm_ioctl_dbg(format, arg...) \
154218 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
154219 + __func__, __LINE__, smp_processor_id(), ##arg)
154220 +#else
154221 +# define _fm_ioctl_dbg(arg...)
154222 +#endif
154223 +
154224 +#endif /* __INTG_IOCTLS_H */
154225 --- /dev/null
154226 +++ b/include/uapi/linux/fmd/ioctls.h
154227 @@ -0,0 +1,96 @@
154228 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154229 + * All rights reserved.
154230 + *
154231 + * Redistribution and use in source and binary forms, with or without
154232 + * modification, are permitted provided that the following conditions are met:
154233 + * * Redistributions of source code must retain the above copyright
154234 + * notice, this list of conditions and the following disclaimer.
154235 + * * Redistributions in binary form must reproduce the above copyright
154236 + * notice, this list of conditions and the following disclaimer in the
154237 + * documentation and/or other materials provided with the distribution.
154238 + * * Neither the name of Freescale Semiconductor nor the
154239 + * names of its contributors may be used to endorse or promote products
154240 + * derived from this software without specific prior written permission.
154241 + *
154242 + *
154243 + * ALTERNATIVELY, this software may be distributed under the terms of the
154244 + * GNU General Public License ("GPL") as published by the Free Software
154245 + * Foundation, either version 2 of that License or (at your option) any
154246 + * later version.
154247 + *
154248 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154249 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154250 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154251 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154252 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154253 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154254 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154255 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154256 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154257 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154258 + */
154259 +
154260 +/**************************************************************************//**
154261 + @File ioctls.h
154262 +
154263 + @Description Structures and definitions for Command Relay Ioctls
154264 +*//***************************************************************************/
154265 +
154266 +#ifndef __IOCTLS_H__
154267 +#define __IOCTLS_H__
154268 +
154269 +#include <asm/ioctl.h>
154270 +
154271 +#include "integration_ioctls.h"
154272 +
154273 +
154274 +/**************************************************************************//**
154275 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
154276 + @{
154277 +*//***************************************************************************/
154278 +
154279 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
154280 + the NCSW Linux module commands */
154281 +
154282 +
154283 +/**************************************************************************//**
154284 + @Description IOCTL Memory allocation types.
154285 +*//***************************************************************************/
154286 +typedef enum ioc_mem_type {
154287 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
154288 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
154289 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
154290 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
154291 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
154292 +} ioc_mem_type;
154293 +
154294 +/**************************************************************************//**
154295 + @Description Enumeration (bit flags) of communication modes (Transmit,
154296 + receive or both).
154297 +*//***************************************************************************/
154298 +typedef enum ioc_comm_mode {
154299 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
154300 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
154301 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
154302 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
154303 +} ioc_comm_mode;
154304 +
154305 +/**************************************************************************//**
154306 + @Description General Diagnostic Mode
154307 +*//***************************************************************************/
154308 +typedef enum ioc_diag_mode
154309 +{
154310 + e_IOC_DIAG_MODE_NONE = 0,
154311 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
154312 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
154313 + E.g. IO-pins, SerDes, etc. */
154314 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
154315 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
154316 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
154317 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
154318 +} ioc_diag_mode;
154319 +
154320 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
154321 +
154322 +
154323 +#endif /* __IOCTLS_H__ */
154324 --- /dev/null
154325 +++ b/include/uapi/linux/fmd/net_ioctls.h
154326 @@ -0,0 +1,430 @@
154327 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154328 + * All rights reserved.
154329 + *
154330 + * Redistribution and use in source and binary forms, with or without
154331 + * modification, are permitted provided that the following conditions are met:
154332 + * * Redistributions of source code must retain the above copyright
154333 + * notice, this list of conditions and the following disclaimer.
154334 + * * Redistributions in binary form must reproduce the above copyright
154335 + * notice, this list of conditions and the following disclaimer in the
154336 + * documentation and/or other materials provided with the distribution.
154337 + * * Neither the name of Freescale Semiconductor nor the
154338 + * names of its contributors may be used to endorse or promote products
154339 + * derived from this software without specific prior written permission.
154340 + *
154341 + *
154342 + * ALTERNATIVELY, this software may be distributed under the terms of the
154343 + * GNU General Public License ("GPL") as published by the Free Software
154344 + * Foundation, either version 2 of that License or (at your option) any
154345 + * later version.
154346 + *
154347 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154348 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154349 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154350 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154351 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154352 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154353 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154354 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154355 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154356 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154357 + */
154358 +
154359 +
154360 +/**************************************************************************//**
154361 + @File net_ioctls.h
154362 +
154363 + @Description This file contains common and general netcomm headers definitions.
154364 +*//***************************************************************************/
154365 +#ifndef __NET_IOCTLS_H
154366 +#define __NET_IOCTLS_H
154367 +
154368 +#include "ioctls.h"
154369 +
154370 +
154371 +typedef uint8_t ioc_header_field_ppp_t;
154372 +
154373 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
154374 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
154375 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
154376 +
154377 +
154378 +typedef uint8_t ioc_header_field_pppoe_t;
154379 +
154380 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
154381 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
154382 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
154383 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
154384 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
154385 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
154386 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
154387 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
154388 +
154389 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
154390 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
154391 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
154392 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
154393 +
154394 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
154395 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
154396 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
154397 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
154398 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
154399 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
154400 +
154401 +
154402 +typedef uint8_t ioc_header_field_eth_t;
154403 +
154404 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
154405 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
154406 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
154407 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
154408 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
154409 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
154410 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
154411 +
154412 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
154413 +
154414 +typedef uint16_t ioc_header_field_ip_t;
154415 +
154416 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
154417 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
154418 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
154419 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
154420 +
154421 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
154422 +
154423 +typedef uint16_t ioc_header_field_ipv4_t;
154424 +
154425 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
154426 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
154427 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
154428 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
154429 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
154430 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
154431 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
154432 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
154433 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
154434 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
154435 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
154436 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
154437 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
154438 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
154439 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
154440 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
154441 +
154442 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
154443 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
154444 +
154445 +
154446 +typedef uint8_t ioc_header_field_ipv6_t;
154447 +
154448 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
154449 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
154450 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
154451 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
154452 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
154453 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
154454 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
154455 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
154456 +
154457 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
154458 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
154459 +
154460 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
154461 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
154462 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
154463 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
154464 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
154465 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
154466 +
154467 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
154468 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
154469 +
154470 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
154471 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
154472 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
154473 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
154474 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
154475 +
154476 +
154477 +typedef uint16_t ioc_header_field_tcp_t;
154478 +
154479 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
154480 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
154481 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
154482 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
154483 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
154484 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
154485 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
154486 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
154487 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
154488 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
154489 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
154490 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
154491 +
154492 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
154493 +
154494 +
154495 +typedef uint8_t ioc_header_field_sctp_t;
154496 +
154497 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
154498 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
154499 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
154500 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
154501 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
154502 +
154503 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
154504 +
154505 +typedef uint8_t ioc_header_field_dccp_t;
154506 +
154507 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
154508 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
154509 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
154510 +
154511 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
154512 +
154513 +
154514 +typedef uint8_t ioc_header_field_udp_t;
154515 +
154516 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
154517 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
154518 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
154519 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
154520 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
154521 +
154522 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
154523 +
154524 +typedef uint8_t ioc_header_field_udp_lite_t;
154525 +
154526 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
154527 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
154528 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
154529 +
154530 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
154531 +
154532 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
154533 +
154534 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
154535 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
154536 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
154537 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
154538 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
154539 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
154540 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
154541 +
154542 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
154543 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
154544 +
154545 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
154546 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
154547 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
154548 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
154549 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
154550 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
154551 +
154552 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
154553 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
154554 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
154555 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
154556 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
154557 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
154558 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
154559 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
154560 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
154561 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
154562 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
154563 +
154564 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
154565 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
154566 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
154567 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
154568 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
154569 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
154570 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
154571 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
154572 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
154573 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
154574 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
154575 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
154576 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
154577 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
154578 +
154579 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
154580 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
154581 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
154582 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
154583 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
154584 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
154585 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
154586 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
154587 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
154588 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
154589 +
154590 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
154591 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
154592 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
154593 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
154594 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
154595 +
154596 +
154597 +typedef uint8_t ioc_header_field_vlan_t;
154598 +
154599 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
154600 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
154601 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
154602 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
154603 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
154604 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
154605 +
154606 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
154607 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
154608 + IOC_NET_HEADER_FIELD_VLAN_VID)
154609 +
154610 +
154611 +typedef uint8_t ioc_header_field_llc_t;
154612 +
154613 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
154614 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
154615 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
154616 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
154617 +
154618 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
154619 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
154620 +
154621 +
154622 +typedef uint8_t ioc_header_field_snap_t;
154623 +
154624 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
154625 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
154626 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
154627 +
154628 +
154629 +typedef uint8_t ioc_header_field_llc_snap_t;
154630 +
154631 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
154632 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
154633 +
154634 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
154635 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
154636 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
154637 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
154638 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
154639 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
154640 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
154641 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
154642 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
154643 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
154644 +
154645 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
154646 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
154647 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
154648 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
154649 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
154650 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
154651 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
154652 +
154653 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
154654 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
154655 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
154656 +
154657 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
154658 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
154659 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
154660 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
154661 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
154662 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
154663 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
154664 +
154665 +
154666 +typedef uint8_t ioc_header_field_gre_t;
154667 +
154668 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
154669 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
154670 +
154671 +
154672 +typedef uint8_t ioc_header_field_minencap_t;
154673 +
154674 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
154675 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
154676 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
154677 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
154678 +
154679 +
154680 +typedef uint8_t ioc_header_field_ipsec_ah_t;
154681 +
154682 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
154683 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
154684 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
154685 +
154686 +
154687 +typedef uint8_t ioc_header_field_ipsec_esp_t;
154688 +
154689 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
154690 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
154691 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
154692 +
154693 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
154694 +
154695 +
154696 +typedef uint8_t ioc_header_field_mpls_t;
154697 +
154698 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
154699 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
154700 +
154701 +
154702 +typedef uint8_t ioc_header_field_macsec_t;
154703 +
154704 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
154705 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
154706 +
154707 +
154708 +typedef enum {
154709 + e_IOC_NET_HEADER_TYPE_NONE = 0,
154710 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
154711 + e_IOC_NET_HEADER_TYPE_ETH,
154712 + e_IOC_NET_HEADER_TYPE_VLAN,
154713 + e_IOC_NET_HEADER_TYPE_IPv4,
154714 + e_IOC_NET_HEADER_TYPE_IPv6,
154715 + e_IOC_NET_HEADER_TYPE_IP,
154716 + e_IOC_NET_HEADER_TYPE_TCP,
154717 + e_IOC_NET_HEADER_TYPE_UDP,
154718 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
154719 + e_IOC_NET_HEADER_TYPE_IPHC,
154720 + e_IOC_NET_HEADER_TYPE_SCTP,
154721 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
154722 + e_IOC_NET_HEADER_TYPE_PPPoE,
154723 + e_IOC_NET_HEADER_TYPE_PPP,
154724 + e_IOC_NET_HEADER_TYPE_PPPMUX,
154725 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
154726 + e_IOC_NET_HEADER_TYPE_L2TPv2,
154727 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
154728 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
154729 + e_IOC_NET_HEADER_TYPE_LLC,
154730 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
154731 + e_IOC_NET_HEADER_TYPE_NLPID,
154732 + e_IOC_NET_HEADER_TYPE_SNAP,
154733 + e_IOC_NET_HEADER_TYPE_MPLS,
154734 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
154735 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
154736 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
154737 + e_IOC_NET_HEADER_TYPE_MACSEC,
154738 + e_IOC_NET_HEADER_TYPE_GRE,
154739 + e_IOC_NET_HEADER_TYPE_MINENCAP,
154740 + e_IOC_NET_HEADER_TYPE_DCCP,
154741 + e_IOC_NET_HEADER_TYPE_ICMP,
154742 + e_IOC_NET_HEADER_TYPE_IGMP,
154743 + e_IOC_NET_HEADER_TYPE_ARP,
154744 + e_IOC_NET_HEADER_TYPE_CAPWAP,
154745 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
154746 + e_IOC_NET_HEADER_TYPE_RFC2684,
154747 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
154748 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
154749 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
154750 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
154751 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
154752 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
154753 +} ioc_net_header_type;
154754 +
154755 +
154756 +#endif /* __NET_IOCTLS_H */